如何从网络管理双重的结束

我对这个问题的答案有一个大问题。 在c ++中交换双位的比特

然而,这个问题或多或少都是我搜索的:我从网络上收到一个双,我想在我的机器上正确编码。

在我收到int的情况下,我使用ntohl执行此代码:

 int * piData = reinterpret_cast((void*)pData); //manage endianness of incomming network data unsigned long ulValue = ntohl(*piData); int iValue = static_cast(ulValue); 

但是在我得到double的情况下,我不知道该怎么做。

该问题的答案建议:

 template  void swap_endian(T& pX) { char& raw = reinterpret_cast(pX); std::reverse(&raw, &raw + sizeof(T)); } 

但是,如果我引用此网站 :

The ntohl() function converts the unsigned integer netlong from network byte order to host byte order. When the two byte orders are different, this means the endian-ness of the data will be changed. When the two byte orders are the same, the data will not be changed.

相反,@ GManNickG对这个问题的回答总是std::reverse 进行反演

考虑到这个答案是错误的,我错了吗? (在ntohl使用的endianess的网络管理范围内虽然在OP问题的标题中没有准确说明)。

最后:我应该将我的double分成4个字节的两个部分并在两个部分上应用ntohl函数吗? 还有更多的经典解决方案吗?

在C中还有这个有趣的问题, 主机到网络加倍? ,但它限制为32位值。 答案说,由于架构差异,双打应该转换为字符串……我也会使用音频样本,我是否真的考虑将所有样本转换为数据库中的字符串? (双打来自我通过网络查询的数据库)

如果你的双打是IEEE 754格式,你应该相对没问题。 现在你必须将它们的64位分成两个32位,然后以big-endian顺序传输它们(这是网络顺序);

怎么样:

 void send_double(double d) { long int i64 = *((reinterpret_cast)(&d)); /* Ugly, but works */ int hiword = htonl(static_cast(i64 >> 32)); send(hiword); int loword = htonl(static_cast(i64)); send(loword); } double recv_double() { int hiword = ntohl(recv_int()); int loword = ntohl(recv_int()); long int i64 = (((static_cast) hiword) << 32) | loword; return *((reinterpret_cast(&i64)); } 

假设您有一个编译时选项来确定字节顺序:

 #if BIG_ENDIAN template  void swap_endian(T& pX) { // Don't need to do anything here... } #else template  void swap_endian(T& pX) { char& raw = reinterpret_cast(pX); std::reverse(&raw, &raw + sizeof(T)); } #endif 

当然,另一种选择是不要在网络上发送double – 考虑到它不能保证与IEEE-754兼容 – 有些机器在那里使用其他浮点格式…例如使用一个字符串会起作用更好…

我无法让JohnKällén代码在我的机器上运行。 此外,将double转换为字节(8位,1个字符)可能更有用:

 template string to_byte_string(const T& v) { char* begin_ = reinterpret_cast(v); return string(begin_, begin_ + sizeof(T)); } template T from_byte_string(std::string& s) { assert(s.size() == sizeof(T) && "Wrong Type Cast"); return *(reinterpret_cast(&s[0])); } 

此代码也适用于使用POD类型的结构。

如果你真的想要双重作为两个整数

 double d; int* data = reinterpret_cast(&d); int first = data[0]; int second = data[1]; 

最后, long int并不总是64位整数(我必须使用long long int int在我的机器上创建64位int)。