Skip to main content

TCP

传输控制协议(英语:Transmission Control Protocol,缩写:TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。处于OSI 模型的传输层(第四层)。

三个阶段#

  • 连接创建 (connection establishment) - 三次握手
  • 数据传送(data transfer)
  • 连接终止(connection termination)- 四次挥手

三次握手#

  • 客户端(通过执行 connect 函数)向服务器端发送一个 SYN 包,请求一个主动打开。该包携带客户端为这个连接请求而设定的随机数 A 作为消息序列号。
  • 服务器端收到一个合法的 SYN 包后,把该包放入 SYN 队列中;回送一个 SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身携带一个随机产生的序号 B。
  • 客户端收到 SYN/ACK 包后,发送一个 ACK 包,该包的序号被设定为 A+1,而 ACK 的确认码则为 B+1。然后客户端的 connect 函数成功返回。当服务器端收到这个 ACK 包的时候,把请求帧从 SYN 队列中移出,放至 ACCEPT 队列中;这时 accept 函数如果处于阻塞状态,可以被唤醒,从 ACCEPT 队列中取出 ACK 包,重新创建一个新的用于双向通信的 sockfd,并返回
  • SYN 队列:存放完成了二次握手的结果。 队列长度由 listen 函数的参数 backlog 指定。
  • ACCEPT 队列:存放完成了三次握手的结果。队列长度由 listen 函数的参数 backlog 指定。

四次挥手#

连接终止使用了四路握手过程(或称四次握手,four-way handshake),在这个过程中连接的每一侧都独立地被终止。当一个端点要停止它这一侧的连接,就向对侧发送 FIN,对侧回复 ACK 表示确认。因此,拆掉一侧的连接过程需要一对 FIN 和 ACK,分别由两侧端点发出。

首先发出 FIN 的一侧,如果给对侧的 FIN 响应了 ACK,那么就会超时等待 2*MSL 时间,然后关闭连接。在这段超时等待时间内,本地的端口不能被新连接使用;避免延时的包的到达与随后的新连接相混淆。RFC793 定义了 MSL 为 2 分钟,Linux 设置成了 30s。参数 tcp_max_tw_buckets 控制并发的 TIME_WAIT 的数量,默认值是 180000,如果超限,那么,系统会把多的 TIME_WAIT 状态的连接给 destory 掉,然后在日志里打一个警告(如:time wait bucket table overflow)

参考#