TCP--连接建立与拆除

连接建立--三次握手

三次握手流程

  1. A初始化连接准备,包括初始化序列号SEQ,然后发送SYN报文
  2. B收到后,回复一个报文,包括自己的SEQ,并且SYN和ACK都置一
  3. A收到后也回复一个ACK,对于A而言连接建立;B收到ACK后对于B而言连接建立。

image-20210910094722376

我们要知道:

  • 连接是双向的,tcp是全双工通信协议,连接建立表示的是通信双方都认为自己连接上了。
  • 网络是分布式的,A和B没有统一的时钟,要确认一个连接是否过时只能由同一方进行确认。

为什么要进行三次握手

  • 连接是双方的

  • 通信是不稳定的

  • 通过三次握手才能阻止重复历史连接的初始化

  • 通过三次握手才能对通信双方的初始序列号进行初始化

我们假设三次握手的报文分别为1、2、3。报文可能会延迟到达或者丢失,所以发送方会在发送后启动一个定时器,超时后需要重新发送。

假设只进行两次握手,即B收到报文1后发送报文即建立了连接。因为网络是分布式的,而且是不稳定的,B无法知道报文1是否是经过延迟才到达,如果是延迟到达的,那么该报文 其实已经过期,还为它分配资源是完全浪费的。

网络是分布式的,A和B没有统一的时钟,要确认一个连接是否过时只能由同一方进行确认。所以A发送完1后要等到一个报文2回来才知道此次没有出现延迟,是否可以正常建立连接。

连接拆除--四次挥手

流程:

image-20210914105746948

  1. 想要拆除连接的一方A发送FIN报文,自身进入到FIN_WAIT_1状态;
  2. 被拆除连接的一方B接收到FIN报文,发ACK,自身进入到CLOSE_WAIT状态;
  3. A收到ACK,进入FIN_WAIT_2状态;
  4. B发送FIN,自身进入LAST_ACK状态;
  5. A收到FIN,发送ACK,自身进入TIME_WAIT状态;
  6. B收到ACK报文,B上的这个socket关闭,端口释放;
  7. A等待2MSL后socket关闭,释放端口。

从以上连接拆除过程我们可以看到:主动发送第一个FIN报文的一方会进入TIME_WAIT状态;进入TIME_WAIT状态的一方需要等待2MSL时间才会释放端口,在2MSL时间内,这个socket对应的四元组(源目IP、源目端口)处于冻结状态。

TIME_WAIT状态的作用主要有两个:

  1. 避免拆链报文在链路中丢失造成连接关闭异常:在第6步,B没有收到ACK报文的时候会认为A没有收到FIN包,进而会重传第4步的FIN,如果这个时候没有TIME_WAIT状态,A侧socket已经关闭,A会针对B发送的FIN包响应RST,有可能导致B连接异常。
  2. *避免乱序到来的业务报文在新生成的socket连接中引发混乱:假设在拆链前有TCP报文由于中间网络传输原因导致在第7步完成之后才到达,如果没有TIME_WAIT状态而A和B又使用同样的4元组新建了一个新的socket,那么迷路的数据包就会进入到新的socket中进行处理,可能导致业务异常。

通过TIME_WAIT状态可以很好的规避上面提到的两个问题,TIME_WAIT状态的老化时间是2MSL,MSL是最大分段生存时间,表示的是一个TCP分段可能在网络上存在的最大时间。2倍MSL的设计可以很好的满足报文在A、B之间一来一回的最大需要消耗的时间,最大程度上避免上述两个问题。在CentOS系统中,MSL的时间一般是30s。

posted @ 2021-09-23 14:45  Glaci  阅读(406)  评论(0编辑  收藏  举报