完成端口 Send时 锁住的问题
完成端口 Send时 锁住的问题
==============================
客户端每一秒钟发送一条数据到服务器.数据为大概30字符..服务器收到后。再转发到每个连接上来的客户端.
开了10个客户端就锁住了... 将 WaitForSingleObject 该成 超时3000,返回的是WAIT_TIMEOUT。
请大家帮忙....
//发送消息
void CIOCPServer::Send(LPCLIENTCONTEXT lpContext, CString strData,int userType)
{
lpContext->m_WriteBuffer.Write(strData);
printf("Waiting for WRITE event\n");
DWORD dwRet =WaitForSingleObject(lpContext->m_hWriteComplete, INFINITE);
//准备发送数据
lpContext->m_wsaOutBuffer.buf = lpContext->m_WriteBuffer.GetBuffer();
lpContext->m_wsaOutBuffer.len = lpContext->m_WriteBuffer.GetBufferLen();
LPOVERLAPPEDPLUS lpOverlap = AllocateOverlappedPlus(OP_IOWrite);
PostQueuedCompletionStatus(m_hIocp, 0, (DWORD) lpContext, &lpOverlap->ol);
}
// 线程 GetQueuedCompletionStatus 后 转到下函数
BOOL CIOCPServer::ProcessIOMessage(IOType opCode, LPCLIENTCONTEXT lpContext , DWORD dwIoSize)
{
BOOL bRet = FALSE;
//根据opCode确定操作
switch (opCode)
{
case OP_IOInitialize:
bRet = OnClientInitializing(lpContext, dwIoSize);
break;
case OP_IORead:
bRet = OnClientReading(lpContext, dwIoSize);
break;
case OP_IOWrite:
bRet = OnClientWriting(lpContext, dwIoSize);
break;
default:
printf("worker thread:unknown operation...\n");
}
return bRet;
}
/// 上函数 opCode->OP_IOWrite 转到下函数
BOOL CIOCPServer::OnClientWriting(LPCLIENTCONTEXT lpContext, DWORD dwIoSize)
{
ULONG ulFlags = MSG_PARTIAL;
//删除已经发送了的数据
lpContext->m_WriteBuffer.Delete(dwIoSize);
if (lpContext->m_WriteBuffer.GetBufferLen() == 0)
{
//数据都发送了!
//清除缓存
lpContext->m_WriteBuffer.ClearBuffer();
// 写事件完成了,可以允许下次写了
SetEvent(lpContext->m_hWriteComplete); ///////// <----------------------------信号完成
printf("WRITE event XB completed \n");
}
else
{
LPOVERLAPPEDPLUS pOverlap = AllocateOverlappedPlus(OP_IOWrite);
lpContext->m_wsaOutBuffer.buf = lpContext->m_WriteBuffer.GetBuffer();
lpContext->m_wsaOutBuffer.len = lpContext->m_WriteBuffer.GetBufferLen();
printf("data to sent: %s, length:%d\n",
lpContext->m_wsaOutBuffer.buf,
lpContext->m_wsaOutBuffer.len);
int nRetVal = WSASend(lpContext->m_Socket,
&lpContext->m_wsaOutBuffer,
1,
&lpContext->m_wsaOutBuffer.len,
ulFlags,
&pOverlap->ol,
NULL);
if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING )
{
FreeClientContext(lpContext);
}
}
return FALSE;//不等待读了!
}