Go基础:一文掌握Go语言网络编程
文章目录
- 一、Go 语言网络编程概述
- 1.1 核心概念
- 1.2 连接管理
- 二、TCP 网络编程
- 2.1 TCP 服务器
- 2.2 TCP 客户端
- 三、UDP 网络编程
- 3.1 UDP 服务器
- 3.2 UDP 客户端
- 四、HTTP 网络编程
- 4.1 HTTP 服务器
- 4.2 HTTP 客户端
一、Go 语言网络编程概述
Go 语言凭借其强大的标准库和原生的并发支持,非常适合用来开发高性能的网络服务。无论是构建 HTTP 服务器、RPC 服务,还是实现 TCP/UDP 通信,Go 都提供了简洁而强大的 API。
Go 语言通过 net
包提供了对 TCP/IP、UDP、域名解析、Unix 域套接字等网络协议的支持。net
包是 Go 网络编程的核心,它封装了底层的系统调用,提供了简洁易用的接口。
1.1 核心概念
- Listener:用于监听和接受来自客户端的连接(如
net.Listen
)。 - Conn:代表一个网络连接,实现了
io.Reader
和io.Writer
接口,可以像读写文件一样读写网络数据。 - Addr:表示一个网络地址(IP + Port)。
- Dial:用于主动连接到服务器。
- TCP:适用于需要可靠传输的场景,如文件传输、HTTP、数据库连接等。
- UDP:适用于对实时性要求高、能容忍丢包的场景,如视频流、DNS、在线游戏等。
- HTTP:基于 TCP 的应用层协议,Go 的
net/http
包提供了强大的 HTTP 客户端和服务器支持。 - 并发模型:Go 的 Goroutine 和 Channel 使得网络编程更加高效和简洁,可以轻松处理大量并发连接。
1.2 连接管理
- 对于 TCP 服务器,确保使用 defer conn.Close()。
- 对于 HTTP 客户端,复用 http.Client 实例而不是频繁创建。
- 总是 defer resp.Body.Close()。
二、TCP 网络编程
TCP 是一种面向连接的、可靠的、基于字节流的传输层通信协议。Go 语言通过 net
包提供了对 TCP 的原生支持。
2.1 TCP 服务器
创建一个 TCP 服务器的标准流程是:监听 -> 接受连接 -> 处理连接。
TCP 服务器的基本流程:
- 监听指定端口。
- 接受客户端连接。
- 为每个连接启动一个 Goroutine 处理请求。
- 读取客户端数据并处理。
- 返回响应给客户端。
示例代码:简单的 TCP Echo 服务器
package main
import ("bufio""fmt""log""net"
)
func handleConnection(conn net.Conn) {defer conn.Close() // 确保连接关闭// 使用 bufio 读取客户端数据reader := bufio.NewReader(conn)for {message, err := reader.ReadString('\n')if err != nil {log.Println("Client disconnected:", err)return}log.Printf("Received: %s", message)// 将消息回显给客户端_, err = conn.Write([]byte("Echo: " + message))if err != nil {log.Println("Failed to send response:", err)return}}
}
func main() {// 监听 TCP 端口listener, err := net.Listen("tcp", ":8080")if err != nil {log.Fatal("Failed to listen:", err)}defer listener.Close()log.Println("TCP server started on :8080")for {// 接受客户端连接conn, err := listener.Accept()if err != nil {log.Println("Failed to accept connection:", err)continue}log.Println("New client connected:", conn.RemoteAddr())// 启动一个 Goroutine 处理连接go handleConnection(conn)}
}
2.2 TCP 客户端
客户端流程:连接 -> 读写 -> 关闭。
TCP 客户端的基本流程:
- 连接到服务器。
- 发送数据。
- 读取服务器响应。
- 关闭连接。
示例代码:TCP 客户端
package main
import ("bufio""fmt""log""net""os"
)
func main() {// 连接到 TCP 服务器conn, err := net.Dial("tcp", "localhost:8080")if err != nil {log.Fatal("Failed to connect:", err)}defer conn.Close()log.Println("Connected to TCP server")// 从标准输入读取用户输入reader := bufio.NewReader(os.Stdin)for {fmt.Print("Enter message: ")message, _ := reader.ReadString('\n')// 发送消息到服务器_, err := conn.Write([]byte(message))if err != nil {log.Println("Failed to send message:", err)return}// 读取服务器响应response, err := bufio.NewReader(conn).ReadString('\n')if err != nil {log.Println("Failed to read response:", err)return}fmt.Print("Server response: " + response)}
}
三、UDP 网络编程
UDP 是一种无连接的、不可靠的、面向数据报的传输层协议。与 TCP 不同,UDP 不保证数据包的顺序和可靠性,但开销更小,适用于对实时性要求高的场景(如视频流、DNS 查询)。
3.1 UDP 服务器
UDP 服务器的基本流程:
- 监听指定端口。
- 读取客户端发送的数据报。
- 处理数据并返回响应。
示例代码:UDP Echo 服务器
package main
import ("log""net"
)
func main() {// 监听 UDP 端口addr, err := net.ResolveUDPAddr("udp", ":8080")if err != nil {log.Fatal("Failed to resolve address:", err)}conn, err := net.ListenUDP("udp", addr)if err != nil {log.Fatal("Failed to listen:", err)}defer conn.Close()log.Println("UDP server started on :8080")buffer := make([]byte, 1024)for {// 读取客户端数据n, clientAddr, err := conn.ReadFromUDP(buffer)if err != nil {log.Println("Failed to read:", err)continue}log.Printf("Received from %s: %s", clientAddr, string(buffer[:n]))// 回显数据给客户端_, err = conn.WriteToUDP([]byte("Echo: "+string(buffer[:n])), clientAddr)if err != nil {log.Println("Failed to send response:", err)}}
}
3.2 UDP 客户端
示例代码:UDP 客户端
package main
import ("bufio""log""net""os"
)
func main() {// 解析服务器地址serverAddr, err := net.ResolveUDPAddr("udp", "localhost:8080")if err != nil {log.Fatal("Failed to resolve address:", err)}// 创建本地 UDP 连接conn, err := net.DialUDP("udp", nil, serverAddr)if err != nil {log.Fatal("Failed to dial:", err)}defer conn.Close()log.Println("Connected to UDP server")reader := bufio.NewReader(os.Stdin)for {fmt.Print("Enter message: ")message, _ := reader.ReadString('\n')// 发送消息_, err := conn.Write([]byte(message))if err != nil {log.Println("Failed to send message:", err)return}// 读取响应buffer := make([]byte, 1024)n, err := conn.Read(buffer)if err != nil {log.Println("Failed to read response:", err)return}fmt.Print("Server response: " + string(buffer[:n]))}
}
四、HTTP 网络编程
Go 语言内置了强大的 net/http
包,可以轻松构建 HTTP 客户端和服务器。
4.1 HTTP 服务器
示例代码:简单的 HTTP 服务器
package main
import ("fmt""log""net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}
func main() {http.HandleFunc("/", helloHandler)log.Println("HTTP server started on :8080")log.Fatal(http.ListenAndServe(":8080", nil))
}
4.2 HTTP 客户端
示例代码:HTTP 客户端
package main
import ("fmt""io/ioutil""net/http"
)
func main() {resp, err := http.Get("http://localhost:8080/world")if err != nil {fmt.Println("Failed to make request:", err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("Failed to read response:", err)return}fmt.Println("Response:", string(body))
}