/** 组包 by dzj, 09.06.16 */ #pragma once #include "../buflog.h" #include "../newcache.h" #include "../apppoolobjs.h" struct NewMsgToPut { public: static const unsigned int MAX_MSG_SIZE = 512; public: PoolFlagDefine(){ return; };//池对象需要; #ifdef USE_CRYPT char msgBuf[MAX_MSG_SIZE+sizeof(unsigned short)/*加密包长*/+sizeof(unsigned int)/*包序号*/]; #else //USE_CRYPT char msgBuf[MAX_MSG_SIZE]; #endif //USE_CRYPT int msgLen; unsigned short msgCmd;//消息命令字,收包时使用; unsigned int timeInfo;//时间信息; }; class CNewPkgBuild { public: #ifdef USE_CRYPT //创建空出了头四个字节以便在加密情形下存放包序号的待发包,同时直接使用本地缓存,因为底层要使用另外的,在内部拷贝发送缓存并加密的新发送函数; template < typename T_Msg > static bool CreatePkgWithSeqID( T_Msg* pPkg, char*& outPkg, unsigned short& outLen ) { if ( pPkg->wCmd != T_Msg::wCmd ) { NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkgWithSeqID,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return false; } if (sizeof(T_Msg) > (NewMsgToPut::MAX_MSG_SIZE - 5)) { NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkgWithSeqID,欲发包的包长超过了NewMsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return false; } int iEnLen = m_clipro.EnCode( (int)pPkg->wCmd, pPkg, &(m_sendBuf[sizeof(unsigned int)/*包序号*/+5/*包长+byPkgType+wCmd*/]), sizeof(m_sendBuf)-sizeof(unsigned int)-5 ); if ( ( iEnLen < 0 ) || (iEnLen > (int)(sizeof(m_sendBuf)-sizeof(unsigned int)-5) ) ) { NewLog( LOG_LEV_ERROR, "组包失败,CNewPkgBuild::CreatePkgWithSeqID,包类型:%x", T_Msg::wCmd ); return false; } outLen = iEnLen + 5;//正常内容+一般包头(包长+包类型+命令字); unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(m_sendBuf[sizeof(unsigned int)/*预留的包序号位置*/+0]), &outLen, 2 );//明文包中的包长不包括包序号的长度,包长:wPkgLen; outLen += sizeof(unsigned int);/*本函数输出内容长度要+包序号长度*/ memcpy( &(m_sendBuf[sizeof(unsigned int)/*预留的包序号位置*/+2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(m_sendBuf[sizeof(unsigned int)/*预留的包序号位置*/+3]), &wCmd, 2 );//命令字:wCmd; outPkg = m_sendBuf; return true; }; #endif //USE_CRYPT template < typename T_Msg > static NewMsgToPut* CreatePkg( T_Msg* pPkg ) { if ( pPkg->wCmd != T_Msg::wCmd ) { NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (NewMsgToPut::MAX_MSG_SIZE - 5)) { NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkg,欲发包的包长超过了NewMsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写NewMsgToPut NewMsgToPut* pMsg = g_MsgToPutPool->DsRetrieve( MsgToPutNO ); if ( NULL == pMsg ) { NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkg,取不到NewMsgToPut,内存分配失败, 包类型:%x", T_Msg::wCmd ); return NULL; } //NewLog( LOG_LEV_DEBUG, "CNewPkgBuild::CreatePkg,取NewMsgToPut成功" ); unsigned short wPkgLen = 0; int iEnLen = m_clipro.EnCode( (int)pPkg->wCmd, pPkg, &pMsg->msgBuf[5], (int)(sizeof(pMsg->msgBuf) - 5) ); if ( ( iEnLen < 0 ) || (iEnLen > (int)(sizeof(pMsg->msgBuf)-5) ) ) { g_MsgToPutPool->DsRelease( MsgToPutNO, pMsg ); NewLog( LOG_LEV_ERROR, "组包失败,CNewPkgBuild::CreatePkg,包类型:%x", T_Msg::wCmd ); return NULL; } //memcpy( &(pMsg->msgBuf[5]), pPkg, sizeof(*pPkg) ); wPkgLen = iEnLen + 5; pMsg->msgLen = wPkgLen; pMsg->msgCmd = pPkg->wCmd;//实际发包时并不使用此字段,为了与收包对应,因此加上; pMsg->timeInfo = 0;//与msgCmd一样,实际发包时并不使用此字段,为了与收包对应,因此加上; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->msgBuf[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->msgBuf[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->msgBuf[3]), &wCmd, 2 );//命令字:wCmd; return pMsg; }; private: static MUX_PROTO::CliProtocol m_clipro; #ifdef USE_CRYPT static char m_sendBuf[NewMsgToPut::MAX_MSG_SIZE+sizeof(unsigned int)];//此处只需多存一个包序号而不需要存加密包长度 #endif //USE_CRYPT }; //class CNewPkgBuild //{ //public: // template < typename T_Msg > // static NewMsgToPut* CreatePkg( T_Msg* pPkg ) // { // if ( pPkg->wCmd != T_Msg::wCmd ) // { // NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); // return NULL; // } // // if (sizeof(T_Msg) > (NewMsgToPut::MAX_MSG_SIZE - 5)) // { // NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkg,欲发包的包长超过了NewMsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); // return NULL; // } // // // 填写NewMsgToPut // NewMsgToPut* pMsg = g_MsgToPutPool->DsRetrieve( MsgToPutNO ); // if ( NULL == pMsg ) // { // NewLog( LOG_LEV_ERROR, "CNewPkgBuild::CreatePkg,取不到NewMsgToPut,内存分配失败, 包类型:%x", T_Msg::wCmd ); // return NULL; // } // //NewLog( LOG_LEV_DEBUG, "CNewPkgBuild::CreatePkg,取NewMsgToPut成功" ); // // unsigned short wPkgLen = 0; // int iEnLen = m_clipro.EnCode( (int)pPkg->wCmd, pPkg, &pMsg->msgBuf[5], (int)(sizeof(pMsg->msgBuf) - 5) ); // if ( ( iEnLen < 0 ) // || (iEnLen > (int)(sizeof(pMsg->msgBuf)-5) ) // ) // { // g_MsgToPutPool->DsRelease( MsgToPutNO, pMsg ); // NewLog( LOG_LEV_ERROR, "组包失败,CNewPkgBuild::CreatePkg,包类型:%x", T_Msg::wCmd ); // return NULL; // } // //memcpy( &(pMsg->msgBuf[5]), pPkg, sizeof(*pPkg) ); // wPkgLen = iEnLen + 5; // // pMsg->msgLen = wPkgLen; // pMsg->msgCmd = pPkg->wCmd;//实际发包时并不使用此字段,为了与收包对应,因此加上; // // unsigned char byPkgType = 0; // unsigned short wCmd = pPkg->wCmd; // // memcpy( &(pMsg->msgBuf[0]), &wPkgLen, 2 );//包长:wPkgLen; // memcpy( &(pMsg->msgBuf[2]), &byPkgType, 1 );//包类型:byPkgType; // memcpy( &(pMsg->msgBuf[3]), &wCmd, 2 );//命令字:wCmd; // // return pMsg; // }; // //private: // static MUX_PROTO::CliProtocol m_clipro; //};