Winsock WSAAsyncSelect在没有无限缓冲区的情况下发送

时间:2010-06-10 23:35:14

标签: c++ winsock send wsaasyncselect

这更像是一个设计问题,而不是一个特定的代码问题,我确信我错过了明显的问题,我只需要另一组眼睛。

我正在编写一个基于WSAAsyncSelect的多客户端服务器,每个连接都是我编写的连接类的对象,它包含相关的设置和缓冲区等。

我的问题涉及FD_WRITE,我理解它是如何运作的:在建立连接后立即发送一个FD_WRITE。此后,您应该发送,直到收到WSAEWOULDBLOCK,此时您将存储剩余的内容发送到缓冲区,并等待被告知可以再次发送。

这是我遇到问题的地方,我在每个连接对象中有多大的保持缓冲区?收到新的FD_WRITE之前的时间是未知的,我可能会尝试在此期间发送大量内容,一直添加到我的传出缓冲区。如果我使缓冲区动态化,如果由于某种原因,内存使用可能会失控,我无法发送()并减少缓冲区。

所以我的问题是你如何处理这种情况?注意我不是在讨论winsock使用的网络缓冲区本身,但是我自己创建的一个用于“排队”发送。

希望我解释得那么好,谢谢大家!

1 个答案:

答案 0 :(得分:0)

当然,正确的设计取决于您的应用程序的性质。

某些程序可以预测在必须使用它之前可以生成的数据量,因此它们可以使用固定大小的缓冲区。例如,我设计的一个协议有一个命令响应结构和一个2字节长度的前缀,所以我可以使用64K缓冲区并知道我永远不会溢出它们。如果缓冲区已满,程序必须等待回复才能允许从该缓冲区发送数据,因此不会再向该缓冲区添加数据。

固定大小缓冲区的另一个好用途是数据来自另一个I / O源。考虑一个Web服务器:从最基本的角度来看,它会从磁盘中篡改文件并将其吐出网络。因此,您知道您一次从磁盘读取的数量,因此您知道缓冲区必须有多大。

我很难找到使用动态缓冲区的充分理由。

您不需要它们的主要原因是TCP's sliding window。如果其中一个连接对等体停止接收数据,则远程对等体的堆栈将在TCP窗口填满时停止发送数据。未读数据将保留在接收堆栈的缓冲区中,直到它被发送的程序请求它。这为接收器提供了一种方法来将输入数据限制到它可以处理的水平。据我所知,这使得固定大小的缓冲区在所有条件下都是实用的。