或者象下边这样
WSARecv(socket,…,&( PerIoData.Overlapped));
在工作线程的后面部分。等GetQueuedCompletionStatus函数返回了—个重叠结构(和完成键)后。便可通过撤消对OperationType成员的引用。调查到底是哪个操作投递到了这个句柄之上(只需将返回的重叠结构造型为自的PER_IO_OPERATlON_DATA结构)。对单I/O操作数据来说,它最大的—个优点便是允许我们在同一个句柄上。同时管理多个I/O操作(读/写、多个读、多个写,等等)。大家此时或许会产生这样的疑问:在同—个套接字上,真的有必要同时投递多个I/O操作吗?答案在于系统的“伸缩性”,或者说“扩展能力”。例如,假定我们的机器安装了多个中央处理器。每个处理器都在远行一个工作者线程,那么在同一个时候、完全可能有几个不同的处理器在同一个套接字上,进行数据的收发操作。
为了完成前述的简单回应服务器示例,我们需要提供一个ServerWorkerThread(服务器工作者线程)函数。在程序消单8.10中,我们展示了如何设计一个工作者线程例程,令其使用单句柄数据以及单I/O操作数据,为I/O请求提供服务。
程序清单8—10 完成端口工作者线程
DWORD WINAPI ServerWokerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort=(HANDLE)ComleTionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIoData;
DWORD SendBytes,RecvBytes;
DWORDFlages;
while(TRUE)
{
//wait for I/O to Complete on any socket
// associated with the completionport
GetQueuedCompletionStatus(CompletionPort,
&BytesTransferred,
(LPDWORD)&PerHandleData,
(LPOVERLAPPED *)&PerIoData,INFINITE);
//first check o see whether an error has occurr
// on the socket ,if so ,close the socke and clearup the
//per-handle and Per-I/O operation data associated with
//socket
if (BytesTransferred == 0)&&
(PerIoData->OperationType == RECV_POSTED)&&
(PerIoData->OperationType == SEND_POSTED)
{
//A Zero BytesTransferred indicates that the
//socke has been closed by the peer,so you should
//close the socket
//Note: Per-handle Data was used to refresence the
// socket associated with the I/O operation;
closesocket(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
continue;
}
//service the completed I/O request;You
//detemine which I/O request has just completed
//by looking as the operationType field contained
// the per-I/O operation data
if (PerIoData->OperationType == RECV_POSTED)
{
//do someting with the received data
//in PerIoData->Buffer
}
//Post another WSASend or WSARecv operation
//as a example we will post another WSARecv()
Flags = 0;
//Set up the Per-I/O Operation Data for a next
//overlapped call