介于要设计游戏服务器和客户端逻辑,现在需要普及一下我在代码中用到的一些数据结构,这一篇讲一下字节流--- ByteStream。
字节流就是自己实现的一个数据存储区,可对基础数据和其他特定数据进行序列化和反序列化。用与玩家数据或者其他服务器数据的落地保存。也可用于客户端和服务器,、服务器和服务器之间的通信。里面也添加了对字节顺序的处理逻辑。如果是通信的数据包可以启动字节顺序转换。
需要注意的一点是我对输入的每一个元素只拷贝元素内容,没有存储其类型,所以在字节流输出的时候没有办法做类型校验,这样对于结构经常变化的数据集合不是很友好,所以如果在通信层面用的话,对于不是经常变化结构的数据集合使用这种方法好于protobuf, 对于经常变化的数据集合可以使用protobuf, 但是我的服务器实现里面是模块化封装,底层的数据结构不会发生改变,所有会用ByteStream, 而 protobuf 会给上层业务层面使用。
贴一下代码:
1:字节顺序代码:
// 字节顺序转换
#ifndef EndianConverter_h__
#define EndianConverter_h__
#include <vector>
namespace SCore
{
// 未知
#define ENDAIN_UNKNOW 0
// 大端 (网络字节顺序)
#define ENDIAN_BIG 1
// 小端 (本地字节顺序)
#define ENDIAN_LITTLE 2
// 每一个包含头文件的cpp 都会生成 endian_struct ,目前只有一个文件包含
static union endian_struct
{
char buf[sizeof(int)];
int i;
} g_endian_t = { {(char)ENDIAN_LITTLE , (char)3, (char)5, (char)ENDIAN_BIG } };
// 本机字节顺序
#define LOCAL_ENDIAN (g_endian_t.i & 0xff)
// 字节顺序反转
template<int N> void EndianReverse(char* value)
{
if (value == (char*)0 || N <= 1)
return;
for (int i = 0; i < N / 2; ++i)
{
std::swap(value[i], value[N - i - 1]);
}
}
// 字节顺序转换
template<typename T> void EndianConverter(T* value)
{
EndianReverse<sizeof(T)>((char*)value);
}
// 网络字节顺序转换成本机字节顺序
template<typename T> void NetEndianToLocal(T* value)
{
if (ENDIAN_BIG == LOCAL_ENDI