GetQueuedCompletionStatus 错误处理(997)
DWORD WINAPI CGCSIoCP::WorkDealThread( void *pVoid)
{
HANDLE * h = NULL;
GCSTS_Base_Overlapped *pOverlapped=NULL;
while(m_bActive)
{
DWORD dwBytesTransferred = 0;
BOOL ret =GetQueuedCompletionStatus(g_hCompletionPort, &dwBytesTransferred,(LPDWORD)&h, (LPOVERLAPPED *)&pOverlapped, INFINITE);
if(ErrDeal(ret, dwBytesTransferred, h, pOverlapped))
{
continue;
}
//正常下处理数据
.
.
.
}
return 0;
}
BOOL CGCSIoCP::ErrDeal(BOOL ret, DWORD dwBytesTransferred, HANDLE h, GCSTS_Base_Overlapped *pOverlapped)
{
int err = WSAGetLastError();
//If a socket handle associated with a completion port is closed, GetQueuedCompletionStatus returns ERROR_SUCCESS,
//with lpNumberOfBytes equal zero.
if(dwBytesTransferred==0/* && err == ERROR_SUCCESS*/)
{
//关闭SOCKET,清理相关数据
//有时候在这一段返回,err=997 ???????????????????????????????????????
//对于997号错误,该如何处理,
return TRUE;
}
//If *lpOverlapped is NULL and the function does not dequeue a completion packet from the completion port, the return value is zero.
//The function does not store information in the variables pointed to by the lpNumberOfBytes and lpCompletionKey parameters. To get extended error
//information, call GetLastError. If the function did not dequeue a completion packet because the wait timed out, GetLastError returns WAIT_TIMEOUT.
if(ret == FALSE && pOverlapped == NULL && err == WAIT_TIMEOUT)
{
return FALSE;
}
//If *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port,
//the return value is zero. The function stores information in the variables pointed to by lpNumberOfBytes, lpCompletionKey,
//and lpOverlapped. To get extended error information, call GetLa stError.
if(ret == FALSE && pOverlapped != NULL && err != ERROR_IO_PENDING)
{
//关闭SOCKET,清理相关数据
return TRUE;
}
//If the function dequeues a completion packet for a successful I/O operation from the completion port, the return value is nonzero.
//The function stores information in the variables pointed to by the lpNumberOfBytesTransferred, lpCompletionKey, and lpOverlapped parameters.
if(ret == TRUE)
{
return FALSE;
}
//关闭SOCKET,清理相关数据
return TRUE;
}
[解决办法]
代码注释太多,有些乱,帮你查了错误:重叠 I/O 操作在进行中。
///////////////////////////////////////////////////
//关闭SOCKET,清理相关数据
//有时候在这一段返回,err=997 ???????????????????????????????????????
//对于997号错误,该如何处理,
return TRUE;
//////////////////////////////////////////////////
comment: 当你关闭SOCKET时, 我不知你是怎样来清理相关数据的, 有可能在这个SOCKET上有抛出的未决IO, 每次你应该只负责清理本次的IO Buffer
[解决办法]
在调用GetQueuedCompletionStatus 之前最好调用SetLastError(0),否则由于线程是迭代工作的,在没有产生新的错误码之前会延存前一错误码。
[解决办法]