c++ - 为什么 TCP socket 在收到错误的 ACK 时发送 RST 数据包而不是重新发送数据?

标签 c++ actionscript-3 sockets tcp tcpdump

关于 TPC 连接的“酷”事情之一是数据不会丢失。当数据未被确认时,TCP 应该 重新发送数据。

我有一个用 C++ 编写的经典游戏服务器,客户端是用 Flash AS3 编写的。

在客户端中,我添加了一个检查工具,它每隔 X 秒尝试连接到 YouTube 和 Twitter,超时为 5 秒。问题是客户端的互联网连接在几秒钟内中断后(互联网检查器收到 1 或 2 次超时,但之后收到 OK),它开始从服务器接收数据,但服务器停止从客户端接收数据。

这是 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));

最佳答案

请注意,转储中似乎缺少一个额外的数据包,服务器字节 2383-2385,尽管客户端似乎确实看到了它们,因为它确认了它们。

服务器未回复错误的 ACK。它用它在流中看到的最后一个字节号 #119 的 ACK 进行回复。当服务器在一段时间后未能确认丢失的字节时,由客户端重新传输这些丢失的字节。相反,它会发送 RST。

没有时间信息,但我不得不猜测 RST 是由于客户端在信息被重新传输之前超时而产生的。

关于c++ - 为什么 TCP socket 在收到错误的 ACK 时发送 RST 数据包而不是重新发送数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12859717/

相关文章:

c++ - Qt 使用 QNetworkReply 获取外部 IP 地址

c++ - 问题应用鼠标冲动

c++ - 派生类继承了getter,找不到返回正确值的方法

actionscript-3 - 构建网络事件系统,我应该使用什么数据格式?

actionscript-3 - 拖动容器的子项时 mouseX/Y 混淆

ruby - 2套接字互操作产生 "socket operation on non-socket - ENOTSOCK"错误

c++ - 将 typedef 与原始指针与 shared_ptr 结合使用

actionscript-3 - 如何使用 ActionScript 和flex将变量值放入arraycollection中?

php:如何保存客户端套接字(未关闭),以便进一步的脚本可以检索它以发送答案?

java - 用 Java 编写异步(或类似异步)客户端套接字代码