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实现
这些高级并发模式将帮助您构建更可靠、更高效的分布式系统!