关于TPC连接的一个“酷”事情是数据不会丢失。当数据未被确认时,TCP 据称重新发送数据。
我有一个用c ++编写的经典游戏服务器,客户端是用Flash AS3编写的。
在客户端,我添加了一个检查工具,每隔X秒尝试连接到YouTube和Twitter,超时为5秒。问题是,在客户端的Internet连接在几秒钟内断开(Internet检查器收到1或2个超时,但在收到OK后),它开始从服务器接收数据,但服务器停止从客户端接收数据。 / p>
这是TCPDUMP收到的流程:
1. server > client: Flags [P.], seq 2374:2378, ack 119, win 14600, length 4
2. client > server: Flags [.], ack 2374, win 15524, length 0
3. client > server: Flags [.], ack 2378, win 15520, length 0
. [Here the client sends data to the server, but the server never receives it...]
4. server > client: Flags [P.], seq 2378:2383, ack 119, win 14600, length 5
5. server > client: Flags [P.], seq 2386:2389, ack 119, win 14600, length 3
6. client > server: Flags [.], ack 2386, win 15512, length 0
7. client > server: Flags [.], ack 2389, win 15509, length 0
8. client > server: Flags [R.], seq 127, ack 2389, win 0, length 0
正如您所读到的,当服务器发送带有错误ACK的数据时,客户端不会重新发送数据,而是发送RST数据包(强制服务器关闭连接)。在客户端日志中,我可以看到接收并处理服务器发送的数据(因此,当服务器发送错误的ACK时,连接不会关闭)。
当TCP在收到错误的ACK后决定发送RST数据包而不是重发数据时?
客户端套接字是以这种方式定义的AS3 Socket
:
var socket:Socket = new Socket();
服务器套接字使用fcntl()
设置为非阻塞。也有这个选项:
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&dummyint, sizeof(int));
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&dummyint, sizeof(int));
答案 0 :(得分:4)
请注意,转储中似乎缺少一个额外的数据包,服务器字节为2383-2385,但似乎客户端确实看到了它们,因为它确认了它们。
服务器未回复错误的ACK。它回复了它在流#119中看到的最后一个字节数的ACK。当服务器在一段时间后无法确认它们时,由客户端重新传输那些丢失的字节。相反,它正在发送RST。
没有时间信息,但我不得不猜测RST是在客户端超时之前发出的,因此需要重新发送信息。
答案 1 :(得分:2)
TCP本身并不“不稳定”,它是一种协议。如果有什么不稳定,那就是你的网络连接。 TCP具有在不稳定网络上重试的算法。您的代码也可能出现问题,并且可能会有中间设备超时连接。