游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5360|回复: 8

返璞归真,网络传输——结构体还是序列化?

[复制链接]

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2008-2-17 13:04:00 | 显示全部楼层 |阅读模式
虽然,网络编程里面的数据传送推荐用序列化,但我不用,还是选择结构体(返璞归真),有以下几点理由:
1.跨平台问题:
  序列化确实可以很好的跨语言平台,可大多数网络游戏不需要跨语言平台

2.别以为有了序列化就不需要结构体
  表面上序列化代码量小,按顺序读和写char int short LPCSTR ... 就好,逻辑对象写不写都无所谓,那就是大错而特错了
  待序列化的对象发送前的结构还是不可省略的序列化的过程就是 object->(按一定顺序拆分)write->bytes->(按拆分顺序组装)read->object的过程
其实object还是不能省略,很多人写网络程序不注重逻辑对象结构,收到的一堆bytes按一定顺序读和写就完事了,这样虽然灵活,但缺乏结构,容易造成混乱,调试起来是灾难
   所以结构体(或类)还是省略不了的,所以:别以为有了序列化,就不需要结构体了。

3.结构体存在内存对齐和CPU不兼容的问题,可以避免
  的确结构体是有内存对齐的问题,存在兼容性问题,我可以选择pack(1)把内存对齐给关闭掉,避免兼容性问题,既然选择了iocp就不打算跨平台了,可以避免结构体平台兼容的问题

4.结构体调试起来方便很多,减少内存拷贝,效率高
  不用序列化可write和read的过程就不需要过多考虑(少写太多代码了),read write 就好像现代社会每个人每天都要穿衣服和脱衣服一样,原始社会需要吗?其实人类进化到原始裸奔状态才是最爽快的
  但还是要说句公道话:有人说序列化编码解码read write 需要耗费资源, 诚然这个过程基本等于赋值和内存拷贝,那点效率损失主要还在内存拷贝上,这点效率损失很小,不能作为序列化的缺点,当然如果涉及到数据加密那将是另外一个话题

5.结构体貌似呆板,发送数据限制多,发送变长数据就不方便,数据组织起来也不灵活
  我想这是很多人抛弃结构体,选择用序列化方式发送和接受数据的一个很重要的原因
  但:其实对于变长结构(子结构也是变长)的问题,用结构体来实现的确很麻烦,但并不代表不能实现
  我已经实现了,而且读和写变长子结构体嵌套任意多层都不成问题,可以存储复杂变长的数据结构,
  数据就如同能自动序列化一样方便,这个应该是技术难点,但细心去做是可以实现的

6.关于结构体指针
  游戏里面要发送的数据内存事先分配好的,不存在指针,深度复制更不用考虑,所以内存拷贝不会出错
  如果用到指针即使用序列化来实现也会面临同样的问题也占不了多少便宜,由于C++这们语言的特点,
  不象java那样有个标准实现,对于序列化本身没有一个统一的标准,所以可想而知,有人说:boost有它的序列化的实现
  其实那个实现不见得就合适你自己,如果真要做序列化,编码和解码的仿照那个过程自己写才最为牢靠,
  哪些指针对应的内存需要序列化那些不需要序列化,是个逻辑结构,需要自己说了算才好(好像扯远了点)
  说回游戏数据,既然不用需要他用到指针,结构体用来发送数据也没问题的

7 平台扩充问题
  退一万步的说:换了语言就基本上换了客户端,客户端的数据组织形式都要重写
  实在不行还可以考虑用xml json 编码等等一些跨平台的解决方案,现在所写的结构体是可以用来做数据接收的,只是发送的不再是结构体而已

8.综上所述
  如果需要跨语言平台,不用序列化(二进制流或xml, json文本等等)根本无法实现
  序列化的优点还是非常多的.如果主要是跨平台和语言自定义读写规则,根据需要读写对象的某一部分数据,
  空间浪费少,不存在内存对齐问题等诸多优点,缺点就是拐弯抹角,代码量大,调试不方便


权衡了良久
  数据如果能组织的合理,而且没有跨语言平台的要求,用结构体也未尝不可,毕竟数据发送直来直去还是方便些,减少内存拷贝,效率也高了很多
  特别是调试起来容易太多了,衡量利弊我还是放弃了序列化,选择了原始的结构体,只是难在数据的组织(好在基本已经克服了)

我知道:序列化很好很强大,很多网络程序高手根本不屑于用结构体,用这个就好象是旁门左道,狗肉上不了大雅之堂一样,狗肉还是很多人喜欢吃的嘛,:)。

我还是返璞归真选择了结构体

一句话:物尽其用,用的恰当,够用就好。

如果有什么不对,敬请拍砖,莫要客气

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2008-2-17 13:52:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

返璞归真的话,不如用字符串。 ;-)

唉,也许其实这个问题压根就不是很重要……

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
 楼主| 发表于 2008-2-17 14:32:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

也不是不重要,看了一些服务器的代码,两种实现的方式也都存在,各有利弊

8

主题

130

帖子

156

积分

注册会员

Rank: 2

积分
156
发表于 2008-2-20 09:52:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

我两个都用过,呵呵,而且都支持了,看具体情况吧!

0

主题

25

帖子

25

积分

注册会员

Rank: 2

积分
25
QQ
发表于 2008-3-3 16:43:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

struct structBase
{
virtual const BYTE* ToBytes() const=0;
virtual bool FromBytes(const BYTE* pBytes)=0;
};

0

主题

25

帖子

25

积分

注册会员

Rank: 2

积分
25
QQ
发表于 2008-3-3 16:48:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

struct structStruct:public structBase
{
virtual const BYTE* ToBytes() const{return this};
virtual bool FromBytes(const BYTE* pBytes){*this=(structStruct*)pBytes;}

int a;
int b;
};
struct structSample:public structBase
{
virtual const BYTE* ToBytes() const{返回组合数据};
virtual bool FromBytes(const BYTE* pBytes){解析组合数据}

int a;
LPCTSTR s;
};
这是我的一点想法,不知是否可行

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
 楼主| 发表于 2008-3-3 19:30:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

结构体里面不要使用virtual,这里面包含vtable,存在字节对齐的诸多问题。

这段时间,研究了前辈的一些代码,很有收获,我已经全面改造,自定义实现了对象的序列化的一套组件。完好支持基本数据类型,数组,用户自定义类型,STL容器里面的常见容器类型还衍生了一个keyedBuffer,基本足够用了。

这些使用起来确实方便,可是这样一来,相当于改变了通讯协议。
摆在面前的是大量的代码重构的工作。

唉。。。。硬着头皮已经重构大半了,而且改掉了以前很多不雅的地方。
现在服务器的通讯模块的程序组织结构看起来也合理了很多,不知道是不是因祸得福。

0

主题

2

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2008-3-7 00:35:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

做windows服务器的都TMD这种德行

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
 楼主| 发表于 2008-3-7 08:17:00 | 显示全部楼层

Re:返璞归真,网络传输——结构体还是序列化?

做windows服务器的怎么啦?
楼上这样的人也能配做IT,说话这么没教养,连最起码的素质都没有。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 09:32

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表