zoukankan      html  css  js  c++  java
  • TCP断开连接的相关问题

    1.TCP四次挥手过程和状态变迁

      TCP断开连接时通过四次挥手方式,双方都可以主动断开连接,断开连接后主机中的资源将被释放。

      

       (1)客户端打算关闭连接,此时会发送一个TCP首部FIN标志位被置为1的报文,即FIN报文,之后客户端进入FIN_WAIT_1状态。

      (2)服务端收到该报文后,就向客户端发送ACK应答报文,接着服务端进入CLOSED_WAIT状态。

      (3)客户端收到服务端的ACK应答报文后,之后进入FIN_WAIT_2状态。

      (4)等待服务端处理完数据后,也向客户端发送FIN报文,之后服务端进入LAST_ACK状态。

      (5)客户端收到服务端的FIN报文后,回一个ACK应答报文,之后进入TIME_WAIT状态。

      (6)服务端收到了ACK应答报文后,就进入CLOSE状态,至此服务端已经完成连接的关闭。

      (7)客户端在经过2MSL时间后,自动进入CLOSE状态,至此客户端也完成连接的关闭。

      每个方向都需要一个FIN和一个ACK,因此通常被称为四次挥手。

      这里值得注意的是:主动关闭连接的,才有TIME_WAIT状态。

    2.为什么挥手需要四次?

      关闭连接时,客户端向服务端发送FIN报文时,仅仅表示客户端不再发送数据了但是还能够接收数据;

      服务器收到客户端的FIN报文时,先回一个ACK应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN报文给客户端表示同意现在关闭连接。

      所以说,服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN一般都会分开发送,从而比三次握手多了一次。

    3.为什么TIME_WAIT等待的时间是2MSL?

      MSL是报文的最大生存时间(Maximum Segment Lifetime),它是任何报文在网络上存在的最长时间,超过这个时间报文就会被丢弃。因为TCP报文基于IP协议的,而IP头中有一个TTL字段,是IP数据报可以经过的最大路由数,每经过一个处理它的路由器,此值就减1,当这个值为0时,就表示数据报将被丢弃,同时发送ICMP报文通知源主机。MSL和TTL的区别是:MSL的单位是时间,而TTL是经过路由跳数,所以MSL应该要大于等于TTL消耗为0的时间,以确保报文已被自然消亡。

      TIME_WAIT等待2倍的MSL:网络中可能存在来自发送方的数据包,当这些数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待2倍的时间。

      比如,如果被动关闭方没有收到断开连接的最后的ACK报文,就会触发超时重发FIN报文,另一方接收到FIN后,会重发ACK给被动关闭方,一来一去正好是2个MSL。这个时间是从客户端收到FIN后发送ACK开始计时的,如果在TIME_WAIT时间内,应为客户端的ACK没有传输到服务端,客户端又收到了服务端重发的FIN报文,那么2MSL时间将重新计时。

    4.为什么需要TIME_WAIT状态?

      主动关闭连接的一方才会有TIME_WAIT状态。

      (1)原因一:防止旧连接的数据包

      如果TIME_WAIT没有等待时间或者时间过短,被延迟的数据包抵达会发生什么?

     

       服务端在关闭连接之前发送SEQ=301报文,被网络延迟,这时有相同端口的TCP连接被复用后,被延迟的SEQ=301抵达了客户端,那么客户端有可能正常接收这个过期的报文,这就会产生数据错乱等严重的问题。所以,TCP中有2MSL这个时间,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是在新建立连接所产生的。

     (2)保证连接正确关闭

      等待足够的时间以确保最后的ACK能让被动关闭方接收,从而帮助其正常关闭。

      

       如果客户端四次挥手的最后一个ACK报文在网络中被丢失,此时如果客户端TIME_WAIT过短或没有,就直接进入了CLOSE状态,那么服务端就会一直处于LAST_ACK状态。当客户端发起建立连接的SYN请求报文后,服务端会发送RST报文给客户端,连接建立的过程就会被中止。

      而如果TIME_WAIT等待时间足够长的话:(1)服务端正常接收到四次挥手的最后一个ACK报文,则服务端正常关闭连接。(2)服务端没有收到四次挥手的最后一个ACK报文,重发FIN关闭连接报文等待新的ACK报文。

      所以,客户端在TIME_WAIT状态等待2MSL时间后,就可以保证双方的连接都可以正常关闭。

    5.TIME_WAIT过多有什么危害?

      如果服务器有处于TIME_WAIT状态的TCP,则说明是由服务器方主动发起的断开请求。过多的TIME_WAIT状态的危害有:

    • 对内存资源的占用;
    • 对端口资源的占用,一个TCP连接至少消耗一个本地端口,如果TIME_WAIT状态过多,占满了所有的端口资源,则会导致无法建立新的连接。  

    6.如果已经建立了连接,但是客户端突然出现了故障了怎么办?

      TCP中有一个保活机制,这个机制的原理是:

      定义一个时间段,在这个时间段,如果没有任何连接相关的活动,TCP保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的TCP连接已经死亡,系统内核将错误信息通知给上层应用程序。

      如果开启了TCP保活,需要考虑这三种情况:

    • 对端程序是正常工作的,当TCP保活的探测报文发送给对端,对端会正常响应,这样TCP保活时间会被重置,等待下一个TCP保活时间的到来;
    • 对端程序崩溃并重启,当TCP保活的探测报文发送给对端后,对端是可以响应的,但由于没有该连接的有效信息,会产生一个RST报文,这样很快就会发现TCP连接已经被重置;
    • 对端程序崩溃或对端由于其他原因导致报文不可达,当TCP保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,达到保活探测次数后,TCP汇报该TCP连接已经死亡。

    参考文献:https://mp.weixin.qq.com/s/ihDCVCI4jm24XDZ9bCTfqQ

  • 相关阅读:
    Leetcode 16.25 LRU缓存 哈希表与双向链表的组合
    Leetcode437 路径总和 III 双递归与前缀和
    leetcode 0404 二叉树检查平衡性 DFS
    Leetcode 1219 黄金矿工 暴力回溯
    Leetcode1218 最长定差子序列 哈希表优化DP
    Leetcode 91 解码方法
    Leetcode 129 求根到叶子节点数字之和 DFS优化
    Leetcode 125 验证回文串 双指针
    Docker安装Mysql记录
    vmware虚拟机---Liunx配置静态IP
  • 原文地址:https://www.cnblogs.com/xiaona-/p/12823737.html
Copyright © 2011-2022 走看看