• 协议


    协议结构体定义

    struct NetMsgHeader
    {
    NetMsgLenType BuffLen;	//buff的长度
    NetMsgMsgIdType MsgID;	//消息ID
    };
    //给客户端的消息
    struct tagNetMsg :public NetMsgHeader
    {
    void Serialize(Stream& stream)
    {
    stream.Write(BuffLen);
    stream.Write(MsgID);
    stream.WriteBuffer(buff, BuffLen);
    }
    bool DeSerialize(Stream& stream)
    {
    if (!stream.Read(BuffLen))
    return false;
    if (!stream.Read(MsgID))
    return false;
    if (!stream.ReadBuffer(buff, BuffLen))
    return false;
    return true;
    }

    协议注册

    //NetMsgHeader Header;
    char buff[enMaxMsgDataBufferSize];	//保证最大长度不会超过ServerMsg的buff
    /*
    * 格式化成字符串输出
    */
    void ToString(char* output,int outputsize);
    };
    
    typedef bool (*NetMsgProcProtoType)(tagNetMsg& msg);
    virtual void RegMsgFun(unsigned int msgID,NetMsgProcProtoType fun,bool isStaticLen,unsigned int DataLen)
    {
    	assert((msgID > GAME_MSG_BEGIN) && (msgID < GAME_MSG_ID_MAX));
    	NetMsgFunction& ele = GetFuncMap()[msgID];
    	ele.proc = fun;
    	ele.IsStaticDataLen = isStaticLen;
    	ele.DataLen = DataLen;
    	ele.MsgID = msgID;
    }
    RegMsgFun(GAME_MSG_HEART_BEAT, NetGate::ServicePlayerHeartBeat, false, 0);

    //协议解析

    1.Stream解析

    //strem类
    #pragma once
    #include <math.h>
    #include <assert.h>
    typedef unsigned int uint32;
    #ifdef WIN32
    #define max(a,b)            (((a) > (b)) ? (a) : (b))
    #endif
    #ifndef WIN32
    #include <limits>
    #endif
    #define Max(a,b)            (((a) > (b)) ? (a) : (b))
    #ifndef WIN32
    #pragma GCC push_options
    #pragma GCC optimize("O3")
    #endif
    class Stream
    {
    public:
    	Stream()
    	{
    	m_Pos = 0;
    	m_MaxBuffSize = 256;
    	m_pBuff = new char[m_MaxBuffSize];
    	m_bAttach = false;
    	}
    	Stream(uint32 Size)
    	{
    	m_Pos = 0;
    	m_MaxBuffSize = Size;
    	m_pBuff = new char[m_MaxBuffSize];
    	m_bAttach = false;
    	}
    	Stream(char* pBuff,uint32 Size)
    	{
    	m_Pos = 0;
    	m_MaxBuffSize = Size;
    	m_pBuff = pBuff;
    	m_bAttach = true;	
    	}
    	~Stream()
    	{
    	if(m_pBuff && !m_bAttach)
    	{
    	delete[] m_pBuff;
    	m_pBuff = 0;
    	}
    	}
    	void AttachBuffer(char* pBuff,uint32 nSize)
    	{
    	if(!pBuff && nSize == 0)
    	{
    	return;
    	}
    	if(m_pBuff && !m_bAttach)
    	{
    	delete[] m_pBuff;
    	m_pBuff = 0;
    	}
    	m_bAttach = true;
    	m_pBuff = pBuff;
    	m_Pos = 0;
    	m_MaxBuffSize = nSize;
    	}
    	uint32 GetBuffSize()
    	{
    	return m_MaxBuffSize;
    	}
    	uint32 GetPos()
    	{
    	return m_Pos;
    	}
    	void SetPos(uint32 pos)
    	{
    	m_Pos = pos;
    	}
    	void WriteBuffer(const char* pBuff,uint32 nSize)
    	{
    	if(m_Pos + nSize > m_MaxBuffSize)
    	{
    	if(m_bAttach == false)
    	{
    	Resize(m_MaxBuffSize + Max(nSize,m_MaxBuffSize / 2));
    	}
    	else
    	{
    	assert(false && "Attach上去的缓冲区已经超过大小");
    	return;
    	}
    	}
    	memcpy(m_pBuff + m_Pos, pBuff, nSize);
    	m_Pos += nSize;
    	}
    	bool ReadBuffer(char* pBuff,uint32 nSize)
    	{
    	if(m_Pos + nSize > m_MaxBuffSize)
    	{
    	return false;
    	}
    	else
    	{
    	assert((pBuff + nSize < m_pBuff) || (pBuff >= m_pBuff + m_MaxBuffSize));
    	memcpy(pBuff, m_pBuff + m_Pos, nSize);
    	m_Pos += nSize;
    	return true;
    	}
    	}
    	template<class T>
    	void Write( T& m_obj)
    	{
    	_write_data<T>(m_obj,0); 
    	}
    	template<class T,void (T::*)(Stream&) > 
    	struct s_write_fun;
    	template<class T> 
    	void _write_data( T& m_obj,s_write_fun<T,&T::Serialize>*)
    	{
    	m_obj.Serialize(*this); 
    	} 
    	template<class T> 
    	void _write_data( T& m_obj,...)
    	{ 
    	WriteBuffer((const char*)&m_obj,sizeof(m_obj));
    	}
    	template<class T,bool (T::*)(Stream&)>
    	struct s_read_fun;
    	template<class T>
    	bool _read_data(T& m_obj,s_read_fun<T,&T::DeSerialize>*)
    	{
    	return m_obj.DeSerialize(*this);
    	}
    	template<class T>
    	bool _read_data(T& m_obj,...)
    	{
    	if(m_MaxBuffSize >= m_Pos + sizeof(T))
    	{
    	//memcpy(&obj,m_pBuff + m_Pos,sizeof(T));
    	ReadBuffer((char*)&m_obj,sizeof(T));
    	return true;
    	}
    	else
    	{
    	return false;
    	}
    	}
    	template<class T>
    	bool Read(T& m_obj)
    	{
    	return _read_data<T>(m_obj,0); 
    	}
    	private:
    	char* m_pBuff;
    	uint32 m_MaxBuffSize;
    	uint32 m_Pos;
    	bool m_bAttach; 
    	void Resize(uint32 newSize)
    	{
    	if(newSize > m_MaxBuffSize)
    	{
    	char* pNewBuff = new char[newSize];
    	memcpy(pNewBuff,m_pBuff,m_Pos + 1);
    	delete[] m_pBuff;
    	m_pBuff = pNewBuff;
    	m_MaxBuffSize = newSize;
    	}
    	}
    };
    #ifndef WIN32
    #pragma GCC pop_options
    #endif

    消息结构体定义

    #pragma once
    #include "Stream.h"
    #define MAX_CHAT_DATA_SIZE 512
    #define MAX_EXTRA_DATA_SIZE 1024
    #pragma pack(push,1)
    //聊天消息类型
    enum enChatType
    {
    	enChatType_PRIVATE = 0,								// 私聊
    	enChatType_TEAM = 1,								// 队伍
    	enChatType_GUILD = 2,								// 帮派
    	enChatType_WORLD = 3,								// 世界	
    	enChatType_HORN = 4,								// 喇叭
    	enChatType_SYSTEM = 5,								// 系统
    	enChatType_CENTERS = 6,								// 中央屏幕
    	enChatType_FRIEND = 7,								// 好友聊天
    	enChatType_STRANGE = 8,								// 陌生人消息
    	enChatType_SCENCE = 9,								// 场景聊天
    	enChatType_CAMP = 10,								// 国家聊天
    	enChatType_RUMOUR = 11,								// 传闻(强化)
    	enChatType_TEAMCAMP = 12,							// 组队招募广播
    };
    struct MsgChat
    {
    	void Serialize(Stream& stream) 
    	{
    		stream.Write((char&) m_ChatType);
    		stream.Write((char&) m_HornType);
    		stream.Write(m_nRecverRoleID);
    		unsigned short nLen = (unsigned short)m_strChatData.GetRealStrLen();
    		stream.Write(nLen);
    		stream.WriteBuffer(m_strChatData.GetName(),nLen);
    		unsigned short nNameLen = (unsigned short)m_strRecverRoleName.GetRealStrLen();
    		stream.Write(nNameLen);
    		stream.WriteBuffer(m_strRecverRoleName.GetName(),nNameLen);
    	}
    
    	bool DeSerialize(Stream& stream)
    	{
    		char nCharType;
    		if (!stream.Read(nCharType))
    			return false;
    		m_ChatType = (enChatType)nCharType;
    
    		char HornType;
    		if (!stream.Read(HornType))
    			return false;
    		m_HornType = (enItemHornType)HornType;
    
    		if (!stream.Read(m_nRecverRoleID))
    			return false;
    
    		unsigned short nLen = 0;
    		if (!stream.Read(nLen))
    			return false;
    
    		if(nLen >= MAX_CHAT_DATA_SIZE - 1)
    		{
    			return false;
    		}
    
    		if (!stream.ReadBuffer(m_strChatData.GetName(), nLen))
    			return false;
    
    
    		if (!stream.Read(m_nExtraDataLen))
    			return false;
    
    		if(m_nExtraDataLen >= MAX_EXTRA_DATA_SIZE - 1)
    		{
    			return false;
    		}
    
    		if (!stream.ReadBuffer(m_ExtraData, m_nExtraDataLen))
    			return false;
    
    		unsigned short nNameLen = 0;
    		if (!stream.Read(nNameLen))
    			return false;
    
    		if(nNameLen >= MAX_ROLE_NAME_LEN - 1)
    		{
    			return false;
    		}
    
    		if (!stream.ReadBuffer(m_strRecverRoleName.GetName(), nNameLen))
    			return false;
    
    		return true;
    	}
    	MsgChat():
    	m_ChatType((enChatType)0),m_HornType((enItemHornType)0),m_nRecverRoleID((t_RoleID)0)
    	{
    		m_strChatData.SetName("");
    		m_strRecverRoleName.SetName("");
    	}
    	MsgChat(enChatType nChatType,enItemHornType nHornType,t_RoleID nRecverRoleID,CommonString<MAX_CHAT_DATA_SIZE> strChatData,CommonRoleName strRecverRoleName):
    	m_ChatType(nChatType),m_HornType(nHornType),m_nRecverRoleID(nRecverRoleID)
    	{
    		m_strChatData.SetName(strChatData.GetName());
    		m_strRecverRoleName.SetName(strRecverRoleName.GetName());
    		m_nExtraDataLen = 0;
    	}
    	enChatType			m_ChatType;
    	enItemHornType		m_HornType;		
    	t_RoleID			m_nRecverRoleID;
    	CommonString<MAX_CHAT_DATA_SIZE> m_strChatData;
    	TUint16		m_nExtraDataLen;
    	char		m_ExtraData[MAX_EXTRA_DATA_SIZE];
    	CommonRoleName		m_strRecverRoleName;
    };
    #pragma pack(pop)

    接收协议解析

    TBool NetGate::ServiceChat( tagNetMsg& msg,WorldPlayer* pWorldPlayer )
    {
     	MsgChat msgRecv;
     	Stream stream(msg.buff, msg.BuffLen);
    	if(stream.Read(msgRecv) == false)
    		return false;
    
    	enChatType MsgType = msgRecv.m_ChatType;
    	Tint32 nLenChat = msgRecv.m_strChatData.GetRealStrLen();
    }


    2.protobuf解析

    这个使用很简单,主要就是生成pb


  • 相关阅读:
    C++字符串(srtring)反转
    字典(Dictionary)
    畅通工程
    子串计算
    神奇的口袋
    SLT 优先队列 哈弗曼树最小带权路径
    大数阶乘
    整数拆分
    A+B (带有,的数字)
    Hdu 1232 畅通工程
  • 原文地址:https://www.cnblogs.com/byfei/p/14104405.html
Copyright © 2020-2023  润新知