TCP11种状态转换图
TCP连接分组交换图
状态转换过程
服务器端创建套接字socket,绑定bind,监听listen,套接字被 被动打开。
accept阻塞直到有套接字来到。
客户端创建套接字socket,connect连接服务器。
阻塞直到连接到服务器(但是如果服务器没有打开的话,会返回一个错误)
- 三路握手
客户端主动打开状态变成SYN_SENT,向服务器发送一个SYN分节,
服务器接受SYN分节状态边为SYN_RCVD,向客户端发送一个SYN分节和ACK确认信息,
客户端接受一个SYN分节和ACK确认信息,状态变为ESTABLISHED,向服务器发送一个ACK确认信息。
服务接受ACK确认信息,状态变成ESTABLISHED。
这样服务器和客户端就可以进行数据交换。
- 四路握手
客户端端调用close,主动关闭,状态变为FIN_WAIT_1,向服务器发送一个FIN分节,
服务器接受FIN分节,状态变为CLOSE_WAIT,并向客户端发送一个ACK确认信息,
客户端接受ACK确认信息,状态变为FIN_WATI_2。
服务器端调用close,向客户端发送一个FIN分节,状态变为LAST_ACK,
客户端接受FIN分节,状态变为TIME_WAIT,并向服务器发送一个ACK确认信息,
服务器接受ACK确认信息,状态变为CLOSED,
客户端经过2倍MSL(最长分节生命周期maximum segment lifetime)后进入CLOSED状态。
CLOSING状态
如TCP状态转换图所展示的。
如果客户端发送了FIN分节给服务器,成为FIN_WAIT_1状态,
然后接受到了FIN分节,并向服务器发送一个ACK确认信息,客户端状态变为CLOSING状态。
此时客服的接受到自己发送的FIN的ACK确认信息,状态变为TIME_WAIT状态,
经过2倍MSL时间,状态变为CLOSED状态。
- 出现的情况
客户端调用close向服务器发送FIN分节,同时服务器调用close向客户端发送FIN分节。
TIME_WAIT状态
TIME_WAIT状态存在的两个理由:
- 可靠地实现TCP全双工连接的终止
- 允许老的重复分节在网络中消逝
- 第一个理由
当服务器调用close关闭套接字时,状态变为LAST_ACK,并向客户端发送FIN分节,
客户端接受FIN分节,状态变为TIME_WAIT状态,并向服务器发送ACK确认信息。
此时,ACK确认信息丢失。
服务器没有接受到ACK确认信息,它将重新发送它最终的FIN,
所以客户端必须维护状态信息,以允许客户端重新发送最终的ACK。
如果客户端不维护状态信息,它将响应一个RST分节,该分节将被服务器解释成一个错误。
- 第二个理由
需要保证每成功建立一个TCP连接时,来自该连接先前化身的老的,重复分组都已经在网络上消逝了。
也就是:如果断开了之前的连接,我们在之前的相同IP地址和端口之间建立新的连接,
新建立的连接被称为前面连接的化身,因为他们的IP地址和端口号相同。
TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,
从而被误解成一个同一个连接的化身。
TIME_WAIT的持续时间是2倍MSL,这样一个方向上最多存活MSL的分组将会被丢弃。
同时,另一个方向上的应答也最多存活MSL,也会被丢弃。