我应该同时调用 WSASend() 吗?

Should I make simultaneous WSASend() calls?

我知道为了同时调用 WSASend(),我需要为每个调用提供唯一的 WSAOVERLAPPEDWSABUF 实例。但这意味着我必须为每次调用跟踪这些实例,这会使事情变得复杂。

我认为如果我创建一个只进行 WSASend() 调用的线程会更好 不是同时而是顺序 。该线程将等待一个队列,该队列将容纳 WSASend() 个请求(每个请求将包含套接字句柄和我要发送的字符串)。当我最终调用 WSASend() 时,我将阻塞线程,直到我从等待完成端口的线程接收到唤醒信号,告诉我 WSASend() 已经完成,然后我继续获取下一个请求。

如果这是个好主意,那么我应该如何实现队列以及如何对其进行阻塞提取调用(而不是使用轮询)?

WSABUF 可以基于堆栈,因为 WSASend() 有责任在返回之前复制它。 OVERLAPPED 和数据缓冲区本身必须存在,直到提取并处理操作的 IOCP 完成。

我一直使用 'extended' OVERLAPPED 结构,它包含数据缓冲区、重叠结构和 WSABUF。然后我使用一个引用计数系统来确保 'per operation data' 存在,直到没有人需要它为止(也就是说,我在 API 调用启动操作之前获取一个引用,并在操作完成时释放一个引用在从 IOCP 中删除完成后完成 - 请注意,这里的引用不是 100% 必需的,但它们可以更容易地将生成的数据缓冲区传递给代码的其他部分。

对于 TCP 连接来说,最理想的情况是在任何时候都有 TCP "window size" 数据在传输中,并有更多的数据待处理,以便 window 始终保持完整并且您始终以连接可以接受的最大值发送。要通过重叠的 I/O 实现此目的,通常最好让许多 WSASend() 调用挂起。但是,您不希望有太多待处理(请参阅 here),实现此目的的最简单方法是跟踪待处理的字节数,将字节排队以供稍后传输并从传输队列中发送当现有发送完成时...