# TCP三次握手与四次挥手

# 1. TCP三次握手

  • 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers);

  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

# 2. TCP四次挥手

  • 客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送;

  • 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号;

  • 服务器B关闭与客户端A的连接,发送一个FIN给客户端A;

  • 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

三次握手

# 3.三次握手的必要性

三次握手的主要目的是确认双方的接收和发送能力,确保连接的可靠性:

  1. 确认双方收发能力:客户端发送SYN确认自己能发送,服务器回复SYN+ACK确认自己能收发,客户端再发送ACK确认自己能接收。
  2. 防止已失效的连接请求:网络延迟可能导致客户端的连接请求在很久以后到达服务器,三次握手可以防止建立已失效的连接。
  3. 同步初始序列号:双方通过交换初始序列号来同步数据传输。

# 4. 四次挥手的原因

TCP连接是全双工的,需要分别关闭两个方向的数据传输:

  1. 独立关闭:当一方发送FIN报文时,只是关闭了该方向的数据传输,另一方向仍可以继续发送数据。
  2. 数据处理时间:服务器收到FIN后可能还有数据未发送完毕,需要时间处理完剩余数据。
  3. 确保数据完整性:分开关闭确保双方都能完整接收和发送所有数据。

# 5. TCP可靠性保证机制

TCP通过多种机制保证数据传输的可靠性:

  1. 数据包校验:通过校验和检测数据在传输过程中是否出错。
  2. 序列号和确认应答:通过序列号对数据包进行编号,接收方通过确认应答告知发送方数据已接收。
  3. 超时重传:发送方在一定时间内未收到确认应答时会重传数据。
  4. 连接管理:通过三次握手建立连接,四次挥手断开连接,确保连接的可靠性。
  5. 流量控制:通过滑动窗口机制控制发送方的发送速度,防止接收方缓冲区溢出。
  6. 拥塞控制:通过慢启动、拥塞避免等算法控制网络拥塞。
  7. 数据重排序:接收方将乱序到达的数据包重新排序后交给应用层。

# 6. TCP报文

TCP报文格式图

  • 序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  • 确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。

# 6.1 tcp的6种标志位的分别代表

标志位 全称 含义
SYN synchronous 发起一个新连接
ACK acknowledgement 确认序号有效
PSH push 接收方应该尽快将这个报文交给应用层
FIN finish 释放一个连接
RST reset 重置连接
URG urgent 紧急指针(urgent pointer)有效

不要将确认序号Ack与标志位中的ACK搞混了

# 6.2 握手过程具体报文内容

  • 第一次握手:客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里

第一次握手TCP报文格式图

  • 第二次握手:服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的ISN加1以,即X+1

第二次握手TCP报文格式图

  • 第三次握手:客户端再次发送确认包(ACK)SYN标志位为0,ACK标志位为1,并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1

第三次握手TCP报文格式图

为了方便查看,图片中标志位的所占字节大小与实际不符

初始序列号(ISN):当两台主机需要使用TCP传输协议传输数据时,会创建一个新的连接。这涉及希望启动连接的第一个主机,以生成所谓的初始序列号(ISN),它基本上是我们正在查看的序列字段中包含的第一个序列号。

# 7. TCP状态迁移

# 7.1 客户端TCP状态迁移

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

# 7.2 服务器TCP状态迁移

CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

# 8. 各个状态的意义如下

标志位 含义
LISTEN 侦听来自远方TCP端口的连接请求
SYN-SENT 在发送连接请求后等待匹配的连接请求;
SYN-RECEIVED 在收到和发送一个连接请求后等待对连接请求的确认;
ESTABLISHED 代表一个打开的连接,数据可以传送给用户;
FIN-WAIT-1 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 从远程TCP等待连接中断请求;
CLOSE-WAIT 等待从本地用户发来的连接中断请求;
CLOSING 等待远程TCP对连接中断的确认;
LAST-ACK 等待原来发向远程TCP的连接中断请求的确认;
TIME-WAIT 等待足够的时间以确保远程TCP接收到连接中断请求的确认;
CLOSED 没有任何连接状态;

# 9. 其他

# 9.1 为什么TCP链接不是两次

为了双方都能明确自己和对方的收、发能力是正常的。

  • 第一次握手:客户端无法知道自己发送是否正常,但是服务端收到请求,知道客户端发送能力正常,自己服务端的接受能力正常;

  • 第二次握手:服务的发送请求到客户端,客户端知道服务端接受到自己第一次握手的请求了,客户端知道自己的发送和接受能力正常,服务端的发送和接受能力正常;

  • 第三次握手:服务端接收到客户端的确认消息,确认了服务端的发送,接受能力正常。

视角 客收 客发 服收 服发
客视角 一 + 二 一 + 二
服视角 二 + 三 二 + 三

# 9.2 为什么TCP断开链接需要四次

第一次挥手:A 说“我没啥要说的了” 第二次挥手:B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话 第三次挥手:于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了” 第四次挥手:A 回答“知道了”,这样通话才算结束。

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手

# 9.3 确认号与序列号关系

确认号:其数值等于发送方的发送序号 +1(即接收方期望接收的下一个序列号)

# 9.4 TCP协议如何来保证传输的可靠性

TCP提供一种面向连接的、可靠的字节流服务。其中,面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个TCP连接。在一个TCP连接中,仅有两方进行彼此通信;而字节流服务意味着两个应用程序通过TCP链接交换8bit字节构成的字节流,TCP不在字节流中插入记录标识符。

# 9.5 对于可靠性,TCP通过以下方式进行保证

  • 数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时TCP发送数据端超时后会重发数据;

  • 对失序数据包重排序:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层;

  • 丢弃重复数据:对于重复数据,能够丢弃重复数据;

  • 应答机制:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;

  • 超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;

  • 流量控制:TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。

tcp传输过程

Last Updated: 9/16/2025, 8:23:04 PM