RakNet学习(13) -- Recieving Packets

本文介绍如何接收和处理网络数据包,包括确定数据包类型、直接处理结构体数据和位流数据的方法。文中提供了具体的代码示例,展示了如何利用数据包处理函数进行数据解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接收数据包

当一个数据包到来时,例如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)释放数据包。

电动汽车数据集:2025年3K+记录 真实电动汽车数据:特斯拉、宝马、日产车型,含2025年电池规格和销售数据 关于数据集 电动汽车数据集 这个合成数据集包含许多品牌和年份的电动汽车和插电式车型的记录,捕捉技术规格、性能、定价、制造来源、销售和安全相关属性。每一行代表由vehicle_ID标识的唯一车辆列表。 关键特性 覆盖范围:全球制造商和车型组合,包括纯电动汽车和插电式混合动力汽车。 范围:电池化学成分、容量、续航里程、充电标准和速度、价格、产地、自主水平、排放、安全等级、销售和保修。 时间跨度:模型跨度多年(包括传统和即将推出的)。 数据质量说明: 某些行可能缺少某些字段(空白)。 几个分类字段包含不同的、特定于供应商的值(例如,Charging_Type、Battery_Type)。 各列中的单位混合在一起;注意kWh、km、hr、USD、g/km和额定值。 列 列类型描述示例 Vehicle_ID整数每个车辆记录的唯一标识符。1 制造商分类汽车品牌或OEM。特斯拉 型号类别特定型号名称/变体。型号Y 与记录关联的年份整数模型。2024 电池_类型分类使用的电池化学/技术。磷酸铁锂 Battery_Capacity_kWh浮充电池标称容量,单位为千瓦时。75.0 Range_km整数表示充满电后的行驶里程(公里)。505 充电类型主要充电接口或功能。CCS、NACS、CHAdeMO、DCFC、V2G、V2H、V2L Charge_Time_hr浮动充电的大致时间(小时),上下文因充电方法而异。7.5 价格_USD浮动参考车辆价格(美元).85000.00 颜色类别主要外观颜色或饰面。午夜黑 制造国_制造类别车辆制造/组装的国家。美国 Autonomous_Level浮点自动化能力级别(例如0-5),可能包括子级别的小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值