Ode*_* R. 10 sockets windows winapi operating-system
我有一个令人困惑的问题.
我在Windows XP/7上使用大型C++库来处理UDP上的某些专有协议.它在整个程序运行期间侦听一个端口,并等待来自远程对等端的连接.
大多数情况下,这很有效.然而,由于一些问题,我已经经历了,我已经决定调用后直接添加一个简单的调试打印WSARecvFrom(从我的兴趣插座在图书馆使用的recv数据报Win32函数,并且告诉哪些IP和端口他们来自).
奇怪的是,在某些情况下,我发现数据包在操作系统级别被删除(即我在Wireshark中看到它们,它们有正确的dst-port,所有校验和都是正确的 - 但它们从未出现在我的调试打印中植入代码).
现在,我充分的事实(人们往往提到有点过于频繁)说,"UDP不保证发送" -但这是不相关的,因为包是由机器接受-我看到他们在Wireshark的.
此外,我熟悉操作系统缓冲区和填充的可能性,但这里有一些奇怪的部分......
我做了一些研究,试图找出哪些数据包被准确删除.我发现的是,所有丢弃的数据包共享两个共同点(尽管有些,但绝对不是大多数,未丢弃的数据包也共享这些):
这两种品质中的任何一种都可以影响OS缓冲区,并导致数据包随机丢弃(或者更有趣 - 有选择地)掉线?
任何关于这个奇怪问题的灯都会非常感激.
非常感谢.
编辑(24/10/12):
我想我可能错过了一个重要的细节.似乎在到达之前丢弃的数据包共享其他共同点:它们(我开始相信,只有它们)被"新"对等体(即之前未尝试联系的对等体)发送到服务器.
例如,如果一个syn-equivalent数据包从我们以前从未见过的对等体*到达,它将不会被看到WSARecvFrom.然而,如果我们已经发出一个SYN-相当于包发送给同行自己(即使它没有当时回复),现在它把我们一个SYN-等同,我们会看到它.
(*)我不确定这是否是我们没有见过的同伴(即ip:port),或者只是我们以前从未见过的端口.
这有帮助吗?
这是我从未听说过的某种WinSock选项吗?(正如我上面所说,代码不是我的,所以它可能是使用我不知道的套接字选项)
再次感谢!
操作系统有一个固定大小的缓冲区,用于存储已到达套接字但尚未被您读取的数据。当该缓冲区耗尽时,它将开始丢弃数据。调试日志记录可能会延迟从套接字提取数据的速率,从而增加溢出的可能性,从而加剧这种情况。
如果这是问题所在,您至少可以通过请求更大的接收缓冲区来减少它的实例。
您可以使用以下命令检查套接字的接收缓冲区的大小
int recvBufSize;
int err = getsockopt(socket, SOL_SOCKET, SO_RCVBUF,
(char*)&recvBufSize, sizeof(recvBufSize));
Run Code Online (Sandbox Code Playgroud)
您可以使用将其设置为更大的尺寸
int recvBufSize = /* usage specific size */;
int err = setsockopt(socket, SOL_SOCKET, SO_RCVBUF,
(const char*)&recvBufSize, sizeof(recvBufSize));
Run Code Online (Sandbox Code Playgroud)
如果您仍然看到操作系统正在接收数据但未将其传递到套接字客户端,则您可以考虑不同的日志记录方法。例如
| 归档时间: |
|
| 查看次数: |
10511 次 |
| 最近记录: |