对于TCP三次握手和四次挥手,我们最主要的就是关注TCP头部的序列号、确认号以及几个标记位(SYN/FIN/ACK/RST)!!!

序列号
在初次建立连接的时候,客户端和服务端都会为「本次的连接」随机初始化一个序列号。(纵观整个TCP流程中,序列号可以用来解决网络包乱序的问题)

确认号
该字段表示「接收端」告诉「发送端」对上一个数据包已经成功接收(确认号可以⽤来解决网络包丢失的问题)

标记位
SYN为1时,表示希望创建连接。ACK为1时,确认号字段有效。FIN为1时,表示希望断开连接。RST为1时,表示TCP连接出现异常,需要断开。

tcp标志位,有6种标示:
SYN(synchronous建立联机)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码)
image.png

三握

以客户端发起连接为例


第一次握手
建立连接时,客户端会随机生成出序列号(这里的序列号一般叫做client_isn),并且把标志位设置为SYN(意味着要连接),然后把该报文发送给服务端,进入SYN_SEND状态,等待服务器确认

第二次握手
服务端接收到了客户端的请求之后,自己也初始化对应的序列号(这里的序列号一般叫做 server_isn,在「确认号」字段里填上client_isn + 1(相当于告诉客户端,已经收到了发送过来的序列号了) ,并且把 SYN 和 ACK 标记位都点亮(置为1),把该报文发送客户端,服务器进入SYN_RECV状态

第三次握手
客户端收到服务端发送的报文后,就知道服务端已经接收到了自己的序列号(通过确认号就可以知道),此时,客户端需要告诉服务端自己已经接收到了他发送过来的序列号,所以在「确认号」字段上填上server_isn+1,并且标记位 ACK 为1,发送报文后后客户端和服务器依次进入ESTABLISHED状态,完成握手
image.png

  1. 第一次 A:发 B:收
  2. 第二次 A:发 +
  3. 第三次 B:收 +

四挥


第一次挥手
假设客户端想要关闭连接,客户端会发 FIN 报文给服务端(其实就是把标志位 FIN 点亮)表示自己没有数据可发送了,但是仍然可接收数据。发送完毕之后,客户端进入FIN_WAIT_1(终止等待1)状态

第二次挥手
服务端收到 FIN 报文之后,回复 ACK 报文给客户端(表示已经收到了),但是还没有准备好关闭连接。服务器端发送完成后进入CLOSE_WAIT状态,客户端接收到这个确认包之后进入FIN_WAIT_2(等待终止2)状态,等待服务器发送连接释放报文(在这之前还需要接收服务器发送的最后数据)

第三次挥手
等服务端确认自己已经没有数据返回给客户端之后,就发送FIN报文给客户端了,自己进入LAST_ACK(最后确认)状态,等待客户端的确认

第四次挥手
客户端收到服务端的FIN报文之后,回应ACK报文,自己进入TIME_WAIT(时间等待)状态。此时TCP还没有释放,必须经过2*MSL(最长报文段寿命)的时间才进入CLOSED状态
服务器收到客户端发出的确认,立即进入CLOSED状态

image.png


四次挥手为什么要等2个MSL,而不是1个MSL?

数据包在网络中存活的时间是一个MSL,通信中一来一回就是2个MSL,超过2MSL后,数据包不可能存在,所以可以确保不会再收到消息了。

2msl是最短的确认数据包已经完全丢失的时间。客户端发送的数据包最长能存活1msl,应答的数据包同理,但是这两个并不是同一个数据包,。应答数据包是在经过1msl(最长),服务端收到客户端发送的数据包后根据tcp协议生成的,再由服务端发送给客户端,应答包也是最长存活1msl,而在客户端看来,他发出数据包,到接收到应答,最长有效就是2msl,低于这个时间,可能数据包还在传输中,你不能直接判断数据丟了,高于这个时间没意义,因为数据包已经不可能存活了

如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存活在网络里的老的TCP报文可能与新TCP连接报文冲突,造成数据冲突

目的是什么?

场景:
1. A发出ACK后,等待一段时间T,确保如果B重传FIN自己一定能收到
分析:
1. ACK从A到B最多经过1MSL,超过这个时间B会重发FIN
2. B重发的FIN最多经过1MSL到达A
结论:如果B重发了FIN,且网络没有故障(重发的FIN被丢弃或错误转发),那么A一定能在2MSL之内收到该FIN,因此A只需要等待2MSL。

为什么不是一个?

如果最后一个ACK包丢了,检测到丢包时用了一个MSL,这时主动关闭端就关闭了,对方再次重传的时候,主动关闭端就接收不到了,就会出现死循环。

部分参考:https://juejin.cn/post/7045059219216662564