gpt4 book ai didi

c++ - 当此时没有 wsarecv 时,传入数据会发生什么

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:45:16 25 4
gpt4 key购买 nike

我在 Windows 中处理多线程 IOCP 服务器。为了避免处理许多挂起的读取,我总是在每个连接的套接字上只有一个 wsarecv 操作。简而言之,我的设计如下:

  1. 客户端连接后,wsarecv 被发送到连接的套接字上
  2. wsarecv 被执行时,数据被处理并且 wsasend 被发送到同一个套接字上
  3. 当第 2 步的 wsasend 完成时(GQCS 收到通知),再次发布 wsarecv

这意味着在第 2 步和第 3 步之间有少量时间,此时没有等待客户端数据的待处理 wsarecv,随时可能出现。

这种情况,我应该担心,或者我可以假设,如果数据会在这个特定的短时间内到达,它将被存储在某种内部缓冲区中,并在此刻从中取出 wsarecv 来自第 3 步的发布 ?

感谢帮助。

最佳答案

只要你没有禁用网络堆栈的缓冲(使用 SO_RCVBUF 并将缓冲区大小设置为 0),那么你将在网络堆栈中有一些缓冲区空间,如果你没有待处理的 WSARecv()

如果您使用的是 TCP,那么您甚至不必担心何时填充此缓冲区空间,因为这将导致零窗口,并且发送方将有希望地停止发送(请参阅 here 了解为什么它实际上可能不会停止发送),但即使没有,您的堆栈也会简单地丢弃后续数据报,TCP 最终会重新发送它们。

UDP 有点不同。如果您填满接收缓冲区,那么您将开始丢弃数据报。默认情况下,堆栈将丢弃最新的数据报,您可以通过设置 SIO_ENABLE_CIRCULAR_QUEUEING 来更改此设置,这将导致最旧的数据报被丢弃。

您可以选择始终有至少一个 WSARecv() 挂起在连接上,方法是 a) 发布多个开始,以及 b) 发布一个新的作为当您做的第一件事一个完成。这对 UDP 很有效,但是对于 TCP,这种方法的问题是你必须考虑多个 recvs 可以“同时”完成的事实,然后你必须确保你的 I/O 线程一起工作以保持同步的 TCP 数据流(有关问题,请参阅 here)。

禁用堆栈的接收缓冲区并始终有足够的 WSARecv() 在连接上挂起可能会更高效,因为这将从入站数据路径中删除内存拷贝。

关于c++ - 当此时没有 wsarecv 时,传入数据会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22720924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com