3

我有一个 C++ 应用程序,它接收股票数据并通过套接字(充当服务器)转发到另一个应用程序。

实际上,该WSASend函数在几秒钟后返回错误代码 10055,我发现这是错误消息

“没有可用的缓冲区空间。无法对套接字执行操作,因为系统缺少足够的缓冲区空间或队列已满”。

仅当我在市场交易时间后运行应用程序时才会出现问题,因为我们在几分钟内收到全天数据(大约 130 MB)(我假设这相对较大)我这样做是为了进行稳健性测试。

我尝试使用setsockopt函数增加发送缓冲区 SO_SNDBUF 但同样的问题仍然存在。我怎么解决这个问题?这与接收缓冲区有关吗?

发送详情:

对于每条完整的消息,我调用使用重叠套接字的发送方法

编辑:有人可以给出在 C++ 中处理高频数据的一般准则吗?

4

2 回答 2

6

如果接收方没有足够快地处理它们的套接字末端,TCP 的流控制将导致内部发送缓冲区填满。从错误消息中可以看出,您正在发送数据,而不考虑 Winsock 堆栈处理数据的速度。如果您能准确说明您是如何发送数据的,那将会很有帮助?您是在等待所有数据到达然后发送一个大块,还是逐个发送?

您是通过非阻塞或重叠套接字发送吗?在任何一种情况下,每次发送后,您可能应该等待套接字处于可以发送更多数据的状态的通知,因为 select()/WaitForMultipleObjects() 表明它可以(对于非阻塞套接字),或者重叠 I/O 完成,表示数据已成功复制到套接字内部发送缓冲区。

您可以重叠发送,即一次排队多个缓冲区 - 这就是重叠 I/O 的用途 - 但您需要仔细考虑锁定大量页面和可能耗尽非分页池的内存影响.

于 2009-02-28T09:44:21.193 回答
0

尼克的回答非常中肯。您很可能通过一次启动太多重叠发送来耗尽“锁定页面限制”。理想情况下,您需要将数据缓冲在自己的内存缓冲区中,并且在任何时候只有一组重叠发送待处理。我在这里谈谈我的 IOCP 框架如何让你处理这种情况http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.html以及相关的 TCP 接收窗口流控制问题在这里http://www.lenholgate.com/blog/2008/06/data-distribution-servers.html和这里http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and -asynchronous-writes.html

我的首选解决方案是在任何时候允许可配置数量的待处理重叠发送,一旦超过此限制就开始缓冲数据,然后使用待处理重叠发送的完成来驱动缓冲数据的发送。这使您可以严格控制非分页池的数量和使用的“锁定页面”的数量,并且可以尽可能快地发送大量连接,但仍然可以控制它们使用的资源。

于 2009-03-09T21:18:57.080 回答