c++ - 如何确保WSASend()会发送数据?

标签 c++ sockets iocp

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/

相关文章:

c++ - 一种将 std::string 复制到 vector<char> 中的更优雅的方法

c++ - 一个非常弱的引用(不能变成共享)

c# - 关闭入站套接字会导致重新读取旧数据

c++ - 是否可以更改与 Windows I/O 完成端口中的 HANDLE 关联的 ULONG_PTR 完成键?

C++ ifstream 失败,为什么这条线没有到达它应该去的地方?

c++ - 指针和构造函数的问题

java - 尝试读取 inputStream 时连接重置

c - Socket如何在C中接受多个连接

c++ - 我可以重复调用 WSASend() 吗?

multithreading - 如何确保iocp中的线程安全接收?