代码之家  ›  专栏  ›  技术社区  ›  Poni

具有多个缓冲区的wsasend()-是否可能完成不完整?

  •  1
  • Poni  · 技术社区  · 14 年前

    假设我发布以下wsasend调用(不带回调函数的Windows I/O完成端口):

    void send_data()
    {
        WSABUF wsaBuff[2];
        wsaBuff[0].len = 20;
        wsaBuff[1].len = 25;
        WSASend(sock, &wsaBuff[0], 2, ......);
    }
    

    当我从完成端口收到“写入完成”通知时,是否可能将wsabuff[1]完全发送(25字节),而wsabuff[0]仅部分发送(即7字节)?

    2 回复  |  直到 14 年前
        1
  •  0
  •   Viktor Svub    14 年前

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

    还有:不,不可能,一个 WSASEND 不管使用的缓冲区是什么,调用仍然是一个IO调用。

        2
  •  2
  •   Len Holgate    14 年前

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

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