TCP连接中的TIME_WAIT状态

根据《UNIX网络编程》卷1,TCP的状态转换图可以得知:执行主动关闭的那端(假设客户端)经历了TIME_WAIT状态,该状态停留在那个状态的持续时间是最长分节期(maximum segment  lifetime,MSL)的两倍,称为2MSL。

TIME_WAIT状态的持续时间在1min~4min之间。MSL是任何IP数据包能够在因特网上存活的最长时间。每个数据包在最大跳数(255)之内在网络上的时间不会超过MSL秒。网络在路由失效后重新找到一条连通的路。在此期间如果发生路由环路,TCP超时未收到确认包会重新发送该数据分组,该数据分组正确到达,不久路由修复,环路中的数据包也到达目的地,这个分组叫做漫游的重复分组。

TIME_WAIT状态存在的两个理由是:

1. 可靠的实现TCP全双工连接的终止;

2. 允许老的数据分组在网络中消逝

关于第一个理由:假设最终的ACK丢失了,服务端将重新发送FIN,因此客户必须维护状态信息,以允许它重新发送那个ACK。要是客户端不维护状态信息,响应一个RST给服务器,服务器认为是错误。如果TCP打算执行所有必要的工作以彻底终止某个连接上两个方向的数据流,必须处理连接终止序列4个分节中任何一个分节丢失的情况。

关于第二个理由:假设新建的连接与前一个连接IP地址和端口一样,TCP必须防止来自某个老的连接的数据分组在该连接终止后出现,从而被误解为新连接的新数据分组,为了做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的连接。一个方向上数据包最多MSL存活期,另一个方向应答最多存活MSL,通过实施这个规则,就能保证每个成功连接的TCP,来自先前连接的老的数据分组都已经在网络中消逝了。

现实来讲,刚终止的./server 重启启动时,需要等一会儿,可采用启用“端口重用”将setsockopt的第四个参数设为1.

    int on = 1;
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));


你可能感兴趣的:(Linux)