RakNet学习(13) -- Recieving Packets
来源:互联网 发布:网络调查问卷 编辑:程序博客网 时间:2024/05/14 21:54
接收数据包
当一个数据包到来时,例如Receive返回一个非零,处理这个数据包需要三步:
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];
}
2. 处理数据
接收结构
如果你原始发送一个结构体,可以按照如下的方式转化出这个结构体:
if (GetPacketIdentifier(packet)==/* 在这里使用赋值的数据包标识符 */)
DoMyPacketHandler(packet);
// 可以将这个函数放到任何位置,在处理游戏的状态类中比较好
void DoMyPacketHandler(Packet *packet)
{
// 将数据转化为适合类型的结构体
MyStruct *s = (MyStruct *) packet->data;
assert(p->length == sizeof(MyStruct)); // 如果传输的是结构体这块这样处理比较好
if (p->length != sizeof(MyStruct))
return;
// 在这里调用函数处理结构体 MyStruct *s
}
使用注释:
1. 将数据包的数据转换为适合类型结构体的指针,这样可以避免复制数据造成的开销。然后在这种情况下,如果你修改了结构体中的任何数据,数据包中的数据也会被修改掉。当然了,这种情况不是我们想要看到的。作为一个服务器,在中继数据的时候要多加注意,因为中继数据会引起未知的Bugs。
2. 尽管assert不是特别必要,但是如果我们对标识符赋值错误了,assert对于发现bug非常有用。
3.在有人要发送一个大小或类型无效的数据包,使得服务器或客户端崩溃情况时,if语句就显得非常有用。在实践中,没有发生过这样的事情,虽然没有出现过也不能说明是安全的。
接收一个位流数据(BitStream)
如果你最初发送的是一个Bitstream,那就需要创建一个BitStream,按照我们的写入顺序来解析数据。使用数据和数据包的长度来创建一个BitStream。我们写入数据的时候,使用的是Write函数,那么就使用Read函数读取数据。如果前面使用的WriteCompressed函数,那读取数据就要使用ReadCompressed函数。如果我们条件性的写入任何数据,依据这个逻辑分支。在接下来的例子中给出了处理在Creating packets中的地雷的数据:
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(networkID); // 在结构体中这里是 NetworkID networkId
myBitStream.Read(systemAddress); // 在结构体中这里是SystemAddress systemAddress
}
3. 通过将数据包传递给RakPeerInterface实例的DeallocatePakcet(Packet *packet)释放数据包。
- RakNet学习(13) -- Recieving Packets
- 一日一点RakNet(14)--Recieving Packets
- RakNet学习(11) -- Creating Packets
- RakNet学习(12) -- Send Packets
- RakNet学习(18) -- Timestamping your packets
- 一日一点RakNet(13)--Send Packets
- RakNet学习(1)--RakNet
- 一日一点RakNet(12)--Creating Packets
- 一日一点RakNet(19)--Timestamping your packets
- RakNet学习
- RakNet学习(3) -- 介绍
- RakNet学习 (9) -- Startup
- RakNet学习(10) -- Connecting
- RakNet学习(14) -- SystemAddress
- RakNet学习(19) -- NetworkIDObject
- RakNet学习(20) -- Statistics
- RakNet(30)学习 -- Autopatcher
- RakNet学习(35) -- FileListTransfer
- 第十周项目一 程序的填充与阅读1
- PreTranslateMessage 、CWND & HWND & 控件ID之间的巧妙转换方法
- 课堂内容听得懂,敲不出代码怎么办?
- 2014年11月2日 平常的日子 伟大的决定
- 第五周及第六周工作表
- RakNet学习(13) -- Recieving Packets
- Sqlite数据库相关(一)SQLiteDatabase类
- hdu1066 Last non-zero Digit in N!
- 第10周项目2传纸条
- UML中的图
- form窗体切换 UltraTabbedMdiManager
- Android权限Uri.parse的详细资料
- RakNet学习(14) -- SystemAddress
- 第十周项目2 M$pszi$y是什么意思