Go 语言的
net
包为网络编程提供了简洁高效的接口。我们可以使用它快速构建 TCP 网络服务,如聊天服务器、RPC、微服务通信等。
一、TCP简介
TCP(Transmission Control Protocol)是面向连接的、可靠的传输协议,通信模型为客户端-服务端(Client-Server)。
基本流程:
arduino
Client -----> Server(连接)
Client <----> Server(数据收发)
Client -----X Server(断开)
二、TCP服务端开发流程
1. 基本步骤
- • 创建监听器
net.Listen("tcp", address)
- • 接收连接
ln.Accept()
- • 启动协程处理每个连接
2. 示例代码:简单回显服务端
go
package main
import (
"bufio"
"fmt"
"net"
)
func main() {
ln, err := net.Listen("tcp", ":8000")
if err != nil {
panic(err)
}
fmt.Println("Server is listening on :8000...")
for {
conn, err := ln.Accept()
if err != nil {
fmt.Println("Accept error:", err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
fmt.Println("Client connected:", conn.RemoteAddr())
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
msg := scanner.Text()
fmt.Println("Received:", msg)
conn.Write([]byte("Echo: " + msg + "\n"))
}
}
三、TCP客户端开发流程
1. 基本步骤
- • 使用
net.Dial("tcp", address)
发起连接 - • 使用
conn.Write()
发送数据 - • 使用
conn.Read()
或bufio.Scanner
接收响应
2. 示例代码:简单回显客户端
go
package main
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8000")
if err != nil {
panic(err)
}
defer conn.Close()
fmt.Println("Connected to server.")
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Print("Input: ")
if !scanner.Scan() {
break
}
text := scanner.Text()
conn.Write([]byte(text + "\n"))
reply := bufio.NewReader(conn)
msg, _ := reply.ReadString('\n')
fmt.Print("Server reply: " + msg)
}
}
四、服务端并发处理连接
- • 每个连接使用
go handleConnection(conn)
启动一个 goroutine。 - • 利用 channel、sync 等包实现更复杂的控制逻辑。
- • 避免 goroutine 泄漏,及时关闭连接。
五、进阶技巧与注意事项
问题 | 建议 |
---|---|
粘包/拆包问题 | 采用固定长度协议或使用 \n 等分隔符协议 |
异常断开检测 | 读取错误后及时清理资源 |
超时控制 | 使用 conn.SetDeadline 设置读写超时 |
多客户端广播/聊天群 | 使用 map 管理连接池,遍历发送消息 |
六、实战小案例:群聊服务端片段
go
var clients = make(map[net.Conn]string)
var broadcast = make(chan string)
func main() {
go broadcaster()
// 省略监听与连接处理...
}
func handleConnection(conn net.Conn) {
defer conn.Close()
clients[conn] = conn.RemoteAddr().String()
for scanner.Scan() {
msg := scanner.Text()
broadcast <- clients[conn] + ": " + msg
}
delete(clients, conn)
}
func broadcaster() {
for {
msg := <-broadcast
for conn := range clients {
fmt.Fprintln(conn, msg)
}
}
}
七、总结
- • TCP 是基础但强大的通信方式,适用于高可靠性场景。
- • Go 的并发模型使构建高性能网络服务变得简单。
- • 在生产环境中,还需结合日志、连接池、协议封装等技术。