首页
学习
活动
专区
圈层
工具
发布

游戏服务器之多线程发送(中)

4、拷贝数据到会话的发送缓冲区

交换发送队列和添加队列,拷贝会话的发送队列的数据到会话的发送缓冲区

代码语言:javascript
复制
BOOL ExecSockDataMgr::CopyWaitSendBuffers(PEXECDATASENDTHREAD pSendThread, BOOL boForceCopy)  
{  
    CGateSendPacket *pSendPacket, **ppPacketList;  
    CBList<CGateSendPacket*> *pBufferList;  
    PRUNGATEUSERSESSION pSession;  
 INT_PTR nCount;  
    common::NetPacketHeader *pPackHdr;  
 int nSize, nTotalSize, nAppendSize, nPacketSize;  
    TICKCOUNT dwMsgTick;  
 
 if ( !boForceCopy )  
        boForceCopy = TryEnterCriticalSection( &pSendThread->SendQueueLock );  
 else EnterCriticalSection( &pSendThread->SendQueueLock );  
 
 if ( boForceCopy )  
    {  
        pBufferList = pSendThread->pSendAppendList;  
        pSendThread->pSendAppendList = pSendThread->pSendProcList;  
        pSendThread->pSendProcList = pBufferList;  
        LeaveCriticalSection( &pSendThread->SendQueueLock );  
 
        nCount = pBufferList->count();  
 if ( nCount > 0 )  
        {  
            dwMsgTick = _getTickCount();  
            ppPacketList = (CGateSendPacket**)*pBufferList;  
            nTotalSize = 0;  
            nAppendSize = 0;  
 do 
            {  
                pSendPacket = *ppPacketList;  
                ppPacketList++;  
                nCount--;  
 
                nPacketSize = (int)pSendPacket->getLength();  
 if (pSendPacket->m_nUserIndex < m_SessionList.count())  
                    pSession = m_SessionList[pSendPacket->m_nUserIndex];  
 else pSession = NULL;  
 
 if ( pSession && pSession->nSocket != INVALID_SOCKET && !pSession->boMarkToClose   
                    && !pSession->boRemoteClosed && pSession->nVerifyIdx == pSendPacket->m_nVerify )  
                {  
 //检测并保留会话缓冲区空间(1024字节对齐) 
                    nSize = pSession->SendBuf.nOffset + sizeof(*pPackHdr) + nPacketSize;  
 if ( pSession->SendBuf.nSize < nSize )//拓展发送缓冲区的大小 
                    {  
                        nSize = (nSize / SESSION_DATAGROW_SIZE + 1) * SESSION_DATAGROW_SIZE;  
                        pSession->SendBuf.nSize = nSize;  
                        pSession->SendBuf.lpBuffer = (char*)realloc( pSession->SendBuf.lpBuffer, nSize );  
                    }  
 //写入包头 
                    pPackHdr = (common::NetPacketHeader*)&pSession->SendBuf.lpBuffer[pSession->SendBuf.nOffset];  
                    pPackHdr->dwIdent = common::NetPacketHeader::NetPacketHeaderIdent;  
                    pPackHdr->wPacketSize = nPacketSize;  
                    pPackHdr->wVerification = 0;  
                    pSession->SendBuf.nOffset += sizeof(*pPackHdr);  
                    nAppendSize += sizeof(*pPackHdr);  
 //写入包体数据(从数据包到发送缓冲区) 
                    memcpy( &pSession->SendBuf.lpBuffer[pSession->SendBuf.nOffset], pSendPacket->getMemoryPtr(), nPacketSize );  
                    pSession->SendBuf.nOffset += nPacketSize;  
                    pSession->dwServerMsgTick = dwMsgTick;  
                    nAppendSize += nPacketSize;  
                }  
                nTotalSize += nPacketSize;  
                pSendPacket->freeBack();  
            }  
 while ( nCount > 0 );  
            pBufferList->clear();  
 
            InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, nAppendSize );//待发送给用户的数据包大小(该变量记录用于程序调试) 
            InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, -nTotalSize );//减少待发给用户的数据包队列大小 
        }  
    }  
 return boForceCopy;  
}   

下一篇
举报
领券