「客户端」学习网络编程,不了解TCP协议?难怪面试被刷下去,还不来学习!( 九 )

30 秒 。 Linux 系统停留在 TIME_WAIT 的时间为固定的 60 秒 。
其定义在 Linux 内核代码里的名称为 TCP_TIMEWAIT_LEN:
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
state about 60 seconds */
如果要修改 TIME_WAIT 的时间长度 , 只能修改 Linux 内核代码里 TCP_TIMEWAIT_LEN 的值 , 并重新编译 Linux 内核 。
为什么需要 TIME_WAIT 状态?
主动发起关闭连接的一方 , 才会有 TIME-WAIT 状态 。
需要 TIME-WAIT 状态 , 主要是两个原因:

  • 防止具有相同「四元组」的「旧」数据包被收到;
  • 保证「被动关闭连接」的一方能被正确的关闭 , 即保证最后的 ACK 能让被动关闭方接收 , 从而帮助其正常关闭;
原因一:防止旧连接的数据包
假设 TIME-WAIT 没有等待时间或时间过短 , 被延迟的数据包抵达后会发生什么呢?
接收到历史数据的异常

  • 如上图黄色框框服务端在关闭连接之前发送的 SEQ = 301 报文 , 被网络延迟了 。
  • 这时有相同端口的 TCP 连接被复用后 , 被延迟的 SEQ = 301 抵达了客户端 , 那么客户端是有可能正常接收这个过期的报文 , 这就会产生数据错乱等严重的问题 。
所以 , TCP 就设计出了这么一个机制 , 经过 2MSL 这个时间 , 足以让两个方向上的数据包都被丢弃 , 使得原来连接的数据包在网络中都自然消失 , 再出现的数据包一定都是新建立连接所产生的 。
原因二:保证连接正确关闭
在 RFC 793 指出 TIME-WAIT 另一个重要的作用是:
TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.
也就是说 , TIME-WAIT 作用是等待足够的时间以确保最后的 ACK 能让被动关闭方接收 , 从而帮助其正常关闭 。
假设 TIME-WAIT 没有等待时间或时间过短 , 断开连接会造成什么问题呢?
没有确保正常断开的异常

  • 如上图红色框框客户端四次挥手的最后一个 ACK 报文如果在网络中被丢失了 , 此时如果客户端 TIME-WAIT 过短或没有 , 则就直接进入了 CLOSE 状态了 , 那么服务端则会一直处在 LASE-ACK 状态 。
  • 当客户端发起建立连接的 SYN 请求报文后 , 服务端会发送 RST 报文给客户端 , 连接建立的过程就会被终止 。
如果 TIME-WAIT 等待足够长的情况就会遇到两种情况:
  • 服务端正常收到四次挥手的最后一个 ACK 报文 , 则服务端正常关闭连接 。
  • 服务端没有收到四次挥手的最后一个 ACK 报文时 , 则会重发 FIN 关闭连接报文并等待新的 ACK 报文 。
所以客户端在 TIME-WAIT 状态等待 2MSL 时间后 , 就可以保证双方的连接都可以正常的关闭 。
TIME_WAIT 过多有什么危害?
如果服务器有处于 TIME-WAIT 状态的 TCP , 则说明是由服务器方主动发起的断开请求 。
过多的 TIME-WAIT 状态主要的危害有两种:
  • 第一是内存资源占用;
  • 第二是对端口资源的占用 , 一个 TCP 连接至少消耗一个本地端口;
第二个危害是会造成严重的后果的 , 要知道 , 端口资源也是有限的 , 一般可以开启的端口为 


推荐阅读