Network programming WSASend()具有多个缓冲区-是否可以完成或不完整?

Network programming WSASend()具有多个缓冲区-是否可以完成或不完整?,network-programming,winsock,iocp,Network Programming,Winsock,Iocp,假设我发布了以下WSASend调用(没有回调函数的Windows I/O完成端口): 当我从完成端口收到“write_done”通知时,是否有可能WSABUF[1]将被完全发送(25字节),而WSABUF[0]将只被部分发送(比如7字节)?因为WSASend是执行重叠套接字IO的首选方法,如果在不完整的情况下完成,则没有任何意义-完成通知/例程/事件是应用程序清理/回收使用过的结构的唯一方法 另外:不,这是不可能的,一个WSASend调用仍然是一个IO调用,不管使用的缓冲区是什么。正如我之前在回

假设我发布了以下WSASend调用(没有回调函数的Windows I/O完成端口):


当我从完成端口收到“write_done”通知时,是否有可能WSABUF[1]将被完全发送(25字节),而WSABUF[0]将只被部分发送(比如7字节)?

因为
WSASend
是执行重叠套接字IO的首选方法,如果在不完整的情况下完成,则没有任何意义-完成通知/例程/事件是应用程序清理/回收使用过的结构的唯一方法


另外:不,这是不可能的,一个
WSASend
调用仍然是一个IO调用,不管使用的缓冲区是什么。

正如我之前在回答您的另一个非常类似的问题时所说,唯一可能失败的时间是在资源不足的情况下(最有可能是未分页池或锁定页面限制问题)您可能会得到ENOBUFS的部分完成和错误返回。同样,正如我之前所说的,在10年的IOCP开发工作中,我从未将这视为生产中的问题,只有在我们一直在对系统进行压力测试直至死亡的情况下(实际上有时无页面池耗尽有时会导致行为不检的驱动程序蓝屏显示)


我建议您简单地添加一些代码来记录失败,关闭套接字,就这样,您已经处理了失败的可能性,可以继续了。如果你的失败处理代码被执行过,我会很惊讶。但是你可以确信你会知道它是否存在,一旦你能够重现这个问题,你就可以花更多的时间思考你是否真的需要更好地处理它。

你确定Len?请仔细注意这个特定的问题-它是一个WSASend()调用,而不是几个调用,因此我希望它将WSABUF数组视为一个单独的、连续的缓冲区。。。这就是我的问题所在。如果你将套接字的发送缓冲区大小设置为零,那么你的缓冲区将被锁定在内存中,因此如果超过锁定的页面限制,那么可能会导致ENOBUFS返回,同样,在这种情况下,我们两人都不知道确切的非页面池使用情况。事实上,您使用的是分散/聚集I/O并没有那么重要。此外,由于WSASend()的文档没有说明这种情况不会导致您所询问的错误,因此您必须假设它可能发生,因此,IMHO,我的答案是正确的。
void send_data()
{
    WSABUF wsaBuff[2];
    wsaBuff[0].len = 20;
    wsaBuff[1].len = 25;
    WSASend(sock, &wsaBuff[0], 2, ......);
}