Go网络编程实战

Go网络编程实战

Go语言凭借其优秀的并发模型和简洁的API设计,成为了网络编程的首选语言之一。本文将深入探讨Go在网络编程领域的各种实战技巧,从基础的TCP/UDP通讯到高级的负载均衡实现。

一、TCP/UDP编程基础

1. TCP服务器与客户端

// TCP服务器
func tcpServer() {
    ln, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    defer ln.Close()

    for {
        conn, err := ln.Accept()
        if err != nil {
            log.Println("accept error:", err)
            continue
        }
        go handleTCPConnection(conn)
    }
}

func handleTCPConnection(conn net.Conn) {
    defer conn.Close()
    buf := make([]byte, 1024)
    for {
        n, err := conn.Read(buf)
        if err != nil {
            log.Println("read error:", err)
            return
        }
        fmt.Printf("received: %s\n", buf[:n])
        conn.Write([]byte("message received"))
    }
}

// TCP客户端
func tcpClient() {
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    if _, err := conn.Write([]byte("hello server")); err != nil {
        log.Fatal(err)
    }

    buf := make([]byte, 1024)
    n, err := conn.Read(buf)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("server reply: %s\n", buf[:n])
}

2. UDP通讯实现

// UDP服务器
func udpServer() {
    pc, err := net.ListenPacket("udp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    defer pc.Close()

    buf := make([]byte, 1024)
    for {
        n, addr, err := pc.ReadFrom(buf)
        if err != nil {
            log.Println("read error:", err)
            continue
        }
        fmt.Printf("from %s: %s\n", addr, buf[:n])
        pc.WriteTo([]byte("udp reply"), addr)
    }
}

// UDP客户端
func udpClient() {
    conn, err := net.Dial("udp", "localhost:8080")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    if _, err := conn.Write([]byte("hello udp")); err != nil {
        log.Fatal(err)
    }

    buf := make([]byte, 1024)
    n, err := conn.Read(buf)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("server reply: %s\n", buf[:n])
}

二、HTTP/HTTPS进阶

1. 自定义HTTP服务器

func customHTTPServer() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("custom http server"))
    })

    server := &http.Server{
        Addr:         ":8443",
        Handler:      mux,
        ReadTimeout:  10 * time.Second,
        WriteTimeout: 10 * time.Second,
        TLSConfig: &tls.Config{
            MinVersion: tls.VersionTLS12,
        },
    }

    // 自签名证书生成:
    // openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 365
    log.Fatal(server.ListenAndServeTLS("server.crt", "server.key"))
}

2. HTTP客户端连接池

var httpClient = &http.Client{
    Transport: &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 10,
        IdleConnTimeout:     30 * time.Second,
        TLSHandshakeTimeout: 10 * time.Second,
    },
    Timeout: 30 * time.Second,
}

func makeRequest(url string) {
    resp, err := httpClient.Get(url)
    if err != nil {
        log.Println("request error:", err)
        return
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Println("read error:", err)
        return
    }
    fmt.Println("response:", string(body))
}

三、WebSocket实时通信

1. WebSocket服务器

func websocketServer() {
    upgrader := websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }

    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            log.Println("upgrade error:", err)
            return
        }
        defer conn.Close()

        for {
            mt, msg, err := conn.ReadMessage()
            if err != nil {
                log.Println("read error:", err)
                break
            }
            log.Printf("recv: %s", msg)
            err = conn.WriteMessage(mt, []byte("echo: "+string(msg)))
            if err != nil {
                log.Println("write error:", err)
                break
            }
        }
    })

    log.Fatal(http.ListenAndServe(":8080", nil))
}

2. WebSocket客户端

func websocketClient() {
    url := "ws://localhost:8080/ws"
    conn, _, err := websocket.DefaultDialer.Dial(url, nil)
    if err != nil {
        log.Fatal("dial error:", err)
    }
    defer conn.Close()

    // 发送消息
    err = conn.WriteMessage(websocket.TextMessage, []byte("hello"))
    if err != nil {
        log.Fatal("write error:", err)
    }

    // 接收消息
    _, msg, err := conn.ReadMessage()
    if err != nil {
        log.Fatal("read error:", err)
    }
    fmt.Println("received:", string(msg))
}

四、DNS解析与处理

1. 自定义DNS解析

func dnsLookup() {
    // 系统DNS解析
    addrs, err := net.LookupHost("google.com")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Google addresses:", addrs)

    // 自定义DNS服务器
    r := &net.Resolver{
        PreferGo: true,
        Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
            d := net.Dialer{Timeout: 5 * time.Second}
            return d.DialContext(ctx, "udp", "8.8.8.8:53")
        },
    }
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    ips, err := r.LookupHost(ctx, "google.com")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Google addresses via 8.8.8.8:", ips)
}

五、负载均衡实现

1. 客户端负载均衡

type ServerPool struct {
    servers []string
    index   uint32
}

func (p *ServerPool) Next() string {
    i := atomic.AddUint32(&p.index, 1)
    return p.servers[i%uint32(len(p.servers))]
}

func loadBalancerExample() {
    pool := &ServerPool{
        servers: []string{
            "http://server1:8080",
            "http://server2:8080",
            "http://server3:8080",
        },
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        target := pool.Next()
        proxy := httputil.NewSingleHostReverseProxy(target)
        proxy.ServeHTTP(w, r)
    })

    log.Fatal(http.ListenAndServe(":80", nil))
}

2. 加权轮询算法

type WeightedServer struct {
    URL    string
    Weight int
    current int
}

type WeightedRoundRobin struct {
    servers []*WeightedServer
    gcd     int
    max     int
}

func NewWeightedRoundRobin(servers []*WeightedServer) *WeightedRoundRobin {
    wrr := &WeightedRoundRobin{servers: servers}
    wrr.gcd = gcdSlice(servers)
    wrr.max = maxWeight(servers)
    return wrr
}

func (wrr *WeightedRoundRobin) Next() string {
    for {
        for _, s := range wrr.servers {
            s.current += s.Weight
            if s.current >= wrr.max {
                s.current -= wrr.gcd
                return s.URL
            }
        }
    }
}

六、网络调试工具

1. net/http/pprof集成

func debugServer() {
    mux := http.NewServeMux()
    mux.HandleFunc("/debug/pprof/", pprof.Index)
    mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
    mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
    mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
    mux.HandleFunc("/debug/pprof/trace", pprof.Trace)

    server := &http.Server{
        Addr:    "localhost:6060",
        Handler: mux,
    }
    log.Fatal(server.ListenAndServe())
}

2. 使用Wireshark分析

# 捕获Go程序的网络包
tcpdump -i lo -w go_network.pcap port 8080

# 在Wireshark中分析
wireshark go_network.pcap

预告:Go并发模式进阶

在掌握了网络编程基础后,下一期我们将探索更高级的并发模式,构建高并发分布式系统:

《Go并发模式进阶》内容预告:

  • 扇出/扇入模式:高效处理数据流
  • 顺序一致性保证:同步机制的深层实现
  • 分布式锁实现:基于Redis/etcd的方案
  • Leader选举模式:集群协调技术
  • Backpressure控制:过载保护机制
  • 容错模式:Circuit Breaker实现

这些高级并发模式将帮助您构建更可靠、更高效的分布式系统!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇