/** * @file PacketBuild.h * @brief 组包模块头文件 * Copyright(c) 2007,上海第九城市游戏研发部 * All rights reserved * 文件名称: PacketBuild.h * 摘 要: 根据通信协议(类型,命令字,协议结构)进行组包 * 作 者: dzj * 完成日期: 2007.11.30 * */ #pragma once #include "CliProtocol_T.h" static const unsigned char SELF_PROTO_TYPE = 0x00;//自身为客户端,定义见srvProtocol.h; static const int PKGBUILD_BUF_SIZE = 512;//不要随意改动此值,因为底层网络模块的缓冲也有限制,只改动这一个值可能导致底层错误; /** 组包类,将待发信息加上包头 注意:应在单线程中使用,并且每次新组包会覆盖旧包,因此每次的组包都应即时发送出去; */ class CPacketBuild { public: static MUX_PROTO::CliProtocol m_clipro; template < typename T_Msg > static bool CreatePkg( T_Msg* pPkg, char** pOutPkg, int& nOutLen ) { // 使用协议工具2008.7.15 if ( pPkg->wCmd != T_Msg::wCmd ) { nOutLen = 0; *pOutPkg = NULL; return false; } if (sizeof(T_Msg) > (PKGBUILD_BUF_SIZE - 5)) { //D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } int iEnLen = (int)m_clipro.EnCode(pPkg->wCmd, pPkg, &(m_InnerBuf[5]), sizeof(m_InnerBuf) - 5); if(iEnLen == -1) { //D_ERROR( "CPacketBuild::CreatePkg,EnCode失败,包类型%x", T_Msg::wCmd ); nOutLen = 0; *pOutPkg = NULL; return false; } unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; unsigned short wPkgLen = iEnLen + 5; memcpy( &(m_InnerBuf[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(m_InnerBuf[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(m_InnerBuf[3]), &wCmd, 2 );//命令字:wCmd; nOutLen = (int)wPkgLen; *pOutPkg = (char*)m_InnerBuf; return true; }; private: static char m_InnerBuf[PKGBUILD_BUF_SIZE]; };