Skip to content

4.2 网络编程 ​

net 包基础 ​

go
// IP 地址
ip := net.ParseIP("192.168.1.1")
ip4 := ip.To4()

// IP 网络
_, network, _ := net.ParseCIDR("192.168.1.0/24")
network.Contains(net.ParseIP("192.168.1.100"))

// DNS 查询
addrs, _ := net.LookupHost("google.com")
names, _ := net.LookupAddr("8.8.8.8")
mx, _ := net.LookupMX("gmail.com")

// TCP 连接
conn, _ := net.Dial("tcp", "google.com:80")
defer conn.Close()
conn.Write([]byte("GET / HTTP/1.0\r\n\r\n"))
buf, _ := io.ReadAll(conn)

// 监听
lis, _ := net.Listen("tcp", ":8080")
defer lis.Close()
for {
    conn, _ := lis.Accept()
    go handleConn(conn)
}

http 客户端 ​

go
// 简单 GET
resp, _ := http.Get("https://api.example.com/data")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)

// 简单 POST
resp, _ = http.Post(
    "https://api.example.com/users",
    "application/json",
    bytes.NewBuffer([]byte(`{"name":"Alice"}`)),
)

// 创建请求
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer token")
q := req.URL.Query()
q.Add("page", "1")
req.URL.RawQuery = q.Encode()

// 自定义客户端
client := &http.Client{
    Timeout: 30 * time.Second,
}
resp, _ = client.Do(req)

// POST JSON
user := User{Name: "Alice"}
body, _ := json.Marshal(user)
req, _ = http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")

http 服务器 ​

go
// 基础服务器
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
})
http.ListenAndServe(":8080", nil)

// Handler 接口
type MyHandler struct{}
func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Custom handler")
}
http.Handle("/custom", &MyHandler{})

// 路由处理
http.HandleFunc("/users/:id", func(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        // 获取
    case http.MethodPost:
        // 创建
    default:
        http.Error(w, "Method not allowed", 405)
    }
})

// 静态文件
http.Handle("/static/", http.StripPrefix("/static/",
    http.FileServer(http.Dir("assets"))))

// 中间件
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        next.ServeHTTP(w, r)
        fmt.Printf("%s %s %v\n", r.Method, r.URL.Path, time.Since(start))
    })
}

Graceful Shutdown ​

go
server := &http.Server{
    Addr:    ":8080",
    Handler: http.DefaultServeMux,
}

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

// 等待中断信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit

// 优雅关闭
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
    log.Fatal(err)
}