从异步套接字中最佳地读取数据

时间:2009-12-30 10:04:54

标签: windows sockets

我的套接字库有问题,它使用WSAASyncSelect将套接字置于异步模式。在异步模式下,套接字处于非阻塞模式(在任何阻止的操作上返回WSAWOULDBLOCK),并且窗口消息被发布到通知窗口,以在套接字准备好被读取,写入等时通知应用程序。

我的问题是这样 - 当收到FD_READ事件时,我不知道要尝试和recv多少字节。如果我传递的缓冲区太小,那么winsock会自动发布另一个FD_READ事件,告诉我要读取更多数据。如果数据到达速度非常快,则可以使用FD_READ消息使消息队列饱和,并且仅当消息队列为空时才发布WM_TIMER和WM_PAINT消息,这意味着如果应用程序接收大量数据并使用异步,则应该可以停止绘制缓冲区太小的套接字。

然后制作缓冲区有多大?我尝试使用ioctlsocket(FIONREAD)来获取要读取的字节数,并使缓冲区完全变大,但是KB192599明确地警告说这种方法充满效率低下。

如何选择足够大的缓冲区大小,但不是很疯狂?

2 个答案:

答案 0 :(得分:1)

据我所知,使用setsockopt SO_RVCBUF选项设置的值是FIONREAD值的上限。因此,调用ioctlsocket来查找getsockopt设置,并将其用作每个SO_RCVBUF的(尝试的)值,而不是调用recv

根据你对Aviad P.回答的评论,听起来这可以解决你的问题。

(免责声明:我自己一直使用FIONREAD。但在阅读了链接知识库文章后,我可能会改变......)

答案 1 :(得分:0)

您可以将缓冲区设置为尽可能大而不影响性能,如果发送方发送了较小的消息,则在填充缓冲区之前依赖TCP PUSH标志使读取返回。

TCP PUSH标志设置在逻辑消息边界(通常在发送操作之后,除非明确设置为false)。当接收端在TCP数据包上看到PUSH标志时,它会返回任何阻塞读取(或异步读取,无关紧要)与接收缓冲区中累积到PUSH点的任何内容。

因此,如果您的发件人正在发送合理大小的邮件,那么您可以,如果不是,那么您可以限制缓冲区大小,即使您全部阅读,也不会对性能产生负面影响(主观)。< / p>