18,356
社区成员
发帖
与我相关
我的任务
分享
DWORD WINAPI ServiceThread( void *pParam )
{
CMyService *pService = (CMyService*)pParam;//主窗口指针
HANDLE hComPort = pService->m_hCompPort;//完成端口
CClientSocketContext * pClient;
DWORD dwIoSize; //传输字节数
LPOVERLAPPED lpOverlapped; //重叠结构指针
BOOL bFlagExit = FALSE; //服务线程退出
BOOL bIORet;
CClientListManager * pClientMgr;
pClientMgr=CClientListManager::GetClientListManager();
pService->DebugMsg("pClientMgr %lx In ServiceThread ",pClientMgr);
while (!bFlagExit)
{
dwIoSize = -1;
lpOverlapped = NULL;
pClient = NULL;
//等待I/O操作结果
bIORet = GetQueuedCompletionStatus(hComPort,
&dwIoSize,
(LPDWORD) &pClient,
&lpOverlapped,
INFINITE);
if (FALSE == bIORet )
{
pService->DebugMsg("CardService: failed overlapped operation occurs. maybe client timeout");
}
//成功的操作完成
if(bIORet && lpOverlapped && pClient)
{
pService->DebugMsg("CardService: normal overlapped occurs,lpOverlapped %lx,pClient %lx",lpOverlapped,pClient);
pClientMgr->ProcessClientIO(pClient, lpOverlapped, dwIoSize);
}
//服务器退出
if(!pService->m_bTcpipServerRunning)
{
pService->DebugMsg("CardService: exit.(m_bTcpipServerRunning FALSE)");
bFlagExit = TRUE;
}
}
return 0;
}
void CClientListManager::ProcessClientIO( CClientSocketContext* pClient,
LPOVERLAPPED pOverlapped,
DWORD dwIOSize)
{
if (0==dwIOSize)
{
//close client
DeleteClient(pClient);
return;
}
//崩溃的时候,从一次调试可以看到,这里dwIOSize的值是正确的。pOverlapped、pClient、pIO的值都是非法的,所以下面进行判断的时候崩溃了。奇怪的是这里pOverlapped和pClient都是GetQueuedCompletionStatus获得的
PIO_OPERATION_DATA pIO = CONTAINING_RECORD(pOverlapped, IO_OPERATION_DATA,overlapped
if (pIO->type==OP_WRITE)
{
pClient->AsyncRecvData();
//具体其他操作
}
else if (pIO->type==OP_READ)
{
//其他操作
}
}
BOOL CClientSocketContext::AsyncRecvData( void )
{
DWORD flags = 0; //标志
DWORD recvBytes =0; //发送字节数
ZeroMemory(&m_iIO, sizeof(m_iIO));
m_iIO.type = OP_READ;//操作类型
WSABUF wsaBuf;
wsaBuf.buf = (char*)&m_iIO.recvBuf; //
wsaBuf.len = sizeof(m_iIO.recvBuf);
time(&m_tLastTimeValue);
//读取数据
if (WSARecv(m_socket,
&wsaBuf,
1,
&recvBytes,
&flags,
&m_iIO.overlapped,
NULL) == SOCKET_ERROR)
{
if(ERROR_IO_PENDING != WSAGetLastError())
{
return FALSE;
}
}
return TRUE;
}
BOOL CClientSocketContext::AsyncSendData( void )
{
DWORD flags = 0; //标志
DWORD sendBytes =0; //发送字节数
m_oIO.type = OP_WRITE; //操作类型
WSABUF wsaBuf;
wsaBuf.buf = (char*)&(m_oIO.recvBuf); //
wsaBuf.len = m_oIO.ulDataLen;
time(&m_tLastTimeValue);
//发送数据
if (WSASend(m_socket,
&wsaBuf,
1,
&sendBytes,
flags,
&m_oIO.overlapped,
NULL) == SOCKET_ERROR)
{
if(ERROR_IO_PENDING != WSAGetLastError())//成功发起重叠操作
{
return FALSE;
}
}
return TRUE;
}
DWORD CClientListManager::KillClientOfTimeout()
{
EnterCriticalSection(&m_critical_section_for_client_list);
list<CClientSocketContext*>::iterator iterList;;
CClientSocketContext* pFindClient;
time_t tCurTime;
double dTimediff;
for (iterList = m_ClientList.begin(); iterList!=m_ClientList.end();)
{
time(&tCurTime);
//dTimediff=tCurTime-(*iterList)->m_tLastTimeValue;
dTimediff=difftime(tCurTime,(*iterList)->m_tLastTimeValue);
if(dTimediff>s_m_dCardTimeoutValue)
{
pFindClient=*iterList;
iterList=m_ClientList.erase(iterList);
delete pFindClient;//删的过程对改client加个锁?
}
else
{
iterList++;
}
}
LeaveCriticalSection(&m_critical_section_for_client_list);
return 0;
}