BOOL GetQueuedCompletionStatus(
HANDLE CompletionPort, // 完成端口句柄
LPDWORD lpNumberOfBytes, // 传送数据字节数
PULONG_PTR lpCompletionKey, // 完成键
LPOVERLAPPED * lpOverlapped, // 重叠结构体
DWORD dwMilliseconds // 超时毫秒数
);
GetQueuedCompletionStatus函数中有两个参数lpCompletionKey和lpOverlapped
lpCompletionKey被称为完成键,传递的数据被称为单句柄数据,数据应该是与每个socket句柄对应
lpOverlapped被称为重叠结构体,传递的数据被称为单IO数据,数据应该与每次的操作WSARecv、WSASend等相对应
两个参数都可以用来传递任意数据,包括操作类型、缓冲buffer、套接字等等,网上下载的例子中把buffer放在哪个里面的都有,有的人喜欢全放到一个里面,难免让新接触IOCP的coder们疑惑究竟应该放在哪个里面好一些。
个人认为理论上哪个都是可以的,但最好还是根据上面所说的句柄和数据分开传递。比如一个只需要connect验证服务器是否开启的服务,是不需要buffer的。
通过对IOCP的深入理解,发现buffer不宜放在完成键中。首先猜测下为什么有人放完成键中,可能是对IOCP模型理解不够深入,也可能因为这样做每个socket句柄只需要一个buffer就可以了,不用每个IO都申请buffer。但是在实际应用中,一个socket可能有多个IO请求在队列中,这时每个IO请求都需要独立的buffer存储数据。
注:以上内容纯属个人理解,如有不对的地方请高手指正!