为什么TCP套接字在接收到不正确的ACK时发送RST数据包而不是重新发送数据
Why TCP socket send a RST packet instead of resending data when receives an incorrect ACK?
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数据包而不是重新发送数据时?
客户端套接字是这样定义的AS3Socket
:
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来自于信息重新传输之前客户端上的超时。
TCP本身并不"不稳定",它是一种协议。如果有什么不稳定的地方,那就是你的网络连接。TCP有一种在不稳定的网络上重试的算法。也有可能你的代码出了问题,也有可能是一个中间设备使你的连接超时。
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 发送固定大小的 UDP 数据包
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 在 c++ 中解析数据包数据的最佳方法是什么?
- 接受函数在发送数据包时等待
- 如何在 omnet++ 中发送自定义数据包?
- 数据包访问实践
- 在C++中创建一个简单的数据包路由器,如何跟踪"客户端"?
- 德拉吉诺 LG01-S 收到异常数据包并停止工作
- 将数据包从C++服务器发送到NodeJs服务器时出现MessagePack解码错误
- 使用C++将UDP数据包存储在Structure中
- FFmpeg av_read_frame从音频流返回数据包
- 为什么操作系统正在更改我的数据包的指定传出端口
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- recvfrom 只收到几个数据包,之后它进入等待状态
- 如何调试由 C++ 编写的 npm 数据包
- 客户端在关闭(SHUT_WR)后将RST发送到收到的数据包
- 为什么TCP套接字在接收到不正确的ACK时发送RST数据包而不是重新发送数据
- RST 数据包是否会发送到应用程序,而不考虑其序列号