Go(Golang)中的编程网络编程具有易用性、强大性和乐趣。高级本指南深入探讨了网络编程的网络复杂性,涵盖了协议、编程TCP/UDP 套接字、高级并发等方面的网络内容,并附有详细的编程注释。
TCP 服务器和客户端示例演示了TCP通信的基础。
服务器:
package mainimport ( "net" "fmt")func main() { // Listen on TCP port 8080 on all available unicast and // any unicast IP addresses. listen, err := net.Listen("tcp", ":8080") if err != nil { fmt.Println(err) return } defer listen.Close() // Infinite loop to handle incoming connections for { conn, err := listen.Accept() if err != nil { fmt.Println(err) continue } // Launch a new goroutine to handle the connection go handleConnection(conn) }}func handleConnection(conn net.Conn) { defer conn.Close() buffer := make([]byte, 1024) // Read the incoming connection into the buffer. _, err := conn.Read(buffer) if err != nil { fmt.Println(err) return } // Send a response back to the client. conn.Write([]byte("Received: " + string(buffer)))}
客户端:
package mainimport ( "net" "fmt")func main() { // Connect to the server at localhost on port 8080. conn, err := net.Dial("tcp", "localhost:8080") if err != nil { fmt.Println(err) return } defer conn.Close() // Send a message to the server. conn.Write([]byte("Hello, server!")) buffer := make([]byte, 1024) // Read the response from the server. conn.Read(buffer) fmt.Println(string(buffer))}
服务器在端口8080上等待连接,读取传入的消息并发送响应。客户端连接到服务器,发送消息并打印服务器的响应。
与TCP不同,UDP是无连接的。以下是UDP服务器和客户端的实现。
服务器:
package mainimport ( "net" "fmt")func main() { // Listen for incoming UDP packets on port 8080. conn, err := net.ListenPacket("udp", ":8080") if err != nil { fmt.Println(err) return } defer conn.Close() buffer := make([]byte, 1024) // Read the incoming packet data into the buffer. n, addr, err := conn.ReadFrom(buffer) if err != nil { fmt.Println(err) return } fmt.Println("Received: ", string(buffer[:n])) // Write a response to the client's address. conn.WriteTo([]byte("Message received!"), addr)}
客户端:
package mainimport ( "net" "fmt")func main() { // Resolve the server's address. addr, err := net.ResolveUDPAddr("udp", "localhost:8080") if err != nil { fmt.Println(err) return } // Dial a connection to the resolved address. conn, err := net.DialUDP("udp", nil, addr) if err != nil { fmt.Println(err) return } defer conn.Close() // Write a message to the server. conn.Write([]byte("Hello, server!")) buffer := make([]byte, 1024) // Read the response from the server. conn.Read(buffer) fmt.Println(string(buffer))}
服务器从任何客户端读取消息并发送响应。客户端发送消息并等待响应。
并发允许同时处理多个客户端。
package mainimport ( "net" "fmt")func main() { // Listen on TCP port 8080. listener, err := net.Listen("tcp", ":8080") if err != nil { fmt.Println(err) return } defer listener.Close() for { // Accept a connection. conn, err := listener.Accept() if err != nil { fmt.Println(err) continue } // Handle the connection in a new goroutine. go handleConnection(conn) }}func handleConnection(conn net.Conn) { defer conn.Close() buffer := make([]byte, 1024) // Read the incoming connection. conn.Read(buffer) fmt.Println("Received:", string(buffer)) // Respond to the client. conn.Write([]byte("Message received!"))}
通过为每个连接使用新的 goroutine,多个客户端可以同时连接。
Gorilla Mux 库简化了 HTTP 请求路由。
package mainimport ( "fmt" "github.com/gorilla/mux" "net/http")func main() { // Create a new router. r := mux.NewRouter() // Register a handler function for the root path. r.HandleFunc("/", homeHandler) http.ListenAndServe(":8080", r)}func homeHandler(w http.ResponseWriter, r *http.Request) { // Respond with a welcome message. fmt.Fprint(w, "Welcome to Home!")}
这段代码设置了一个 HTTP 服务器,并为根路径定义了一个处理函数。
实现 HTTPS 服务器可以确保安全通信。
package mainimport ( "net/http" "log")func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Respond with a message. w.Write([]byte("Hello, this is an HTTPS server!")) }) // Use the cert.pem and key.pem files to secure the server. log.Fatal(http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil))}
服务器使用 TLS(传输层安全性)来加密通信。
可以使用自定义的 TCP 协议进行专门的通信。
package mainimport ( "net" "strings")func main() { // Listen on TCP port 8080. listener, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } defer listener.Close() for { // Accept a connection. conn, err := listener.Accept() if err != nil { panic(err) } // Handle the connection in a new goroutine. go handleConnection(conn) }}func handleConnection(conn net.Conn) { defer conn.Close() buffer := make([]byte, 1024) // Read the incoming connection. conn.Read(buffer) // Process custom protocol command. cmd := strings.TrimSpace(string(buffer)) if cmd == "TIME" { conn.Write([]byte("The current time is: " + time.Now().String())) } else { conn.Write([]byte("Unknown command")) }}
这段代码实现了一个简单的自定义协议,当客户端发送命令“TIME”时,它会回复当前时间。
WebSockets 提供了通过单一连接的实时全双工通信。
package mainimport ( "github.com/gorilla/websocket" "net/http")var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024,}func handler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { http.Error(w, "Could not open websocket connection", http.StatusBadRequest) return } defer conn.Close() for { messageType, p, err := conn.ReadMessage() if err != nil { return } // Echo the message back to the client. conn.WriteMessage(messageType, p) }}func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}
WebSocket 服务器会将消息回传给客户端。
可以使用 context 包来管理连接超时。
package mainimport ( "context" "fmt" "net" "time")func main() { // Create a context with a timeout of 2 seconds ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // Dialer using the context dialer := net.Dialer{ } conn, err := dialer.DialContext(ctx, "tcp", "localhost:8080") if err != nil { panic(err) } buffer := make([]byte, 1024) _, err = conn.Read(buffer) if err == nil { fmt.Println("Received:", string(buffer)) } else { fmt.Println("Connection error:", err) }}
这段代码为从连接读取数据设置了两秒的截止时间。
速率限制控制请求的速率。
package mainimport ( "golang.org/x/time/rate" "net/http" "time")// Define a rate limiter allowing two requests per second with a burst capacity of five.var limiter = rate.NewLimiter(2, 5)func handler(w http.ResponseWriter, r *http.Request) { // Check if request is allowed by the rate limiter. if !limiter.Allow() { http.Error(w, "Too Many Requests", http.StatusTooManyRequests) return } w.Write([]byte("Welcome!"))}func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}
此示例使用速率限制器,将请求速率限制为每秒两个请求,突发容量为五个。
责任编辑:赵宁宁 来源: 技术的游戏 Go编程(责任编辑:知识)
华硕推Hyper M.2 x16 Gen5扩展卡 支持最高四盘扩展
四川阿坝州提高孤儿基本生活最低养育标准 2022年1月起执行
“放水养鱼”式管理激发市场活力 安徽降本减负典型经验做法获点赞
RLHF中的「RL」是必需的吗?有人用二进制交叉熵直接微调LLM,效果更好