Go语言TCP编程:从协议原理到完整通信代码实现

阿橙
阿橙
发布时间:2026-10-15| 5人浏览过
原创

本文深入解析Go语言中基于 net 包的TCP编程,涵盖面向连接、可靠交付等核心特性。详细梳理TCP三次握手建立连接与四次挥手释放连接的流程,并结合完整示例代码演示服务端监听、客户端连接及双向数据通信的具体实现方法。

TCP协议核心特性解析

TCP(传输控制协议)是面向连接的运输层协议,其核心优势在于提供可靠、有序的数据传输服务。在使用 net 包进行开发前,理解以下特性至关重要:

  • 面向连接:通信前必须建立TCP连接,数据传输完毕后需释放连接,确保资源有效管理。
  • 点对点通信:每条TCP连接仅包含两个端点,保证数据传输的针对性。
  • 可靠交付:通过序列号和确认机制,确保数据无差错、不丢失、不重复且按序到达。
  • 全双工通信:允许通信双方在任一时刻互相发送数据,提高交互效率。
  • 面向字节流:TCP将应用层数据视为连续的字节流处理,屏蔽了底层数据包的结构差异。

TCP连接的生命周期

TCP连接的形成与销毁涉及复杂的握手与挥手过程,理解这些状态有助于排查网络连通性问题。

TCP 连接建立:三次握手

传输控制块(TCB)用于存储连接关键信息,如缓冲指针和序列号。假设主机A为客户端,主机B为服务端:

  • 第一次握手:服务端创建TCB并进入 LISTEN 状态。客户端创建TCB后,发送同步位 SYN=1 的请求报文段,选择初始序号 seq=x。该报文段消耗一个序号但不携带数据,客户端随后进入同步已发送状态。
  • 第二次握手:服务端收到请求后,若同意建立连接,则回复确认报文段,将 SYN 和 ACK 置为 1,确认号为 ack=x+1,并选择自己的初始序号 y。服务端进入同步收到状态,同样消耗一个序号。
  • 第三次握手:客户端收到确认后,向服务端发送确认报文段,ACK=1,确认号 ack=y+1,序号 seq=x+1。此时连接正式建立,双方进入 ESTABLISHED 状态。

TCP 连接释放:四次挥手

当数据传输完毕,主动关闭方A发送带有 FIN=1 的释放报文段(序号 seq=u),进入 FIN-WAIT-1 状态。服务端B收到后发出确认 ack=u+1,进入 CLOSE-WAIT 半关闭状态,此时A无法发送数据但B仍可发送。B的应用进程通知TCP释放连接后,发送 FIN=1 报文段(序号 w),进入 LAST-ACK 状态。A收到后发出最终确认 ack=w+1,进入 TIME-WAIT 状态。经过 2MSL(最长报文段寿命,通常默认为2分钟)的时间等待后,A彻底进入 CLOSED 状态。

Go语言TCP通信代码实现

基于标准库 net 包,我们可以快速构建可靠的TCP通信应用。首先创建 client 和 server 两个目录以分离逻辑。

第1步:服务端建立监听

在Go中,使用 net.Listen 方法绑定特定端口进行监听。监听成功后,应立即使用 defer listener.Close() 确保程序退出时正确释放资源。

ADDRESS := "127.0.0.1:5000"
listener, err := net.Listen("tcp", ADDRESS)
if err != nil {
    fmt.Printf("start tcp server %s failed ,err : %s ", listener, err)
    return
}
defer listener.Close()

第2步:客户端发起连接

客户端通过 net.Dial 主动向服务端发起TCP连接。连接建立后,返回的 conn 对象可用于后续的数据读写操作。建议检查错误以确保连接成功建立。

ADDRESS := "127.0.0.1:5000"
conn, err := net.Dial("tcp", ADDRESS) // 主动与服务端建立连接
if err != nil {
    fmt.Printf("dial %s failed; err :%s", ADDRESS, err)
    return
}

第3步:实现双向数据通信

通信阶段的核心是利用 Read 和 Write 方法在服务端和客户端之间交换数据。为了支持持续交互,通常结合循环结构进行处理。

服务端接收与回复

服务端需要不断等待客户端发来的数据。使用 bufio.NewReader 可以方便地读取用户输入并进行回复,形成简单的交互式聊天功能。

var data [1024]byte
var msg string
reader := bufio.NewReader(os.Stdin)
for {
    // 接受来自客户端的信息
    n, err := conn.Read(data[:])
    if err == io.EOF {
        break
    }
    if err != nil {
        fmt.Printf("read from conn failed,err:%s", err)
        return
    }
    fmt.Println("Access Info : ", string(data[:n]))
    
    // 回复信息给客户端
    fmt.Print("回复信息:")
    msg, _ = reader.ReadString('\n')
    msg = strings.TrimSpace(msg)
    if msg == "exit" {
        break
    }
    _, _ = conn.Write([]byte(msg))
}
defer conn.Close()

客户端发送与接收

客户端持续获取用户输入并通过 Write 发送至服务端,同时从服务端接收回复内容。设置 “exit” 命令以便优雅退出循环。

for {
    fmt.Print("请输入:")
    msg, _ := reader.ReadString('\n')
    msg = strings.TrimSpace(msg)
    if msg == "exit" {
        break
    }
    // 发送数据至服务端
    _, _ = conn.Write([]byte(msg))
    
    // 接收服务端的回复
    n, err := conn.Read(data[:])
    if err == io.EOF {
        break
    }
    if err != nil {
        fmt.Println("read from conn failed, err :", err)
        return
    }
    fmt.Println("收到的回复:", string(data[:n]))
}
以上就是Go语言TCP从原理到代码实现详解的详细内容,更多关于Go TCP原理代码的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。