iOS设备上的字节顺序是否相同,这是否会使iOS设备之间不必使用htonl和ntohl?

时间:2013-11-21 07:22:21

标签: ios objective-c macos intel htonl

我正在阅读此example有关如何将NSData用于网络消息的信息。

创建NSData时,该示例使用:

unsigned int state = htonl(_state);
[data appendBytes:&state length:sizeof(state)];

当转换NSData时,该示例使用:

  [data getBytes:buffer range:NSMakeRange(offset, sizeof(unsigned int))];
  _state = ntohl((unsigned int)buffer);

在此示例中是否不必使用htonl和ntohl? - 由于数据在iOS设备上打包/解包,因此字节排序不一样,因此不必使用htonl和ntohl。 - 它的使用方式不正确吗?该示例使用htonl进行打包,使用ntohl进行解包。但实际上,如果有人知道发送者或接收者使用的是特定格式,那么不应该只这样做吗?

1 个答案:

答案 0 :(得分:3)

  

该示例使用htonl进行打包,使用ntohl进行解包。

这是对的。

当发送方通过网络传输数据(整数,浮点数)时,它应将它们重新排序为“网络字节顺序”。接收器通过从网络字节顺序重新排序到“主机字节顺序”来执行解码。

  

但实际上,如果有人知道发件人或收件人使用的是特定格式,那么不应该只这样做吗?

通常,发送方不知道接收方的字节顺序,反之亦然。因此,为了避免歧义,需要定义“网络”的字节顺序。如果发送方和接收方实际上正确地对网络进行编码/解码,这种方法很有效。

编辑:

如果您担心编码的性能:

在现代CPU上,字节交换所需的机器代码非常快。

在语言层面,编码和解码一系列字节的功能也可以非常快。但是,我们帖子中的Objective-C示例不属于那些“快速”例程。

例如,由于主机字节顺序在编译时是已知的,如果主机字节顺序等于网络字节顺序,ntohl变为“空”功能(也称为“NoOp”)。

其他字节交换实用程序函数在ntoh宏系列上扩展为64位,double和float值,可以使用C ++模板技巧,也可能成为“NoOp”函数。

然后可以完全进一步优化这些“空”函数,这有效地导致机器代码只执行从源缓冲区到目标缓冲区的move

但是,由于字节交换的额外开销非常小,因此在不需要交换的情况下,这些优化只能在高性能代码中被察觉。但是你的第一个声明:

[data getBytes:buffer range:NSMakeRange(offset, sizeof(unsigned int))];

比以下声明贵很多

_state = ntohl((unsigned int)buffer);

即使需要字节交换。