关闭

2D网络游戏开发(网络篇)(十一)

标签: 网络游戏网络游戏object数据结构服务器
1809人阅读 评论(0) 收藏 举报
2D网络游戏开发(网络篇)(十一)
 
作者:akinggw
 
前言
 
在前面的内容中,我们讲解了什么是比特流(bitstream),如何建立数据包,如何发送数据包。今天,我们将讲解如何接收数据包,把这三个内容翻译了,我们将来实际编写一下代码。看看这些东西到底有多重要。
 
接收数据包
 
当一个数据包从网络上传输过来。接收函数将返回不为0,在这里我们要分三步来处理这个接收过程。Multiplayer类将为你处理第一步和第三步,
 
1. 决定数据包的类型,这个数据包的类型可以由下面的代码返回:
 
unsigned char GetPacketIdentifier(Packet *p)
{
if((unsigned char)p->data[0]==ID_TIMESTAMP)
return (unsigned char) p->data[sizeof(unsigned char) + sizeof(unsigned long)];
else
return (unsigned char)p->data[0];
}
 
接收数据结构
 
如果你原来发送的是一个结构,你就可以像下面这样接收它:
 
//如果你不使用Multiplayer,这里就将交给ProcessUnhandledPacket处理
if(packetIdentifier==/*这里是已经分配给用户的数据包标识*/)
DoMyPacketHandler(packet);
 
//把这个函数放在你想放的任何地方,在状态类中处理游戏是一个好的地方
void DoMyPacketHandler(Packet *packet)
{
//将数据放在结构的适当类型当中
MyStruct *s=(MyStruct *) packet->data;
Assert(p->length==sizeof(MyStruct));
If(p->length!=sizeof(MyStruct))
Return;
 
//用NetworkIDGenerator和宏定义位置,然后得到一个指针指向标明结构的对象
MyObject *object =(MyObject *) GET_OBJECT_FORM_ID(s.objected);
//对于这个数据包的类型,执行一个功能
object->DoFunction();
}
 
有用的注释
 
l               我们将数据包中的数据指向结构的相应类型是为了避免空拷贝。这样做的话,不管怎样,如果我们改变了结构中任何的数据,那么也将同样改变数据包。这可能或也不可能是你想要的结果。小心保管服务器返回的信息,因为这可能引起一些不必要的麻烦。
l               那断言(assert),也并不一定是必须的,但是当我们发送数据包时,分配了错误的标识或者错误的长度的时候,它对于找到错误将是非常有用的。
l               但某些人为了攻击客户端或服务器,而发送一些包含错误长度和类型的数据包,在这种情况下,状态就显得特别的重要了。
 
2. 通过DeallocatePacket(Packet *packet)=0;函数删除数据包。
 
接收比特流
 
如果你寄出一个比特流,我们建立比特流去分析数据应该按照我们写数据相同的顺序。我们建立比特流,使用了数据和数据包的长度。我们然后在使用写(Write)函数之前使用读(Read)函数;在使用写压缩(WriteCompressed)之前使用读压缩(ReadCompressed),无论我们写何种数据都将按照上面给出的相同的逻辑分支。
下面,我们给出一个例子,这个例子使用了在建数据包时使用的结构Mine。这个例子的作用就是如何读出Mine结构中的数据。
 
Void DoMyPacketHandler(Packet *packet)
{
Bitstream myBitStream(packet->data,packet->length,false); //第三个参数false的作用是不允许我们拷贝传输过来的数据
MyBitStream.Read(useTimeStamp);
MyBitStream.Read(timestamp);
MyBitStream.Read(typeId);
Bool isAtZero;
MyBitStream.Read(isAtZero);
If(isAtZero==false)
{
 x=0.0f;
 y=0.0f;
 z=0.0f;
}
else
{
myBitStream.Read(x);
myBitStream.Read(y);
myBitStream.Read(z);
}
myBitStream.Read(objectId); // 在这个结构中,这是对象标识
myBitStream.Read(playerId); //在这个结构中, 这是玩家标识
}
 
关于更多内容请访问金桥科普网站( http://popul.jqcq.com  )游戏开发栏目,如你需要游戏开发方面的书籍请参考金桥书城游戏频道(http://book.jqcq.com/category/1_70_740.html )。如果你在阅读本篇文章时有什么好的建议请来信给我,我的E_mail: akinggw@126.com. 如果你在使用SDL时有什么问题,请到金桥科普网站(http://popul.jqcq.com  )游戏开发栏目,我将详细地为你解答。
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:44078次
    • 积分:664
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:0篇
    • 译文:0篇
    • 评论:7条
    文章分类
    最新评论