我可以反复调用 WSASend() 吗?
Posted
技术标签:
【中文标题】我可以反复调用 WSASend() 吗?【英文标题】:Can I call WSASend() repeatedly? 【发布时间】:2015-02-23 12:31:32 【问题描述】:在使用 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();
【问题讨论】:
【参考方案1】:是的,您可以发出多个 I/O 请求而无需等待完成通知。或者,您可以一次调用 WSASend() 多个缓冲区。
无论哪种方式,或两者兼而有之,都可以正常工作。每个调用的 OVERLAPPED 块本质上是指向 I/O 请求的链表的指针,因此当 I/O 资源可用时,它们都可以被内核和通信堆栈排队并执行。
这也适用于 WSARecv 等重叠 I/O。这允许内核/堆栈在用户线程代码处理之前通知的缓冲区时加载缓冲区。
注意:OVERLAPPED 块和缓冲区在每次调用时都必须是唯一的,并且它们的生命周期必须延长到完成通知。在用户线程处理完成通知之前,您不能让它们被 RAII 或删除。缓冲区和 OVERLAPPED 通常是一个“IOrequest”类的成员(使用“SocketContext*”类指针成员将每个 IOrequest 与其绑定的套接字连接起来)。
【讨论】:
【参考方案2】:是的,您可以在单个套接字上发出多个重叠操作,而无需等待任何完成。
在 TCP 套接字上进行多个未完成的 WSASend()
调用时需要注意的一件事是,您正在有效地将 WSASend()
调用中使用的缓冲区的资源管理移交给另一端的对等方。插座。这样做的原因是,如果您发送数据而对等方读取数据的速度不如您发送的那么快,那么您最终将导致 TCP 的流量控制启动。这不会阻止您发出更多的 WSASend()
调用和所有你会注意到完成需要越来越长的时间。有关详细信息,请参阅here。
【讨论】:
以上是关于我可以反复调用 WSASend() 吗?的主要内容,如果未能解决你的问题,请参考以下文章
具有多个缓冲区的 WSASend() - 可以完成不完整吗?
我应该为 WSASend 和 WSARecv 使用不同的 WSAOVERLAPPED 结构吗?