您好,欢迎来到[编程问答]网站首页   源码下载   电子书籍   软件下载   专题
当前位置:首页 >> 编程问答 >> VC/MFC >> 完成端口GetQueuedCompletionStatus()当客户端连接上来没有相应

完成端口GetQueuedCompletionStatus()当客户端连接上来没有相应

来源:网络整理     时间:2016/7/26 13:55:54     关键词:

关于网友提出的“ 完成端口GetQueuedCompletionStatus()当客户端连接上来没有相应”问题疑问,本网通过在网上对“ 完成端口GetQueuedCompletionStatus()当客户端连接上来没有相应”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: 完成端口GetQueuedCompletionStatus()当客户端连接上来没有相应
描述:

前面多个客户端异常断电掉线,服务端是通过心跳包来监测掉线的,如果掉线则调用closesocket(),可是再连接后GetQueuedCompletionStatus函数就没有响应了
DWORD WINAPI CIOCPModel::_WorkerThread(LPVOID lpParam)
{    
THREADPARAMS_WORKER* pParam = (THREADPARAMS_WORKER*)lpParam;
CIOCPModel* pIOCPModel = (CIOCPModel*)pParam->pIOCPModel;
int nThreadNo = (int)pParam->nThreadNo;
pIOCPModel->_ShowMessage("工作者线程启动,ID: %d.",nThreadNo);
OVERLAPPED           *pOverlapped = NULL;
PER_SOCKET_CONTEXT   *pSocketContext = NULL;
DWORD                dwBytesTransfered = 0;
// 循环处理请求,知道接收到Shutdown信息为止
while (WAIT_OBJECT_0 != WaitForSingleObject(pIOCPModel->m_hShutdownEvent, 0))
{
BOOL bReturn = GetQueuedCompletionStatus(
pIOCPModel->m_hIOCompletionPort,
&dwBytesTransfered,
(PULONG_PTR)&pSocketContext,
&pOverlapped,
INFINITE);
// 如果收到的是退出标志,则直接退出
if ( EXIT_CODE==(DWORD)pSocketContext )
{
break;
}
// 判断是否出现了错误
if( !bReturn )  
{  
DWORD dwErr = GetLastError();
// 显示一下提示信息
if(pSocketContext->m_Socket != INVALID_SOCKET)
{
if( !pIOCPModel->HandleError( pSocketContext,dwErr ) )
{
PER_IO_CONTEXT* pIoContext = CONTAINING_RECORD(pOverlapped,PER_IO_CONTEXT,m_Overlapped);
//break;
if(ACCEPT_POSTED == pIoContext->m_OpType)
{
int i = 0;
while(i<12)
{
bool Flag = pIOCPModel->_PostAccept(pIoContext);
if(!Flag)
{
i++;
}
else 
{
break;
}
}
}
}
}
continue;  
}  
else  
{  
// 读取传入的参数
PER_IO_CONTEXT* pIoContext = CONTAINING_RECORD(pOverlapped, PER_IO_CONTEXT, m_Overlapped);  
// 判断是否有客户端断开了
if((0 == dwBytesTransfered) && ( RECV_POSTED==pIoContext->m_OpType || SEND_POSTED==pIoContext->m_OpType))  
{  
pIOCPModel->_ShowMessage( _T("客户端 %s:%d 断开连接."),inet_ntoa(pSocketContext->m_ClientAddr.sin_addr), ntohs(pSocketContext->m_ClientAddr.sin_port) );
// 释放掉对应的资源
pIOCPModel->_RemoveContext( pSocketContext );
  continue;  
}  
else
{
switch( pIoContext->m_OpType )  
{  
 // Accept  
case ACCEPT_POSTED:

// 为了增加代码可读性,这里用专门的_DoAccept函数进行处理连入请求
pIOCPModel->_DoAccpet( pSocketContext, pIoContext );
}
break;
// RECV
case RECV_POSTED:
{
// 为了增加代码可读性,这里用专门的_DoRecv函数进行处理接收请求
pIOCPModel->_DoRecv( pSocketContext,pIoContext,dwBytesTransfered );
}
break;
// SEND
// 这里略过不写了,要不代码太多了,不容易理解,Send操作相对来讲简单一些
case SEND_POSTED:
{
pIOCPModel->_PostRecv(pIoContext );
}
break;
default:
// 不应该执行到这里
TRACE(_T("_WorkThread中的 pIoContext->m_OpType 参数异常.\n"));
break;
} //switch
}//if
}//if
}//while
TRACE(_T("工作者线程 %d 号退出.\n"),nThreadNo);
// 释放线程参数
RELEASE(lpParam);
return 0;
}
心跳包监测
DWORD WINAPI CIOCPModel::_HeartWork(LPVOID lpParam)
{
THREADPARAMS_WORKER* pParam = (THREADPARAMS_WORKER*)lpParam;
CIOCPModel* pIOCPModel = (CIOCPModel *)pParam->pIOCPModel;
PER_SOCKET_CONTEXT *pSocketContext;
PER_IO_CONTEXT *pIoContext;
while(pIOCPModel->m_StopFlag)
{
WaitForSingleObject(g_hEventHeart,INFINITE);
WaitForSingleObject(g_ThreadParameter,INFINITE);
CTime tm = CTime::GetCurrentTime();
for(int i = 0;im_arrayClientContext.GetCount();i++)
{
pSocketContext = pIOCPModel->m_arrayClientContext.GetAt(i);
//ULONG time = tm.GetTime();
CTimeSpan Timediff = tm-pSocketContext->tm;
if(Timediff.GetTotalSeconds()>180)
{
pIoContext = pSocketContext->m_arrayIoContext.GetAt(0);
closesocket(pIoContext->m_sockAccept);
}
}
ReleaseSemaphore(g_ThreadParameter, 1, NULL);
}
RELEASE(lpParam);
return 0;
}
分不多了,求大神讲讲可能得原因吧


以上介绍了“ 完成端口GetQueuedCompletionStatus()当客户端连接上来没有相应”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/2944224.html

相关图片

相关文章