我知道为了同时拨打WSASend()
,我需要为每个呼叫提供唯一的WSAOVERLAPPED
和WSABUF
个实例。但这意味着我必须为每次调用跟踪这些实例,这会使事情变得复杂。
我认为如果我创建一个仅WSASend()
调用而不是同时调用而是按顺序调用的线程会更好。该线程将等待一个将保存WSASend()
个请求的队列(每个请求将包含套接字句柄和我想要发送的字符串)。当我最终调用WSASend()
时,我将阻塞该线程,直到我收到来自等待完成端口的线程的唤醒信号,告诉我WSASend()
已完成,然后我继续获取下一个请求。
如果这是一个好主意,那么我应该如何实现队列以及如何对其进行阻塞获取调用(而不是使用轮询)?
答案 0 :(得分:1)
WSABUF
可以基于堆栈,因为WSASend()
有责任在返回之前复制它。 OVERLAPPED
和数据缓冲区本身必须存在,直到提取和处理操作的IOCP完成。
我一直使用'扩展'OVERLAPPED
结构,它结合了数据缓冲区,重叠结构和WSABUF
。然后我使用引用计数系统来确保“每个操作数据”存在,直到没有人再需要它为止(这是我在API调用启动操作之前获取引用,并且在删除之后操作完成时释放引用从IOCP完成 - 请注意,这里引用不是100%必需的,但它们可以更容易地将结果数据缓冲区传递给代码的其他部分。)
TCP连接最适合在任何时候传输数据的TCP“窗口大小”,并且还有一些待处理的数据,以便窗口始终保持满,并且您始终以最大值发送连接可以采取。要通过重叠I / O实现此目的,通常最好有许多WSASend()
个呼叫待处理。但是,您不希望有太多挂起(请参阅here),最简单的方法是跟踪待处理的字节数,队列字节以便以后传输并从传输队列发送当现有发送完成时......