完成端口例子二
Tag: GetQueuedComple
//工作线程
DWORD WINAPI ServerWorkerThread(LPVOID ComlpetionPortID)
{
HANDLE ComplectionPort = (HANDLE) ComlpetionPortID;
DWORD BytesTransferred;
LPOVERLAPPED Overlapped;
LPPER_HANDLE_DATA PerHandleData;
LPPER_IO_OPERATION_DATA PerIOData;
DWORD SendBytes,RecvBytes;
DWORD Flags;
while (TRUE)
{
if (GetQueuedCompletionStatus(ComplectionPort,&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED*)&PerIOData,INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error%d/n",GetLastError());
return 0;
}
//首先检查套接字上是否发生错误,如果发生了则关闭套接字并且清除同套节字相关的SOCKET_INFORATION 结构体
if (BytesTransferred == 0)
{
printf("Closing Socket %d/n",PerHandleData->Socket);
if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)
{
printf("closesocket failed with error %d/n",WSAGetLastError());
return 0;
}
GlobalFree(PerHandleData);
GlobalFree(PerIOData);
continue;
}
//检查BytesRecv域是否等于0,如果是,说明WSARecv调用刚刚完成,可以用从己完成的WSARecv调用返回的BytesTransferred值更新BytesRecv域
if (PerIOData->BytesRecv == 0)
{
PerIOData->BytesRecv = BytesTransferred;
PerIOData->BytesSend = 0;
}
else
{
PerIOData->BytesRecv +=BytesTransferred;
}
//
if (PerIOData->BytesRecv > PerIOData->BytesSend)
{
//发布另一个WSASend()请求,因为WSASendi 不能确保发送了请的所有字节,继续WSASend调用直至发送完所有收到的字节
ZeroMemory(&(PerIOData->OVerlapped),sizeof(OVERLAPPED));
PerIOData->DATABuf.buf = PerIOData->Buffer + PerIOData->BytesSend;
PerIOData->DATABuf.len = PerIOData->BytesRecv - PerIOData->BytesSend;
if (WSASend(PerHandleData->Socket,&(PerIOData->DATABuf),1,&SendBytes,0,&(PerIOData->OVerlapped),NULL) ==SOCKET_ERROR )
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() fialed with error %d/n",WSAGetLastError());
return 0;
}
}
}
else
{
PerIOData->BytesRecv = 0;
//Now that is no more bytes to send post another WSARecv() request
//现在己经发送完成
Flags = 0;
ZeroMemory(&(PerIOData->OVerlapped),sizeof(OVERLAPPED));
PerIOData->DATABuf.buf = PerIOData->Buffer;
PerIOData->DATABuf.len = DATA_BUFSIZE;
if (WSARecv(PerHandleData->Socket,&(PerIOData->DATABuf),1,&RecvBytes,&Flags,&(PerIOData->OVerlapped),NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d/n",WSAGetLastError());
return 0;
}
}
}
}
}