#include "CliSession.h" #include "DataProc.h" #include "CircularBuf.h" #include "GSEGuard.h" #include "../Common/Util.h" #include "GSECommunication.h" #define MAX_DATA_SIZE 40960 CCliSession::CCliSession(CDataProc* pDataProc, GSECommunication* pCommucation) : m_CommunicationUsed(true), m_DataProc(pDataProc), m_Communication(pCommucation) { m_InBuf = GSEMemNew CCircularBuf(MAX_DATA_SIZE); m_OutBuf = GSEMemNew CCircularBuf(MAX_DATA_SIZE); m_bCanVerify = false; } CCliSession::~CCliSession(void) { GSEMemDelete m_InBuf; GSEMemDelete m_OutBuf; GSEGuard gseGuard(&m_SendQueLock); //删除未获得发送机会的数据 while (m_SendQue.size() > 0) { char* pData = m_SendQue.front(); GSEMemFree(pData); m_SendQue.pop_front(); } } bool CCliSession::OnErase() { return !m_CommunicationUsed; } int CCliSession::OnClose() { CCliSession* pCliSession = this; uint16 nPackLen = sizeof(MSGHEADER); char* pData = GSEMemAlloc(char, sizeof(MSGHEADER) + sizeof(pCliSession)); memset(pData, 0, sizeof(MSGHEADER) + sizeof(pCliSession)); PMSGHEADER pmsgHeader = reinterpret_cast(pData); pmsgHeader->PackCmd = CLOSEMSG::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nPackLen; memcpy(pData + pmsgHeader->PackLen, &pCliSession, sizeof(pCliSession)); m_DataProc->AddData(pData); m_CommunicationUsed = false; return 0; } int CCliSession::OnError(int nErrorCode) { CUtil::Msg("%s connection error %d\n", CliIp().c_str(), nErrorCode); OnClose(); return 0; } int CCliSession::OnRecv(char *pszData, int nLen) { m_LastRecvTime = time(NULL); m_InBuf->UpdateWrite(nLen); ParseData(); return 0; } int CCliSession::OnSend(char *pszData, int nLen) { m_OutBuf->UpdateRead(nLen); return 0; } int CCliSession::OnInitSend(char*& pszBuf, int& nLen) { { GSEGuard gseGuard(&m_SendQueLock); //把要发送的数据写入Out缓冲区中 while (m_SendQue.size() > 0) { char* pData = m_SendQue.front(); PMSGHEADER pmsgHeader = reinterpret_cast(pData); if (pmsgHeader->PackLen > m_OutBuf->GetFreeSize()) { break; } m_OutBuf->WriteData(pData, pmsgHeader->PackLen); GSEMemFree(pData); m_SendQue.pop_front(); } } //通知网络模块要发送的数据 pszBuf = m_OutBuf->GetReadPtr(); nLen = m_OutBuf->GetContiguousFreeSize(0); return 0; } int CCliSession::OnInitRecv(char*& pszBuf, int& nLen) { pszBuf = m_InBuf->GetWritePtr(); nLen = m_InBuf->GetContiguousFreeSize(1); return 0; } int CCliSession::ParseData() { while (m_InBuf->GetUsedSize() >= sizeof(MSGHEADER)) { MSGHEADER msgHeader; m_InBuf->SoftReadData((char*)&msgHeader, sizeof(MSGHEADER)); if (msgHeader.PackLen <= m_InBuf->GetUsedSize()) { CCliSession* pCliSession = this; char* pData = GSEMemAlloc(char, msgHeader.PackLen + sizeof(pCliSession)); memset(pData, 0, msgHeader.PackLen + sizeof(pCliSession)); m_InBuf->ReadData(pData, msgHeader.PackLen); //把CliSession对象指针也放进数据包中 memcpy(pData + msgHeader.PackLen, &pCliSession, sizeof(pCliSession)); m_DataProc->AddData(pData); } else { break; } } return 0; } void CCliSession::AddData(char* pData) { GSEGuard gseGuard(&m_SendQueLock); m_SendQue.push_back(pData); } int CCliSession::OnConnect() { m_LastRecvTime = time(NULL); CCliSession* pCliSession = this; uint16 nPackLen = sizeof(MSGHEADER); char* pData = GSEMemAlloc(char, sizeof(MSGHEADER) + sizeof(pCliSession)); memset(pData, 0, sizeof(MSGHEADER) + sizeof(pCliSession)); PMSGHEADER pmsgHeader = reinterpret_cast(pData); pmsgHeader->PackCmd = CONNMSG::wCmd; pmsgHeader->PackType = 0; pmsgHeader->PackLen = nPackLen; memcpy(pData + pmsgHeader->PackLen, &pCliSession, sizeof(pCliSession)); m_DataProc->AddData(pData); return 0; } void CCliSession::UnUsed() { m_CommunicationUsed = false; } bool CCliSession::OnReadMask() { return true; } bool CCliSession::OnWriteMask() { time_t ttCur = time(NULL); if((ttCur - m_LastRecvTime) > 60) { shutdown(m_Communication->GetSocket(), SD_SEND); m_LastRecvTime = ttCur; } GSEGuard gseGuard(&m_SendQueLock); return m_OutBuf->GetContiguousFreeSize(0) > 0 || m_SendQue.size() > 0; } void CCliSession::CanVerify(bool bVerify) { m_bCanVerify = bVerify; } bool CCliSession::CanVerify() { return m_bCanVerify; } void CCliSession::CliIp(string strIp) { m_CliIp = strIp; } string CCliSession::CliIp() { return m_CliIp; }