Go语言中的网络编程
Go语言中的网络编程1. 网络编程的基本概念网络编程是指编写在网络上进行通信的程序。在Go语言中网络编程主要通过net包来实现支持TCP、UDP、HTTP等多种协议。2. TCP服务器2.1 基本TCP服务器package main import ( fmt net ) func handleConnection(conn net.Conn) { defer conn.Close() // 读取客户端数据 buffer : make([]byte, 1024) n, err : conn.Read(buffer) if err ! nil { fmt.Println(Error reading:, err) return } fmt.Printf(Received: %s, buffer[:n]) // 发送响应 _, err conn.Write([]byte(Hello from server!\n)) if err ! nil { fmt.Println(Error writing:, err) return } } func main() { // 监听端口 listener, err : net.Listen(tcp, :8080) if err ! nil { fmt.Println(Error listening:, err) return } defer listener.Close() fmt.Println(Server listening on port 8080) // 接受连接 for { conn, err : listener.Accept() if err ! nil { fmt.Println(Error accepting:, err) continue } // 处理连接 go handleConnection(conn) } }2.2 TCP客户端package main import ( fmt net ) func main() { // 连接服务器 conn, err : net.Dial(tcp, localhost:8080) if err ! nil { fmt.Println(Error connecting:, err) return } defer conn.Close() // 发送数据 _, err conn.Write([]byte(Hello from client!\n)) if err ! nil { fmt.Println(Error writing:, err) return } // 读取响应 buffer : make([]byte, 1024) n, err : conn.Read(buffer) if err ! nil { fmt.Println(Error reading:, err) return } fmt.Printf(Received: %s, buffer[:n]) }3. UDP服务器和客户端3.1 UDP服务器package main import ( fmt net ) func main() { // 监听UDP端口 addr, err : net.ResolveUDPAddr(udp, :8080) if err ! nil { fmt.Println(Error resolving address:, err) return } conn, err : net.ListenUDP(udp, addr) if err ! nil { fmt.Println(Error listening:, err) return } defer conn.Close() fmt.Println(UDP server listening on port 8080) // 接收数据 buffer : make([]byte, 1024) for { n, clientAddr, err : conn.ReadFromUDP(buffer) if err ! nil { fmt.Println(Error reading:, err) continue } fmt.Printf(Received from %s: %s, clientAddr, buffer[:n]) // 发送响应 _, err conn.WriteToUDP([]byte(Hello from UDP server!\n), clientAddr) if err ! nil { fmt.Println(Error writing:, err) continue } } }3.2 UDP客户端package main import ( fmt net ) func main() { // 解析服务器地址 addr, err : net.ResolveUDPAddr(udp, localhost:8080) if err ! nil { fmt.Println(Error resolving address:, err) return } // 创建UDP连接 conn, err : net.DialUDP(udp, nil, addr) if err ! nil { fmt.Println(Error connecting:, err) return } defer conn.Close() // 发送数据 _, err conn.Write([]byte(Hello from UDP client!\n)) if err ! nil { fmt.Println(Error writing:, err) return } // 读取响应 buffer : make([]byte, 1024) n, _, err : conn.ReadFromUDP(buffer) if err ! nil { fmt.Println(Error reading:, err) return } fmt.Printf(Received: %s, buffer[:n]) }4. HTTP服务器4.1 基本HTTP服务器package main import ( fmt net/http ) func helloHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(Hello, World!\n)) } func main() { // 注册路由 http.HandleFunc(/, helloHandler) // 启动服务器 fmt.Println(HTTP server listening on port 8080) err : http.ListenAndServe(:8080, nil) if err ! nil { fmt.Println(Error starting server:, err) } }4.2 HTTP客户端package main import ( fmt net/http ) func main() { // 发送GET请求 resp, err : http.Get(http://localhost:8080) if err ! nil { fmt.Println(Error sending request:, err) return } defer resp.Body.Close() // 读取响应 buffer : make([]byte, 1024) n, err : resp.Body.Read(buffer) if err ! nil { fmt.Println(Error reading response:, err) return } fmt.Printf(Response: %s, buffer[:n]) fmt.Printf(Status: %s\n, resp.Status) }5. 高级网络编程5.1 自定义HTTP服务器package main import ( fmt net/http ) type MyHandler struct {} func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(Hello from custom handler!\n)) } func main() { // 创建自定义处理器 handler : MyHandler{} // 启动服务器 server : http.Server{ Addr: :8080, Handler: handler, } fmt.Println(Custom HTTP server listening on port 8080) err : server.ListenAndServe() if err ! nil { fmt.Println(Error starting server:, err) } }5.2 中间件package main import ( fmt net/http time ) // 日志中间件 func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start : time.Now() next.ServeHTTP(w, r) end : time.Now() fmt.Printf(%s %s %v\n, r.Method, r.URL.Path, end.Sub(start)) }) } func helloHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte(Hello, World!\n)) } func main() { // 注册路由 http.HandleFunc(/, helloHandler) // 使用中间件 wrappedHandler : loggingMiddleware(http.DefaultServeMux) // 启动服务器 server : http.Server{ Addr: :8080, Handler: wrappedHandler, } fmt.Println(HTTP server with middleware listening on port 8080) err : server.ListenAndServe() if err ! nil { fmt.Println(Error starting server:, err) } }6. 网络编程的最佳实践6.1 错误处理package main import ( fmt net ) func main() { // 错误处理示例 listener, err : net.Listen(tcp, :8080) if err ! nil { fmt.Println(Error listening:, err) return } defer listener.Close() for { conn, err : listener.Accept() if err ! nil { fmt.Println(Error accepting:, err) continue } go func(c net.Conn) { defer c.Close() buffer : make([]byte, 1024) n, err : c.Read(buffer) if err ! nil { fmt.Println(Error reading:, err) return } fmt.Printf(Received: %s, buffer[:n]) _, err c.Write([]byte(Hello!\n)) if err ! nil { fmt.Println(Error writing:, err) return } }(conn) } }6.2 超时设置package main import ( fmt net time ) func main() { // 设置超时 conn, err : net.DialTimeout(tcp, localhost:8080, 5*time.Second) if err ! nil { fmt.Println(Error connecting:, err) return } defer conn.Close() // 设置读取超时 err conn.SetReadDeadline(time.Now().Add(5 * time.Second)) if err ! nil { fmt.Println(Error setting read deadline:, err) return } // 发送数据 _, err conn.Write([]byte(Hello!\n)) if err ! nil { fmt.Println(Error writing:, err) return } // 读取响应 buffer : make([]byte, 1024) n, err : conn.Read(buffer) if err ! nil { fmt.Println(Error reading:, err) return } fmt.Printf(Received: %s, buffer[:n]) }6.3 连接池package main import ( fmt net sync ) type ConnectionPool struct { conns chan net.Conn addr string maxConns int mu sync.Mutex } func NewConnectionPool(addr string, maxConns int) *ConnectionPool { pool : ConnectionPool{ conns: make(chan net.Conn, maxConns), addr: addr, maxConns: maxConns, } // 初始化连接池 for i : 0; i maxConns/2; i { conn, err : net.Dial(tcp, addr) if err nil { pool.conns - conn } } return pool } func (p *ConnectionPool) Get() (net.Conn, error) { select { case conn : -p.conns: // 检查连接是否有效 if err : conn.SetReadDeadline(time.Now().Add(1 * time.Second)); err ! nil { conn.Close() return p.Get() } return conn, nil default: // 创建新连接 p.mu.Lock() defer p.mu.Unlock() if len(p.conns) p.maxConns { conn, err : net.Dial(tcp, p.addr) if err ! nil { return nil, err } return conn, nil } // 等待连接 conn : -p.conns return conn, nil } } func (p *ConnectionPool) Put(conn net.Conn) { select { case p.conns - conn: // 连接已放回池 default: // 连接池已满关闭连接 conn.Close() } } func (p *ConnectionPool) Close() { close(p.conns) for conn : range p.conns { conn.Close() } } func main() { // 使用连接池 pool : NewConnectionPool(localhost:8080, 10) defer pool.Close() // 获取连接 conn, err : pool.Get() if err ! nil { fmt.Println(Error getting connection:, err) return } defer pool.Put(conn) // 使用连接 _, err conn.Write([]byte(Hello!\n)) if err ! nil { fmt.Println(Error writing:, err) return } // 读取响应 buffer : make([]byte, 1024) n, err : conn.Read(buffer) if err ! nil { fmt.Println(Error reading:, err) return } fmt.Printf(Received: %s, buffer[:n]) }7. 实战应用7.1 简单的聊天服务器package main import ( fmt net strings ) var ( clients make(map[net.Conn]bool) broadcast make(chan []byte) register make(chan net.Conn) unregister make(chan net.Conn) ) func handleConnections() { for { select { case conn : -register: clients[conn] true fmt.Println(New client connected) case conn : -unregister: if _, ok : clients[conn]; ok { delete(clients, conn) conn.Close() fmt.Println(Client disconnected) } case message : -broadcast: for conn : range clients { err : conn.Write(message) if err ! nil { conn.Close() delete(clients, conn) } } } } } func handleClient(conn net.Conn) { defer func() { unregister - conn }() for { buffer : make([]byte, 1024) n, err : conn.Read(buffer) if err ! nil { break } message : buffer[:n] broadcast - message fmt.Printf(Broadcast: %s, message) } } func main() { // 启动处理协程 go handleConnections() // 监听端口 listener, err : net.Listen(tcp, :8080) if err ! nil { fmt.Println(Error listening:, err) return } defer listener.Close() fmt.Println(Chat server listening on port 8080) // 接受连接 for { conn, err : listener.Accept() if err ! nil { fmt.Println(Error accepting:, err) continue } register - conn go handleClient(conn) } }7.2 简单的HTTP API服务器package main import ( encoding/json fmt net/http ) type User struct { ID int json:id Name string json:name Age int json:age } var users []User{ {ID: 1, Name: Alice, Age: 30}, {ID: 2, Name: Bob, Age: 25}, } func getUsers(w http.ResponseWriter, r *http.Request) { w.Header().Set(Content-Type, application/json) json.NewEncoder(w).Encode(users) } func getUser(w http.ResponseWriter, r *http.Request) { w.Header().Set(Content-Type, application/json) // 提取ID id : r.URL.Path[len(/users/):] if id { http.Error(w, Missing ID, http.StatusBadRequest) return } // 查找用户 for _, user : range users { if fmt.Sprintf(%d, user.ID) id { json.NewEncoder(w).Encode(user) return } } http.Error(w, User not found, http.StatusNotFound) } func main() { // 注册路由 http.HandleFunc(/users, getUsers) http.HandleFunc(/users/, getUser) // 启动服务器 fmt.Println(API server listening on port 8080) err : http.ListenAndServe(:8080, nil) if err ! nil { fmt.Println(Error starting server:, err) } }8. 总结使用net.Listen()创建TCP服务器使用net.Dial()创建TCP客户端使用net.ListenUDP()创建UDP服务器使用net.DialUDP()创建UDP客户端使用http.ListenAndServe()创建HTTP服务器使用http.Get()、http.Post()等创建HTTP客户端实现自定义HTTP处理器和中间件合理设置超时和错误处理使用连接池提高性能掌握网络编程的最佳实践能够开发简单的网络应用
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2475528.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!