WSASend()
无论数据是否发送都会立即返回。但如何确保数据将被发送,例如,我的 UI 中有一个按钮,按下时将发送 “Hello World!”
。现在我想确保当用户单击此按钮时 "Hello World!"
将在某个时刻发送,但 WSASend()
可能会返回 WSAEWOULDBLOCK
指示数据不会被发送,所以我应该将 WSASend()
包含在一个循环中,直到 WSASend()
返回 0 才会退出
(成功)。
注意:我正在使用 IOCP。
最佳答案
should I enclose WSASend() in a loop that does not exit until WSASend() returns 0 (success)
呃..不!
让 UI 发出重叠的 WSASend 请求,并包含缓冲区和重叠。如果奇迹般地,它确实立即返回成功(我从未见过),那么你就很好了。
如果(当:)它返回 WSA_IO_PENDING 时,您将无法在 UI 按钮处理程序中执行任何操作,因为 GUI 事件处理程序无法等待。图形用户界面是状态机 - 您必须退出按钮处理程序并以提示方式返回到消息输入队列。如果你愿意的话,你可以做一些 GUI 的事情。也许禁用“发送”按钮,或者向备忘录组件添加一些“消息已发送”文本。就是这样 - 然后您必须退出。
一段时间后,成功完成通知(或失败通知)将被发布到 IOCP 完成队列,并且处理程序线程将获取它。使用 PostMessage、QueueUserAPC 或类似的线程间通信机制向 UI 线程发出“某物”信号(例如原始 WSASend 中使用的缓冲区对象),以便它可以对返回的结果采取操作,例如。重新启用“发送”按钮。
是的,这可能会被视为困惑,但这是唯一有效的方法。
其他方法 - 轮询循环、Application.DoEvents、计时器等都是可怕的困境。
关于c++ - 如何确保WSASend()会发送数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28752103/