首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

GetQueuedCompletionStatus 异常处理(997)

2012-03-08 
GetQueuedCompletionStatus 错误处理(997)DWORD WINAPI CGCSIoCP::WorkDealThread( void *pVoid){HANDLE *

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),否则由于线程是迭代工作的,在没有产生新的错误码之前会延存前一错误码。
[解决办法]

探讨
在调用GetQueuedCompletionStatus 之前最好调用SetLastError(0),否则由于线程是迭代工作的,在没有产生新的错误码之前会延存前一错误码。

热点排行