0%

TCP四次挥手

tcp四次挥手

TCP四次挥手的过程以及握手两端状态的变化。

挥手过程

  • 第一次挥手: 主动关闭方(可以使客户端,也可以是服务器端,这里标记为:A),将FIN置为1,ACK置为1,Seq(Sequence Number)设置为X为上一次对方传送过来的Ack(Acknowledgment Number)值,Ack(Acknowledgment Number)设置为Y为上一次对方传过来的Seq(Sequence Number)值+1。设置好以上值后,将数据发送至被动关闭方(这里标记为:B)。然后A进入FIN_WAIT_1状态。

  • 第二次挥手:B收到了A发送的FIN报文段,向A回复,将ACK置为1,Ack(Acknowledgment Number)设置为X第一次挥手中的Seq(Sequence Number)值+1,Seq(Sequence Number)设置为Y第一次挥手中的Ack(Acknowledgment Number)值。然后B进入CLOSE_WAIT状态,A收到B的回复后,进入FIN_WAIT_2状态。

  • 第三次挥手:B再次向A发送报文,将FIN置为1,ACK置为1,Ack(Acknowledgment Number)设置为X+1第二次挥手中的Ack(Acknowledgment Number)值,Seq(Sequence Number)设置为Y第二次挥手中的Seq(Sequence Number)值。然后B进入LAST_ACK状态,A收到B的报文后,进入TIME_WAIT状态。

  • 第四次挥手:A收到B发送的FIN报文段,像B回复,将ACK置为1,Ack(Acknowledgment Number)设置为Y第三次挥手中的Seq(Sequence Number)值+1,Seq(Sequence Number)设置为X+1第三次挥手中的Ack(Acknowledgment Number)值。然后A进入TIME_WAIT状态,B在收到报文后进入CLOSED状态,A在发送完报文等待了2MSL时间后进入CLOSED状态。

为什么 TIME_WAIT 状态要等待 2MSL 之后才关闭连接

  • 2MSL表示两个MSL的时长,MSL全称为Maximum Segment Life,表示TCP 对TCP Segment 生存时间的限制。

  • 为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST_ACK状态的B收不到对自己已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段。而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后A和B都正常进入到CLOSED状态。如果A在TIME_WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会在发送一次确认报文段。这样,B就无法按照正常步骤进入CLOSED状态。

  • 防止已失效的连接请求报文段出现在本连接中。A在发送完最后一个ACK报文段后,在经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

抓包实践

抓包看,挥手的过程却只有三次。这是因为数据传输中的延迟确认策略。

何谓延迟确认策略?

WIKI:TCP delayed acknowledgment is a technique used by some implementations of the Transmission Control Protocol in an effort to improve network performance. In essence, several ACK responses may be combined together into a single response, reducing protocol overhead. However, in some circumstances, the technique can reduce application performance.即接收方收到包后,如果暂时没有内容回复给发送方,则延迟一段时间再确认,假如在这个时间范围内刚好有数据需要传输,则和确认包一起回复。这种也被称为数据捎带。延迟确认只是减轻网络负担,未必可以提升网络性能,有些情况下反而会影响性能。

正是这个策略,让图中缺少了一次断开连接的包,仔细看可以发现8和9之间时间也是差了200ms左右,为什么是200ms?根据TCP/IP详解卷一里面的描述是绝不大部分平台的时延是按200ms来实现的,但是不允许超过500ms。

谈到延迟确认就必须再谈谈Nagle算法,两者的作用都是减轻网络负担,Nagle算法起源于John Nagle在RFC896的提议,所以命名为Nagle算法。Nagle在描述The small-packet problem时提到TCP在传输1字节有用信息时必须传输41字节的数据,其中20字节的TCP头,20字节的IP头,4000%的开销在低负载网络是可以容忍的,但是在重负载网络,这种开销是会导致网络拥塞,进而导致重传和数据丢失。这里暂时先不用关注拥塞、重传等,后面再讨论。重点关注下Nagle算法的实现原理,即在发送的数据在未被确认前,如果有新的小数据生成,那就把小数据收集起来,等凑足一个MSS或者收到确认后再发送。

说到这,我们就清楚了提到的延迟确认和Nagle算法的作用都是降低网络负担,提高传输效率,但是未必能提升网络性能。

参考