利用__PRETTY_FUNCTION__宏实现服务器消息机制

游戏服务器总是会与客户端通信的,一般通信协议是自定义的,比如下面这种

消息基类 用大、小消息号标志

struct MsgBase
{
MsgBase(UINT8 t,UINT8 st)
{
t_ = t;
st_ = st;
}

UINT8 t_;
UINT8 st_;
};

某个特定的消息具有约定好的 大、小消息号,只要双方保持一致即可,比如

UINT8 MSG_LOGIN= 1;

UINT8 MSG_ACCOUNT_PASSWD = 1;
struct UserAccountMsg : public MsgBase
{
UserAccountMsg() : MsgBase(MSG_LOGIN,MSG_ACCOUNT_PASSWD)
{
bzero(account,sizeof(account));
bzeor(passwd,sizeof(passwd))
}

char account[33];
char passwd[33];
};


聪明的你一定发了问题,既然消息定义的类UserAccountMsg 是唯一的(不然编译器肯定报类型重定义的错)那干嘛还要什么大小消息号来标志呢,用类型名不就行了么。

这样做也是有问题的,字符串占的字节数比两个UINT8多很多啊,流量大大的浪费了。

那把字符串跟一个唯一ID绑定不就行了么,也省流量了,上面不就是这样做的么?

只不过上面是手动定义的形式,那有没有一个方法,能够自动把消息的类型名的字符串跟一个ID绑定呢?

把字符串跟ID绑定不是什么问题,生成一个唯一ID就够了,关键是怎么自动获取到消息类型的字符串表示呢?

c++里面是有一个宏可以获取到函数名,__function__,但是我们现在是要获取类型名呢?

想想,能不能通过函数名获取类型名呢?

想啊想。。。

类的构造函数名不是跟类型名是一样的么?哈哈

在类的构造函数里面使用__function__不就得到类型名了么,但是,你想在每个类里都手动加这么一句么。这也太挫了,咱程序员就是要偷懒的。

想想怎么自动完成吧。

那就只能在基类里面弄了,可是那样获取的是基类的类型名啊,不是子类的。

模板也可以把类型给传进来的。

template <typename T>
struct type_help_t
{
type_help_t()
{
name = __function__;
}
std::string name;
};
调用 type_help_t<UserAccountMsg>是不是可以呢?

发现不行,__function__不能获取到类型名,但是他的增强版__PRETTY_FUNCTION__倒是可以

他的调用结果是这么个形式

type_help_t<int> -> type_help_t<T>::type_help_t() [with T = int]
type_help_t<float> -> type_help_t<T>::type_help_t() [with T = float]
type_help_t<std::vector<int> > -> type_help_t<T>::type_help_t() [with T = std::vector<int, std::allocator<int> >]


接下来的事情,就是字符串截取了,这样就获得了类型名。

写个宏吧 TYPE_NAME(x) type_help_t<x>::getInstance()->getName()

服务器启动的时候,把所有消息类型名跟ID绑定,这样client消息到来的时候就可以正确的分发到响应函数了,而且有一个好处,消息的ID可以每次启动服务器的时候都不一样,这样可以一定程度的防外挂,或者可以每个client每次连接上来的时候动态生成消息类型名与ID的映射,然后发到client,再来通信。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值