我可以反复调用WSASend()吗?

时间:2015-02-23 12:31:32

标签: c++ sockets winapi network-programming iocp

当使用IOCP时,如果我拨打WSASend(),我是否必须等到通知到达才能再次呼叫,或者我可以在收到任何通知之前多次呼叫通知,例如类似于这允许:

WSASend();

// Call it again without waiting for notification of previous call
WSASend();

// Call it again without waiting for notification of previous call
WSASend();

2 个答案:

答案 0 :(得分:2)

是的,您可以在不等待完成通知的情况下发出多个I / O请求。或者,您可以通过一次调用WSASend()多个缓冲区。

无论哪种方式,或两者兼而有之,都能正常工作。每个调用的OVERLAPPED块本质上是指向I / O请求的链接列表的指针,因此当I / O资源可用时,它们都可以由内核和通信栈堆叠并执行。

这也适用于WSARecv等重叠I / O.这允许内核/堆栈加载缓冲区,而用户线程代码正在处理之前通知的那些缓冲区。

注意:OVERLAPPED块和缓冲区每次调用必须是唯一的,并且它们的生命周期必须延伸到完成通知。在用户线程处理完成通知之前,您不得让它们成为RAII或删除。缓冲区和OVERLAPPED通常是一个“IOrequest”的成员。 class,(使用' SocketContext *'类指针成员将每个IOrequest与其绑定套接字连接起来)。

答案 1 :(得分:2)

是的,您可以在单个套接字上发出多个重叠操作,而无需等待任何完成。

在TCP套接字上使用多个未完成的WSASend()调用需要注意的一件事是,您正在有效地将WSASend()调用中使用的缓冲区的资源管理移交给对等端套接字的另一端。这样做的原因是,如果您发送数据并且对等方没有像您发送的那样快速读取数据,那么最终将导致TCP的流量控制启动。这并不会阻止您发出更多WSASend()个电话,您将注意到的是,完成时间越来越长。有关详细信息,请参阅here