在Go中实现TCP通信需处理粘包问题,使用net包建立连接,通过长度头封包(如4字节长度+数据)实现消息边界,发送前写入数据长度,接收时先读长度再读数据体,结合ReadFull确保完整读取,每次收发均封装为sendPacket和readPacket函数,配合json或protobuf序列化,并设置超时防止阻塞,从而实现可靠的TCP通信。

在Go语言中实现TCP数据包的发送与接收,关键在于理解TCP是面向流的协议,不保留消息边界。这意味着你发送的多个数据包可能被合并接收,或一个大包被拆分成多次接收。因此,在实际开发中必须自行处理“粘包”问题。
Go标准库net提供了完整的TCP支持。服务端通过Listen监听端口,客户端用Dial发起连接。
服务端示例:
listener, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go handleConn(conn)
}客户端示例:
立即学习“go语言免费学习笔记(深入)”;
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
defer conn.Close()TCP本身无消息边界,需在应用层定义协议格式。常见方法是在数据前加长度头。
封包结构: [4字节长度][实际数据]
发送函数示例:
func sendPacket(conn net.Conn, data []byte) error {
var buf [4]byte
binary.BigEndian.PutUint32(buf[:], uint32(len(data)))
_, err := conn.Write(buf[:])
if err != nil {
return err
}
_, err = conn.Write(data)
return err
}接收函数示例:
func readPacket(conn net.Conn) ([]byte, error) {
var buf [4]byte
_, err := io.ReadFull(conn, buf[:])
if err != nil {
return nil, err
}
length := binary.BigEndian.Uint32(buf[:])
data := make([]byte, length)
_, err = io.ReadFull(conn, data)
return data, err
}基本上就这些。只要处理好长度头和分次读取,Go的TCP通信稳定可靠,适合做微服务通信、自定义协议传输等场景。关键是不能假设一次Read就拿到完整消息。
以上就是GolangTCP数据包发送与接收实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号