根据FC793协议规范和BSD 4.4的实现,本文总结了TCP分组丢失时的状态变迁,如下图所示:实线箭头表示客户端的状态变迁,虚线箭头表示服务端的状态变迁,红色文字表示分组丢失时的行为,黑色文字表示正常时的行为。
这里假设重传时分组依然会丢失,当在不同状态(CLOSED除外)分组丢失后,最终会关闭套接字而回到CLOSED状态。下面逐个分析各状态时
的情景。
SYN_SENT 连接阶段第1次握手,客户端发送SYN分组但丢失,因此超时收不到服务端的SYN+ACK而重传SYN,尝试几次后放弃,关闭套接字。
SYN_RCVD 1)连接阶段第2次握手,服务端响应SYN+ACK分组但丢失,因此超时收不到客户端的ACK而重传SYN+ACK,尝试几次后放弃,发送RST并关闭套接字。
2)连接阶段第3次握手,客户端发送ACK分组但丢失,因此服务端超时收不到ACK而重传SYN+ACK,尝试几次后放弃,发送RST并关闭套接字。
ESTABLISHED 1)连接阶段第3次握手,客户端发送ACK分组后,虽然丢失但会进入该状态(因为ACK不需要确认),但此时服务端还处于SYN_RCVD状态,因为超时收不到客户端的ACK而重传SYN+ACK、尝试几次后放弃、发送RST并关闭套接字,而此时客户端收到RST。
2)数据传输阶段,当超时没有收到数据的确认时,会重传数据,尝试几次后放弃,发送RST并关闭套接字。
FIN_WAIT_1 1)关闭阶段第1次握手,客户端发送的FIN分组丢失,因此超时收不到服务端的ACK而重传FIN,尝试几次后放弃,发送RST并关闭套接字。
2)关闭阶段第2次握手,客户端发送的FIN分组到达服务端,但服务端响应的ACK分组丢失,因此客户端超时收不到ACK而重传FIN,尝试几次后放弃,发送RST并关闭套接字。
FIN_WAIT_2 关闭阶段第3次握手,服务端发送的FIN分组丢失,因此超时收不到客户端的ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时客户端收到RST。
CLOSING 本端发送的ACK分组丢失,导致对端超时收不到ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时本端收到RST。
TIME_WAIT 关闭阶段第4次握手,客户端发送的ACK分组丢失,导致服务端超时收不到ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时客户端收到RST。
CLOSE_WAIT 服务端发送的ACK分组丢失,导致客户端超时收不到ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时服务端收到RST。
LAST_ACK 服务端发送的FIN分组丢失,导致超时收不到客户端的ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字。