CIOCP自定义帮助函数

                                                 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;
}
posted @ 2012-10-18 16:04 xingoo 阅读(...) 评论(...) 编辑 收藏