www.gusucode.com > VC++三子棋游戏源码(类似五子棋)-源码程序 > VC++三子棋游戏源码(类似五子棋)-源码程序\code\Server\MessageQ.cpp

    #include "MessageQ.h"
////////////////////////////////////////////////////////////////////////////////
// Download by http://www.NewXing.com
CMessageQueue::CMessageQueue()
{
    InitializeCriticalSection(&m_tUsageSection);

	if (m_tMessageQueue.size() != 0)
	{
        RemoveAllMessages();
	}

    //create event indicator event
	SECURITY_ATTRIBUTES tSecurityAttr;
	tSecurityAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	tSecurityAttr.lpSecurityDescriptor = NULL;
	tSecurityAttr.bInheritHandle = TRUE;

	m_hLockQueueHandle = CreateEvent(&tSecurityAttr, TRUE, FALSE, NULL);
}

CMessageQueue::~CMessageQueue()
{
    if (m_tMessageQueue.size() != 0)
	{
        RemoveAllMessages();
	}
    DeleteCriticalSection(&m_tUsageSection);

	if( NULL != m_hLockQueueHandle)
	{
		CloseHandle(m_hLockQueueHandle);
		m_hLockQueueHandle = NULL;
	}
}

void CMessageQueue::BlockQueue()
{
    EnterCriticalSection(&m_tUsageSection);
}

void CMessageQueue::UnBlockQueue()
{
    LeaveCriticalSection(&m_tUsageSection);
}

WORD CMessageQueue::AddMessage(TSingleMessage* pMsg)
{
	BlockQueue();
	
	TSingleMessage* ptMsg = pMsg;    
    m_tMessageQueue.push_back((TSingleMessage*)ptMsg);
	WORD wMsgCount = GetMsgCount();
    
	UnBlockQueue();

	SetQueueHandleEvent();
	
	return wMsgCount;
}

WORD CMessageQueue::InsertMessage( TSingleMessage* pMsg, WORD pos )
{
	BlockQueue();

    TSingleMessage* ptMsg = pMsg;
    m_tMessageQueue.insert(m_tMessageQueue.begin()+pos, ptMsg);

	UnBlockQueue();
    SetQueueHandleEvent();

    return pos;
}
WORD CMessageQueue::AddSingleMessage( TSingleMessage* pMsg )
{
    BlockQueue();

    TSingleMessage* ptMsg = pMsg;    
    m_tMessageQueue.push_back(pMsg);
	WORD wMsgCount = GetMsgCount();

    UnBlockQueue();
	SetQueueHandleEvent();

    return wMsgCount;
}

TSingleMessage* CMessageQueue::GetMessage( WORD Num )
{
	BlockQueue();

    TSingleMessage* pMsg = NULL;
    pMsg = PeekMessage( Num );  

	UnBlockQueue();	
    
    return pMsg;
}

TSingleMessage* CMessageQueue::PeekMessage( WORD Num )
{
	if (!IsMsgValid(Num)) return NULL;

	BlockQueue();

    TSingleMessage* lp;    
    TSingleMessage* pssm = m_tMessageQueue.at(Num);
    lp = pssm;

	UnBlockQueue();	

    return lp;
}

HANDLE CMessageQueue::GetLockQueueHandle()
{
	return m_hLockQueueHandle;
}

BOOL CMessageQueue::IsMsgValid(WORD Num)
{
    if (Num < 0 || Num >= GetMsgCount()) return FALSE;

    return TRUE;
}

void CMessageQueue::SetQueueHandleEvent()
{
    if (GetMsgCount() > 0)
	{
		SetEvent(m_hLockQueueHandle);
	}
    else
	{
		ResetEvent(m_hLockQueueHandle);
	}
}

WORD CMessageQueue::GetMsgCount()
{
	BlockQueue();

    WORD wMsgCount = (WORD)m_tMessageQueue.size();

	UnBlockQueue();

    return wMsgCount;
}

BOOL CMessageQueue::IsQueueFull()
{
	HANDLE hQueueHandle = GetLockQueueHandle();
	BOOL bIsFull = (WaitForSingleObject(hQueueHandle, 0) == WAIT_OBJECT_0);
	
	return bIsFull;
}

void CMessageQueue::RemoveMessage(WORD Num)
{
    if (!IsMsgValid(Num)) return;
	
	BlockQueue();
    
	TSingleMessage *pMessage = GetMessage( Num );
	if( NULL != pMessage )
	{
		delete pMessage;
		pMessage = NULL;
	}
    
	UnBlockQueue();
	SetQueueHandleEvent();
}

void CMessageQueue::RemoveAllMessages()
{
	BlockQueue();

    for(WORD wIndex = 0; wIndex < GetMsgCount(); wIndex++)
    {
        LPVOID lpMessage = PeekMessage( wIndex );
        if (NULL != lpMessage)
		{
			delete lpMessage;
			lpMessage = NULL;
		}
    }
    m_tMessageQueue.clear();

	UnBlockQueue();
	SetQueueHandleEvent();
}

void CMessageQueue::ClearMessage(WORD Num)
{
    if (!IsMsgValid(Num)) return;

	BlockQueue();

    m_tMessageQueue.erase(m_tMessageQueue.begin() + Num);

	UnBlockQueue();
	SetQueueHandleEvent();
}

void CMessageQueue::ClearAllMessages()
{
	BlockQueue();

    m_tMessageQueue.clear();
	
	UnBlockQueue();
	SetQueueHandleEvent();
}

TSingleMessage* CMessageQueue::GetFirstMessage()
{
    BlockQueue();

	int Num = 0;
    TSingleMessage* pMessage = GetMessage( Num );
	if( NULL != pMessage )
	{
		m_tMessageQueue.erase(m_tMessageQueue.begin() + Num);
	}

    UnBlockQueue();

	if( NULL != pMessage )
	{
		SetQueueHandleEvent();
	}
    
	return pMessage;
}

void CMessageQueue::RemoveMsgAndItsContents(void *pMsg, BOOL bDelOrNot)//从消息队列中删去,并删去相应消息内容
{
	//输入变量
	TSingleMessage *ptMsg = (TSingleMessage *)pMsg;
	if( NULL == ptMsg)
	{
		return;
	}
	else {}

    WORD wNum = 0;
    BOOL bFindOrNot = false;    
    while( wNum < GetMsgCount() )
    {
        TSingleMessage* ptMessage = PeekMessage( wNum );
        if (ptMessage == ptMsg)
        {
            m_tMessageQueue.erase(m_tMessageQueue.begin()+wNum);
            if(bDelOrNot)
            {
                delete ptMessage;
				ptMessage = NULL;
            }
            bFindOrNot = true;
        }
        wNum ++ ;
    }
    if( !bFindOrNot )
    {
    }

    SetQueueHandleEvent();

    return ;

}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//class CMessageMgr
void *CMessageMgr::pvPL_AssembleMsg(TMainHeader* ptMainHdr, TSubHeader* ptSubHdr, void * pvMsgData )
{
    //Allocate the Sending Msg Data and return its' pointer.
    char * pcWholeMsg = NULL;
    char * pcMsgStart = NULL;

    WORD wLen = 0;
    if( NULL != ptSubHdr )
    {
        wLen = ptSubHdr->dwDatalen ;
    }
     
    WORD wAllLen = wPL_GetMainSubHerderLen() + wLen;
    try {
        pcWholeMsg = new CHAR[wAllLen];
		memset(pcWholeMsg, 0, wAllLen);
    }
    catch (std::bad_alloc) {
		delete [] pcWholeMsg;
		pcWholeMsg = NULL;

        return NULL;
    }
    //Fill the MainHeader of the Msg Data, 
    TMainHeader* ptsm = ( TMainHeader* )pcWholeMsg;
    //TSingleMessage* ptsm_all = ( TSingleMessage* )pcWholeMsg;
    ptsm->wHeadFlag = PROTOCOLID;
    ptsm->byDstAddr = ptMainHdr->byDstAddr ;
    ptsm->byDstSysNo = ptMainHdr->byDstSysNo ;
    ptsm->bySrcAddr = 0;
    ptsm->bySrcSysNo = 0;
    ptsm->byVersionMain = MAINVERSION;
    ptsm->byVersionSub = SUBVERSION;
    ptsm->wReserve = 0x00;
    ptsm->wDatalen = wAllLen - wPL_GetMainHerderLen();
    
    //Fill the SubHeader of the Msg Data, 
    TSubHeader* ptSubH = &( (( TSingleMessage* )pcWholeMsg)->tsubHeader);
    if( NULL != ptSubHdr )
    {
        ptSubH->dwDatalen = ptSubHdr->dwDatalen ;
        ptSubH->dwMsgId = ptSubHdr->dwMsgId ;
        ptSubH->dwSubMsgId = ptSubHdr->dwSubMsgId ;
        ptSubH->wDesTaskId = ptSubHdr->wDesTaskId ;
        ptSubH->wSrcTaskId = ptSubHdr->wSrcTaskId ;
    }
    else
    {
        ptSubH->dwDatalen = 0x0000 ;
        ptSubH->dwMsgId =  0x0000 ;
        ptSubH->dwSubMsgId = 0x0000 ;
        ptSubH->wDesTaskId = 0x00 ;
        ptSubH->wSrcTaskId = 0x00 ;
    }

    //Add the real Msg Data here
    if( wLen > 0 )
    {
        pcMsgStart = pcWholeMsg + wPL_GetMainSubHerderLen();
        memcpy( (void *)pcMsgStart, (void *)pvMsgData, wLen );
        //ptsm->pvMsgData = pcMsgStart;
    }
    else 
    {
    }

    //Revert Big endian to Little endian 
    TSingleMessage* ptRetMsg = NULL;
    ptRetMsg = (TSingleMessage*) pcWholeMsg;
    ptRetMsg->tmainHeader.wHeadFlag = htons(ptRetMsg->tmainHeader.wHeadFlag);
    ptRetMsg->tmainHeader.wReserve = htons(ptRetMsg->tmainHeader.wReserve);
    ptRetMsg->tmainHeader.wDatalen = htons(ptRetMsg->tmainHeader.wDatalen);

    ptRetMsg->tsubHeader.wDesTaskId = htons(ptRetMsg->tsubHeader.wDesTaskId);
    ptRetMsg->tsubHeader.wSrcTaskId = htons(ptRetMsg->tsubHeader.wSrcTaskId);
    ptRetMsg->tsubHeader.dwMsgId = htonl(ptRetMsg->tsubHeader.dwMsgId);
    ptRetMsg->tsubHeader.dwSubMsgId = htonl(ptRetMsg->tsubHeader.dwSubMsgId);
    ptRetMsg->tsubHeader.dwDatalen = htonl(ptRetMsg->tsubHeader.dwDatalen);

    return pcWholeMsg;
}

BOOL CMessageMgr::bPL_IsCorrectHeader(const char* pcheader)
{
    TMainHeader * TMsg = (TMainHeader *)pcheader;
    if( PROTOCOLID != TMsg->wHeadFlag )
    {
        return false;
    }
    else if ( 0 > TMsg->wDatalen )
    {
        return false;
    }
    // Add more Judgements below if needed.
    
    return true;
}

BOOL CMessageMgr::bPL_IsRcvdMainHeaderCorrect(const char* pcMainheader)
{
    if(NULL == pcMainheader) return false;

    WORD wLen = wPL_GetMainHerderLen();
    char * ctmp = new CHAR[wLen];
	memset(ctmp, 0, wLen);
    memcpy(ctmp, pcMainheader, wLen);
    TMainHeader* ptmainHeader = (TMainHeader*) ctmp;

    ptmainHeader->wHeadFlag = ntohs(ptmainHeader->wHeadFlag);
    ptmainHeader->wReserve = ntohs(ptmainHeader->wReserve );
    ptmainHeader->wDatalen = ntohs(ptmainHeader->wDatalen);

    if( PROTOCOLID != ptmainHeader->wHeadFlag )
    {
        delete [] ctmp;
		ctmp = NULL;

        return false;
    }
    else if ( 0 > ptmainHeader->wDatalen )
    {
        delete [] ctmp;
		ctmp = NULL;

        return false;
    }

    // Add more Judgements below if needed.
    delete [] ctmp;
	ctmp = NULL;

    return true;

}

TSingleMessage* CMessageMgr::ptPL_CheckRegHeaderofRecMsg(void * pvMsg)
{
    //Revert Big endian to Little endian 
    TSingleMessage* ptRetMsg = NULL;
    ptRetMsg = (TSingleMessage*) pvMsg;
    ptRetMsg->tmainHeader.wHeadFlag = ntohs(ptRetMsg->tmainHeader.wHeadFlag);
    ptRetMsg->tmainHeader.wReserve = ntohs(ptRetMsg->tmainHeader.wReserve);
    ptRetMsg->tmainHeader.wDatalen = ntohs(ptRetMsg->tmainHeader.wDatalen);

    ptRetMsg->tsubHeader.wDesTaskId = ntohs(ptRetMsg->tsubHeader.wDesTaskId);
    ptRetMsg->tsubHeader.wSrcTaskId = ntohs(ptRetMsg->tsubHeader.wSrcTaskId);
    ptRetMsg->tsubHeader.dwMsgId = ntohl(ptRetMsg->tsubHeader.dwMsgId);
    ptRetMsg->tsubHeader.dwSubMsgId = ntohl(ptRetMsg->tsubHeader.dwSubMsgId);
    ptRetMsg->tsubHeader.dwDatalen = ntohl(ptRetMsg->tsubHeader.dwDatalen);

    //You may add extra codes to Do some Conversion from Recieved data.

    //Check Header's validation
    if( !bPL_IsCorrectHeader((char*)ptRetMsg) )
    {
        //bPL_deleteMsg((void*)ptRetMsg)
        return NULL;
    }
    else
    {
        return ptRetMsg;
    }
}

void CMessageMgr::BuildMainSubHeaderofMsg(void * pOutputMsg, 
										  void * pInputMsg, int nHeaderFlag)
{
	if( ( NULL == pOutputMsg ) || ( NULL == pInputMsg ) ) return;

	if( MAIN_HEADER == nHeaderFlag )
	{
		TMainHeader *ptRetMainHeader = (TMainHeader *)pOutputMsg;
		TMainHeader *ptInMainHeader = (TMainHeader *)pInputMsg;

		ptRetMainHeader->wHeadFlag = ptInMainHeader->wHeadFlag;
		ptRetMainHeader->byDstAddr = ptInMainHeader->byDstAddr ;
		ptRetMainHeader->byDstSysNo = ptInMainHeader->byDstSysNo ;
		ptRetMainHeader->bySrcAddr = ptInMainHeader->bySrcAddr;
		ptRetMainHeader->bySrcSysNo = ptInMainHeader->bySrcSysNo;
		ptRetMainHeader->byVersionMain = ptInMainHeader->byVersionMain;
		ptRetMainHeader->byVersionSub = ptInMainHeader->byVersionSub;
		ptRetMainHeader->wReserve = ptInMainHeader->wReserve;
		ptRetMainHeader->wDatalen = ptInMainHeader->wDatalen;
	}
	else if( SUB_HEADER == nHeaderFlag )
	{
		TSubHeader *ptRetSubHeader = (TSubHeader *)pOutputMsg;
		TSubHeader *ptInSubHeader = (TSubHeader *)pInputMsg;

		ptRetSubHeader->wDesTaskId = ptInSubHeader->wDesTaskId;
		ptRetSubHeader->wSrcTaskId = ptInSubHeader->wSrcTaskId;
		ptRetSubHeader->dwMsgId = ptInSubHeader->dwMsgId;
		ptRetSubHeader->dwSubMsgId = ptInSubHeader->dwSubMsgId;
		ptRetSubHeader->dwDatalen = ptInSubHeader->dwDatalen;
	}
	else {}
}
////////////////////////////////////////////////////////////////////////////