package main

import (

"fmt"
"github.com/getlantern/systray"
"github.com/getlantern/systray/example/icon"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"

)

var server *http.Server

func main() {

startServer()
systray.Run(onReady, onExit)

}

func onReady() {

systray.SetTitle("My Tool")
systray.SetTooltip("My handy tool")
systray.SetIcon(icon.Data)
startItem := systray.AddMenuItem("开始", "启动 HTTP 服务")
endItem := systray.AddMenuItem("结束", "停止 HTTP 服务")
quitItem := systray.AddMenuItem("退出", "退出软件")

go func() {
    for {
        select {
        case <-startItem.ClickedCh:
            startServer()
        case <-endItem.ClickedCh:
            stopServer()
        case <-quitItem.ClickedCh:
            systray.Quit()
        }
    }
}()

}

func startServer() {

// 获取当前目录下的 www 目录作为 web 目录
currentDir, err := os.Getwd()
if err != nil {
    log.Fatal(err)
}
webDir := filepath.Join(currentDir, "www")

mux := http.NewServeMux()

// 注册静态文件服务器
mux.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(webDir))))

// 注册路由处理器
mux.HandleFunc("/sendParams", sendParamsHandler)

// 创建服务器
server = &http.Server{
    Addr:    ":8080",
    Handler: mux,
}

fmt.Println("Starting server...")
go func() {
    err := server.ListenAndServe()
    if err != nil && err != http.ErrServerClosed {
        log.Fatal(err)
    }
}()

openBrowser("http://localhost:8080")

}
func sendParamsHandler(w http.ResponseWriter, r *http.Request) {

if r.Method == "POST" {
    r.ParseForm()
    param := r.Form.Get("param")
    fmt.Println("Received parameter:", param)
    fmt.Fprintf(w, "Parameter received: %s", param)

} else {
    http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
}

}
func stopServer() {

fmt.Println("Stopping server...")
if server != nil {
    err := server.Close()
    if err != nil {
        log.Fatal(err)
    }
}

}

func onExit() {

// 这里可以添加退出时的清理逻辑
if server != nil {
    stopServer()
}

}

func openBrowser(url string) {

var err error
switch runtime.GOOS {
case "linux":
    err = exec.Command("xdg-open", url).Start()
case "windows":
    err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
case "darwin":
    err = exec.Command("open", url).Start()
default:
    fmt.Println("Unsupported platform")
}
if err != nil {
    log.Fatal(err)
}

}

前端

<!DOCTYPE html>
<html lang="en">
<head>

<meta charset="UTF-8">
<title>使用GO语言开发Web服务</title>

</head>
<body>
<button id="sendButton">发送单个参数</button>
<button id="sendButton2">发送多个参数</button>
<button id="sendButton3">请求json数据</button>
<button id="closeSys">关闭服务</button>

表格

<script>

document.getElementById('sendButton').addEventListener('click', function() {
    const param = 'Hello, World!';
    console.log('发送请求');

    fetch('/sendParams', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `param=${encodeURIComponent(param)}`
    })
        .then(response => response.text())
        .then(data => console.log(data))
        .catch(error => console.error('Error:', error));
});
document.getElementById('sendButton2').addEventListener('click', function() {
    const param = { message: 'Hello, World!',aaa:'aaa' };
    console.log('发送请求');

    fetch('http://localhost:8080/sendMoreParams', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(param)
    })
        .then(response => response.text())
        .then(data => console.log('Response:', data))
        .catch(error => console.error('Error:', error));
});
document.getElementById('sendButton3').addEventListener('click', function() {
    const param = { message: 'Hello, World!',aaa:'aaa' };
    console.log('发送请求');

    fetch('http://localhost:8080/getJsonData', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(param)
    })
        .then(response => response.text())
        .then(data => console.log('Response:', data))
        .catch(error => console.error('Error:', error));
});
document.getElementById('closeSys').addEventListener('click', function() {
    const param = { message: 'Hello, World!',aaa:'aaa' };
    console.log('发送请求');

    fetch('http://localhost:8080/closeSys', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(param)
    })
        .then(response => response.text())
        .then(data => console.log('Response:', data))
        .catch(error => console.error('Error:', error));
});

</script>
</body>
</html>

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os/exec"
    "runtime"
    "time"
)

func openBrowser(url string) {
    var cmd *exec.Cmd

    switch runtime.GOOS {
    case "darwin":
        cmd = exec.Command("open", url)
    case "linux":
        cmd = exec.Command("xdg-open", url)
    case "windows":
        cmd = exec.Command("cmd", "/c", "start", url)
    default:
        log.Println("Unsupported OS")
        return
    }

    err := cmd.Start()
    if err != nil {
        log.Printf("Failed to open browser: %v", err)
    }
}
func main() {

    // 设置静态文件服务目录为当前目录下的www文件夹
    fs := http.FileServer(http.Dir("./www"))

    // 添加一个新的路由来处理发送参数的请求
    http.HandleFunc("/sendParams", sendParamsHandler)

    http.HandleFunc("/sendMoreParams", sendMoreParamsHandler)
    //另一个请求 http.HandleFunc("/anotherRequest", anotherRequestHandler)
    // 将请求转发到静态文件服务器
    // 使用http.HandleFunc来处理根URL("/")的请求
    // 使用FileServer来服务静态文件
    http.Handle("/", http.StripPrefix("/", fs))
    openBrowser("http://localhost:8080")
    // 设置服务器监听的端口
    log.Println("Starting server on :8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }

}

// sendParamsHandler 处理参数传输请求。
// 它接受 POST 请求,并解析请求体中的 "param" 参数。
// 在接收参数后,它会打印参数值,向客户端响应参数值,
// 并依次关闭 HTTP 服务器和浏览器。
func sendParamsHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method == "POST" {
        r.ParseForm()
        param := r.Form.Get("param")
        fmt.Println("Received parameter:", param)
        fmt.Fprintf(w, "Parameter received: %s", param)

        // 关闭 HTTP 服务器
        shutdownServer()

        // 关闭浏览器
        closeBrowser()
    } else {
        http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
    }
}

// 处理发送参数的请求
func sendMoreParamsHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method == "POST" {
        body, err := ioutil.ReadAll(r.Body)
        if err != nil {
            http.Error(w, "Error reading request body", http.StatusBadRequest)
            return
        }
        defer r.Body.Close()

        var param map[string]string
        err = json.Unmarshal(body, &param)
        if err != nil {
            http.Error(w, "Error parsing JSON", http.StatusBadRequest)
            return
        }

        message, ok := param["message"]
        if !ok {
            http.Error(w, "Missing 'message' field in JSON", http.StatusBadRequest)
            return
        }
        aaa, ok := param["aaa"]
        if !ok {
            http.Error(w, "Missing 'message' field in JSON", http.StatusBadRequest)
            return
        }
        fmt.Println("Received parameter:", aaa)
        fmt.Println("Received parameter:", message)
        fmt.Fprintf(w, "Parameter received: %s", message)

        // 关闭 HTTP 服务器
        //shutdownServer()

        // 关闭浏览器
        //closeBrowser()
    } else {
        http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
    }
}

// 关闭 HTTP 服务器
func shutdownServer() {
    server := &http.Server{Addr: ":8080"}
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    if err := server.Shutdown(ctx); err != nil {
        log.Fatalf("Could not gracefully shutdown the server: %v\n", err)
    } else {
        log.Println("Server gracefully shut down")
    }
}

// 关闭浏览器
func closeBrowser() {
    var cmd *exec.Cmd

    switch runtime.GOOS {
    case "darwin":
        cmd = exec.Command("osascript", "-e", "tell application \"Safari\" to quit")
    case "linux":
        cmd = exec.Command("xdotool", "key", "Ctrl+Q")
    case "windows":
        cmd = exec.Command("taskkill", "/F", "/IM", "chrome.exe")
    default:
        log.Println("Unsupported OS")
        return
    }

    err := cmd.Run()
    if err != nil {
        log.Printf("Failed to close browser: %v", err)
    } else {
        log.Println("Browser closed")
    }
}

网线接法图解、水晶头接法图解

1、一种是直连互联法,一种是交叉互联法。交叉线的做法是:一头采用568A标准,一头采用568B标准;直连线的做法是:两头同为568A标准或568B标准。

2、
标准568A:绿白-1,绿-2,橙白-3,蓝-4,蓝白-5,橙-6,棕白-7,棕-8。
标准568B:橙白-1,橙-2,绿白-3,蓝-4,蓝白-5,绿-6,棕白-7,棕-8。

3、先用压线钳,将网线的胶皮剪掉约2厘米,露出8股内线。然后按照568A或者568B的标准线序把网线排列好,接着把8股线末端剪齐,将水晶头有塑料弹簧片的一端向下,有金属针脚的一端向上,把整齐的8股线插入水晶头,并使其紧紧的顶在顶端,最后把水晶头插入8P槽内,用力握紧压线钳即可。