一些IOCP处理数据收发的代码片断
接收完成操作函数

bool CIOCPServer::OnClientReading(ClientContext* pContext, DWORD dwIoSize)


{
CLock cs(CIOCPServer::m_cs, "OnClientReading");

if (dwIoSize == 0)

{
RemoveStaleClient( pContext, FALSE );
return false;
}

// 添加到缓冲区 Add the message to out message
// Dont forget there could be a partial, 1, 1 or more + partial mesages
pContext->m_ReadBuffer.Write(pContext->m_byInBuffer,dwIoSize);



..

}


发送完成处理函数

bool CIOCPServer::OnClientWriting(ClientContext* pContext, DWORD dwIoSize)


{
ULONG ulFlags = MSG_PARTIAL;

// 已经发送的数据需要从发送缓冲中去除 Finished writing - tidy up
pContext->m_WriteBuffer.Delete(dwIoSize);

// 判断写缓冲中的数据是否还有未发送的
if (pContext->m_WriteBuffer.GetBufferLen() == 0)

{
// 发送完成
pContext->m_WriteBuffer.ClearBuffer();
// 发送完成,写完成事件置位 Write complete
SetEvent(pContext->m_hWriteComplete);
return true; // issue new read after this one

}
else

{
// 还有数据需要发送
OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);

m_pNotifyProc((LPVOID) m_pFrame, pContext, NC_TRANSMIT);

// 处理数据发送工作
pContext->m_wsaOutBuffer.buf = (char*) pContext->m_WriteBuffer.GetBuffer();
pContext->m_wsaOutBuffer.len = pContext->m_WriteBuffer.GetBufferLen();

int nRetVal = WSASend(pContext->m_Socket,
&pContext->m_wsaOutBuffer,
1,
&pContext->m_wsaOutBuffer.len,
ulFlags,
&pOverlap->m_ol,
NULL);


if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING )
RemoveStaleClient( pContext, FALSE );

}
return false; // issue new read after this one
}

发送数据

void CIOCPServer::Send(const CString& strClient, CString strData)


{
ClientContext* pContext = FindClient(strClient);
if (pContext == NULL)
return;
int nBufLen = strData.GetLength();

// 将需要发送的数据放入缓冲区 4 byte header [Size of Entire Packet]
pContext->m_WriteBuffer.Write((PBYTE) &nBufLen, sizeof(nBufLen));

pContext->m_WriteBuffer.Write((PBYTE) strData.GetBuffer(nBufLen), nBufLen);
// 等待上次发送结束 Wait for Data Ready signal to become available
WaitForSingleObject(pContext->m_hWriteComplete, INFINITE);

// 到这里,上一次数据已经全部发送完成

// 准备好发送缓冲区(?)
int nSize = pContext->m_WriteBuffer.GetBufferLen();
pContext->m_wsaOutBuffer.buf = (CHAR*) new BYTE[nSize];
pContext->m_wsaOutBuffer.len = nSize;

// 通知工作者线程可以进行写操作
OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IOWrite);
PostQueuedCompletionStatus(m_hCompletionPort, 0, (DWORD) pContext, &pOverlap->m_ol);

pContext->m_nMsgOut++;

}


posted on 2007-11-20 16:34 王骏的BLOG 阅读(1091)
评论(7) 编辑 收藏