TCP分组丢失时的状态变迁
本文根据RFC793协议规范和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并关闭套接字。
3)同时打开第2次握手,本端响应的SYN+ACK分组丢失,因此对端超时收不到SYN+ACK而重传SYN、尝试几次后放弃、发送RST并关闭套接字,而此时本端收到RST。
ESTABLISHED
1)连接阶段第3次握手,客户端发送ACK分组后,虽然丢失但会进入该状态(因为ACK不需要确认),但此时服务端还处于SYN_RCVD状态,因为超时收不到客户端的ACK而重传SYN+ACK、尝试几次后放弃、发送RST并关闭套接字,而此时客户端收到RST。
2)数据传输阶段,本端发送的Data分组丢失,因此超时收不到对数据的确认而重传、尝试几次后放弃、发送RST并关闭套接字,而此时对端收到RST。
FIN_WAIT_1
1)关闭阶段第1次握手,客户端发送的FIN分组丢失,因此超时收不到服务端的ACK而重传FIN,尝试几次后放弃,发送RST并关闭套接字。
2)关闭阶段第2次握手,服务端响应的ACK分组丢失,因此客户端超时收不到ACK而重传FIN,尝试几次后放弃,发送RST并关闭套接字。
FIN_WAIT_2
关闭阶段第3次握手,服务端发送的FIN分组丢失,因此超时收不到客户端的ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时客户端收到RST。
CLOSING
同时关闭第2次握手,本端发送的ACK分组丢失,导致对端超时收不到ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时本端收到RST。
TIME_WAIT
关闭阶段第4次握手,客户端响应的ACK分组丢失,导致服务端超时收不到ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时客户端收到RST。
CLOSE_WAIT
关闭阶段第2次握手,服务端响应的ACK分组丢失,导致客户端超时收不到ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字,而此时服务端收到RST。
LAST_ACK
关闭阶段第3次握手,服务端发送的FIN分组丢失,导致超时收不到客户端的ACK而重传FIN、尝试几次后放弃、发送RST并关闭套接字。