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

时间:2015-03-05 11:28:33

标签: c++ multithreading sockets iocp

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

TCP连接最适合在任何时候传输数据的TCP“窗口大小”,并且还有一些待处理的数据,以便窗口始终保持满,并且您始终以最大值发送连接可以采取。要通过重叠I / O实现此目的,通常最好有许多WSASend()个呼叫待处理。但是,您不希望有太多挂起(请参阅here),最简单的方法是跟踪待处理的字节数,队列字节以便以后传输并从传输队列发送当现有发送完成时......