c/c++语言开发共享从C访问网络数据包中未对齐数据的安全有效方法

我正在用ARM9处理器在C for Linux上编写程序。 该程序用于访问网络数据包,其中包括一系列标记数据,如:

 ... 

fieldID和length字段都是uint16_t。 数据可以是1个或更多字节(如果使用全长,则最多64k,但事实并非如此)。

只要具有偶数个字节,我就不会发现问题。 但是如果我有一个1或3或5字节部分,那么下一个16位fieldID最终不会出现在16位边界上,我预计会出现对齐问题。 已经有一段时间了,因为我从头做过这样的事情,所以我对细节不太了解。 任何反馈欢迎。 谢谢。

    为了避免在这种情况下出现对齐问题,请将所有数据作为unsigned char * 。 所以:

     unsigned char *p; //... uint16_t id = p[0] | (p[1] << 8); p += 2; 

    上面的示例假定为“little endian”数据布局,其中最低有效字节首先出现在多字节数字中。

    您应该具有函数(如果您使用的语言支持这些function,则为内联和/或模板化),这些函数将读取可能未对齐的数据并返回您感兴趣的数据类型。例如:

     uint16_t unaligned_uint16( void* p) { // this assumes big-endian values in data stream // (which is common, but not universal in network // communications) - this may or may not be // appropriate in your case unsigned char* pByte = (unsigned char*) p; uint16_t val = (pByte[0] << 8) | pByte[1]; return val; } 

    简单的方法是以速度为代价手动重建uint16_t ;

     uint8_t *packet = ...; uint16_t fieldID = (packet[0] << 8) | packet[1]; // assumes big-endian host order uint16_t length = (packet[2] << 8) | packet[2]; uint8_t *data = packet + 4; packet += 4 + length; 

    如果你的处理器支持它,你可以输入pun或者使用union(但要注意严格的别名 )。

     uint16_t fieldID = htons(*(uint16_t *)packet); uint16_t length = htons(*(uint16_t *)(packet + 2)); 

    请注意,并不总是支持未对齐访问(例如,它们可能会生成某种类型的错误),而在其他体系结构上,它们受到支持,但性能会受到影响。

    如果数据包未对齐,您可以始终将其复制到静态缓冲区中然后读取它:

     static char static_buffer[65540]; memcpy(static_buffer, packet, packet_size); // make sure packet_size <= 65540 uint16_t fieldId = htons(*(uint16_t *)static_buffer); uint16_t length = htons(*(uint16_t *)(static_buffer + 2)); 

    就个人而言,我只是选择#1,因为它将是最便携的。

    如果你通过一个字节指针,对齐总是很好,虽然可能不是超级高效。

    抛开endian-ness的问题,你可以将’真实’字节指针存储到你想要/需要的任何正确对齐的内容中,你就可以了。

    (这是有效的,因为生成的代码将数据加载/存储为字节,这是对齐安全的。当生成的程序集有指令以错误对齐的方式加载和存储16/32/64位内存时,它们全部崩溃)。

      以上就是c/c++开发分享从C访问网络数据包中未对齐数据的安全有效方法相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560068.html

      (0)
      上一篇 2021年1月27日
      下一篇 2021年1月27日

      精彩推荐