【问题标题】:endianness influence in C++ codeC++ 代码中的字节序影响
【发布时间】:2018-02-10 15:02:40
【问题描述】:

我知道这可能是一个愚蠢的问题,但我是一名 C++ 开发新手,我需要对字节序进行一些说明。

我必须实现一个依赖于 SCTP 协议的通信接口,以便在两台不同的机器(一台基于 ARM,另一台基于 Intel)之间进行通信。

我们的目标是:

  1. 将消息编码为要在套接字上发送的字节流(我使用了一个 uint8_t 向量,并定位了不同字段的每个字节 - 将 uint16/32/64 拆分为单个字节 - 遵循 big-endian约定)
  2. 通过套接字将字节流发送到接收器(使用stcp)
  3. 检索流并对其进行解析,以便用正确的元素(由标头 + TV 信息元素表示)填充消息对象

我对使用接口的两台机器的底层架构的字节顺序可能存在问题感到困惑。 我认为将对象拆分为单个字节并使用大端序定位它们可以排除在到达时流的表示方式不同,对吧?还是我错过了什么?

另外,我对C++表示多字节变量的作用存有疑问,例如:

uint16_t var=0x0123;

//low byte 0x23 
uint8_t low = (uint8_t)var;

//hi byte 0x01
uint8_t hi = (uint8_t)(var >> 8);

这段代码是否依赖字节序?即如果我在大端机器上工作,我想上面的代码是可以的,但如果是小端,我会以不同的顺序获取字节吗?

我已经搜索过这样的问题,但没有人给我明确的答复,所以我对此仍有疑问。

提前谢谢大家,祝你有美好的一天!

【问题讨论】:

  • reinterpret_cast<uint8_t*>(&var)[0] 会因字节顺序而异。
  • 您可以reinterpret_cast<uint8_t&>var 避免冗长和混乱的语法。
  • 现在我想起来了,uint8_t 不一定是 unsigned char 的 typedef,所以将 uint16_t 的一部分重新解释为 uint8_t 实际上是未定义的。
  • @patatahooligan:如果您发送消息,则缺少括号。 [0] 主要是一个占位符,因为 [1] 也会以同样有问题的方式使用。
  • 确实对于迂腐的 UB 部分。

标签: c++ sockets endianness


【解决方案1】:

这段代码是否依赖字节序?

不,代码不依赖于目标机器的字节序。按位运算的工作方式与例如数学运算符可以。

它们独立于数字的内部表示。


虽然如果您通过网络交换数据,您需要在双方都知道一个已定义的字节顺序。通常这是网络字节顺序(即大端)。

htonx() ntohx() 系列的功能将帮助您正确且透明地对(多字节)数字进行编码/解码。

【讨论】:

  • 好的,谢谢。流部分呢?事实上,我以大端格式手动放置单个字节,然后通过套接字发送它们,知道大端顺序的检索和解码应该没问题,对吧?
  • 抱歉,我在发表评论后才看到您的编辑 :) 谢谢,我一定会检查这些方法!
  • "在某些实现中,这些函数被定义为宏。"很遗憾,一些库维护者在创建函数时不理解他们的意图
  • @UkMonkey,在自然实现的平台上反对#define htonl(x) (x) 有真正的理由吗?现在,如果您要将它们实现为多次扩展其参数的宏,那么那个将是无能的。
  • @TobySpeight 2 突然想到... 1. std::string blah; htonl(blah) 2. 命名空间自定义 { char htonl(char*) {...}} 开发人员不太可能将其组合在一起,但这并不意味着没问题。为什么他们不能只创建一个内联函数来返回 x?
【解决方案2】:

您提供的代码与字节序无关,并且可能是您的用例的正确方法。

依赖于对象内存布局的代码不起作用且不可移植:

// Don't do this!
uint16_t var=0x0123;
auto p = reinterpret_cast<char*>(&var);
uint8_t hi = p[0]; // 0x01 or 0x23 (probably!)
uint8_t lo = p[1]; // 0x23 or 0x01 (probably!)

(我在 cmets 中写了 probably 以表明这些可能是真实世界的值,而不是标准 C++ 指定的任何值)

【讨论】:

    猜你喜欢
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多