我知道TIME_WAIT
是为了防止一个连接的延迟段被误解为后续连接的一部分。在连接处于TIME_WAIT等待状态时到达的任何段都将被丢弃。
在我的实验中,当客户端发送RST数据包而不是FIN数据包时,我看不到TIME_WAIT
。为什么呢?
服务器
while (1) {
int len = sizeof(struct sockaddr);
fd = accept(sfd, &remote, &len);
read(fd, buf, sizeof(buf));
strcpy(buf, "Hello Client");
write(fd, buf, strlen(buf));
close(fd);
}
客户端
res = connect(sfd, result->ai_addr, result->ai_addrlen);
strcpy(buf, "Hello Server!");
write(sfd, buf, strlen(buf));
close(sfd);
注意:客户端发送RST而不是FIN,因为它在关闭套接字之前没有读取服务器已经发送的缓冲数据。
答案 0 :(得分:2)
当您close(2)
与挂起接收数据的连接时,连接断开,因为您没有读取所有待处理数据(可以在缓冲区中,已确认,未确认或仅在传输中)您是打破状态机,这就是激发RST
(从主机发送到另一端,响应任何到达连接这一端的数据段)的原因。如果按照建议读取RFC文档,则连接处于错误状态,并且会向其收到的每个数据包回复RST
帧...它不再处于TIME_WAIT
状态。
在读取 RFC-793具体说: Sec 3.4建立连接 [...] 所以,你可以在任何情况下阅读...... close(2)
之前调用EOF
(当您从另一端收到FIN
时,取消阻止读取0字节)条件是协议错误< / strong>,因为接收方(您)正在丢失传输到您身边的剩余数据。你有一个系统调用shutdown(2)
,目的是表明你没有写更多数据的意图(一半关闭你的发送方),并允许等待剩余的数据来,它强迫你的一方发送一个{ {1}}到另一端并将连接置于FIN
状态(等待FIN_WAIT1
的{{1}}和/或来自另一方的ACK
< / p>
注
FIN
状态是一种状态,用于确保任何FIN&ACK
数据包有足够的时间到达目的地并正确处理。由于连接失败,两端未同步,因此等待任何数据包到达没有任何意义,因为无法正确处理。没有数据包响应TIME_WAIT
而发送,连接通常会进入in-transit
状态。RST
CLOSED
没有Reset Processing
In all states except SYN-SENT, all reset (RST) segments are validated
by checking their SEQ-fields. A reset is valid if its sequence number
is in the window. In the SYN-SENT state (a RST received in response
to an initial SYN), the RST is acceptable if the ACK field
acknowledges the SYN.
The receiver of a RST first validates it, then changes state. If the
receiver was in the LISTEN state, it ignores it. If the receiver was
in SYN-RECEIVED state and had previously been in the LISTEN state,
then the receiver returns to the LISTEN state, otherwise the receiver
aborts the connection and goes to the CLOSED state. If the receiver
was in any other state, it aborts the connection and advises the user
and goes to the CLOSED state.
州。
答案 1 :(得分:0)
因为它声明没有这种联系,其效果是在没有偏见的情况下终止它。
换句话说,因为RFC 793明确表示在RST
接收时不会发送任何响应,您必须进入CLOSED
状态(除了在某些情况下与连接建立有关)在哪种情况下你再次进入LISTEN
状态。