1 客户连接列表
m_pConnectionList指向客户连接列表,描述所有连接的CIOCPContext对象组成的表
AddAConnnection函数向列表中加入一个CIOCPContext对象。如果到达最大数量返回FALSE
CloseAConnnection函数关闭指定的客户连接
CloseAllConnection函数遍历整个连接列表,关闭所有的客户套接字
2 抛出接收请求的列表
所有未决的accept请求都在m_pPendingAccepts指向的列表中
InsertPendingAccept函数将一个IO缓冲区对象插入到m_pPendingAccepts表中
RemovePendingAccept函数遍历这个表,从中移除指定的缓冲区对象
3 序列化读操作
为保证异步读操作投递顺序完成,为每个连接投递读请求分配一个序列号。
pOutOfOederReads列表中的元素是按照其序列号从小到大的顺序排列的
GetNextReadBuffer函数:
以客户上下文 和 读操作完成缓冲区对象 为参数,以正确的顺序返回这个客户发送的下一个缓冲区对象
主要函数代码:
CIOCPBuffer *CIOCPServer::GetNextReadBuffer(CIOCPContext *pContext,CIOCPBuffer *pBuffer)
{
if(pBuffer !=NULL)
{
if(pBuffer->nSequenceNumber == pContext->nCurrentReadSequence)
return pBuffer;
pBuffer->pNext = NULL;
CIOCPBuffer *ptr = pContext->pOutOfOrderReads;
CIOCPBuffer *pPre = NULL;
while(ptr!=NULL)
{
if(pBuffer->nSequenceNumber < ptr->nSequenceNumber)
break;
pPre = ptr;
ptr = ptr->pNext;
}
if(pPre == NULL)
{
pBuffer->pNext = pContext->pOutOfOrderReads;
pContext->pOutOfOrderReads = pBuffer;
}
else
{
pBuffer->pNext = pPre->pNext;
pPre->pNext = pBuffer;
}
}
CIOCPBuffer *ptr = pContext->pOutOfOrderReads;
if(ptr!=NULL &&(ptr->nSequenceNumber == pContext->nCurrentReadSequence))
{
pContext->pOutOfOrderReads = ptr->pNext;
return ptr;
}
return NULL
}
4 投递重叠IO
PostAccept PostSend PostRecv函数分别用于在套接字上投递AcceptIO SendIO RecvIO
PostRecv代码比其他两个多了一个投递序列号..其他的都差不多,代码如下:
BOOL CIOCPServer::PostRecv(CIOCPContext *pContext,CIOCPBuffer *pBuffer)
{
pBuffer->nOperation = OP_READ;
::EnterCriticalSection(&pContext->Lock);
pBuffer->nSequenceNumber = pContext->nSequenceNumber;
DWORD dwBytes;
DWORD dwFlags= 0;
WSABUF buf;
buf.buf = pBuffer->buff;
buf.len = pBuffer->nLen;
if(::WSARecv(pContext->s,&buf,1,&dwBtytes,&dwFlags,&pBuffer->ol,NULL)!=NO_ERROR)
{
::LeaveCriticalSection(&pContext->Lock);
return FALSE;
}
pContext->nOutstandingRecv++;
pContext->nReadSequence++;
::LeaveCriticalSection(&pContext->Lock);
return TRUE;
}
转载于:https://my.oschina.net/u/204616/blog/545081