登录
首页 >  Golang >  Go教程

Golang TCP数据包收发实战教程

时间:2026-04-06 15:55:15 447浏览 收藏

本文深入浅出地讲解了在Go语言中实现可靠TCP通信的核心要点,直击TCP面向流、无消息边界的本质问题——粘包,并通过长度头封包(4字节长度前缀+数据体)、ReadFull确保完整读取、sendPacket/readPacket函数封装、超时控制及json/protobuf序列化等实战手段,构建出稳定、可复用的TCP收发机制;无论你是开发微服务底层通信、自定义协议传输,还是想真正掌握Go网络编程的底层逻辑,这篇教程都提供了即学即用、经生产验证的关键技术路径。

GolangTCP数据包发送与接收实践

在Go语言中实现TCP数据包的发送与接收,关键在于理解TCP是面向流的协议,不保留消息边界。这意味着你发送的多个数据包可能被合并接收,或一个大包被拆分成多次接收。因此,在实际开发中必须自行处理“粘包”问题。

使用net包建立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)
}

客户端示例:

conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
    log.Fatal(err)
}
defer conn.Close()

解决粘包:封包与拆包

TCP本身无消息边界,需在应用层定义协议格式。常见方法是在数据前加长度头。

封包结构: [4字节长度][实际数据]

  • 发送前先写入数据长度(如uint32),再写数据体
  • 接收时先读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
}

完整通信流程建议

  • 连接建立后,所有发送都走sendPacket封装
  • 接收循环中持续调用readPacket获取完整消息
  • 可结合jsonprotobuf序列化结构体数据
  • 设置合理的超时(SetReadDeadline)防止阻塞

基本上就这些。只要处理好长度头和分次读取,Go的TCP通信稳定可靠,适合做微服务通信、自定义协议传输等场景。关键是不能假设一次Read就拿到完整消息。

今天关于《Golang TCP数据包收发实战教程》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>