2011-05-21 74 views
5

我想通过网络发送一些双精度浮点数。 (标准C,标准套接字)没有htond或ntohd将数据转换为网络字节顺序和从网络字节顺序转换数据。我该怎么办?我有一些解决方案,但我想知道常用的做法。主机到网络双重?

(我也想知道什么是发送64位整数,就像使用的GStreamer值gint64常见的做法)

编辑: 这是一个解决方案,我想到的。我认为它适用于任何大小的整数,但对于双打是否正确?

void swap_if_necessary (void* buff, int buff_len) 
{ 
    uint32_t foo = 1; 
    if (htonl(foo) != foo) 
    { 
     char* to_swap = (char*)buff; 

     int i; 
     for (i = 0; i < buff_len/2; i++) 
     { 
      char swap_buff = to_swap[i]; 
      to_swap[i] = to_swap[buff_len -1 -i]; 
      to_swap[buff_len -1 -i] = swap_buff; 
     } 
    } 
} 
+0

[此节在维基百科](http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness)很好地解释了这种情况。 – hammar 2011-05-21 20:34:30

+1

难道你只是发送像所有其他整数一样的64位整数大端?这将如何与其他整数不同? – 2011-05-21 21:11:57

+0

问题是我应该把它转换成大端序列,还是有一些库为我做。标准的bsd套接字只有32位和16位整数的功能。 – 2011-05-21 21:16:44

回答

5

安德烈在说什么,因为不同计算机体系结构之间的差异,二进制浮点数在整个网络中是不可信的。超出字节顺序的差异(大/小端)。因此,如果您的数据有可能由不同的计算机体系结构处理,那么转换为字符串或使用XDR等库是非常必要的。

整数和字符的简单格式可以通过刚才的endian调整来滑过,但浮点变得更加复杂。

+1

我想我会做我自己的字节交换,我在我的问题编辑中添加的一个,但在64位整数,而不是双打。说实话,64位整数对我来说已经足够了。我想发送一些我从gstreamer中获取的与时间有关的信息。它将时间间隔存储为64位整数中的毫秒数。我只是将它们转换为我自己的“满意”,因为我习惯于NSTimeinterval,这是一个时间间隔,存储为Apple(iOS和OSX)C和ObjectiveC框架中使用的秒数(双浮点)。 – 2011-05-21 22:02:34

4

你可能想看看这是首次在rfc1014定义XDR。显然,你想找到一个为你的平台实现XDR的库。

10

将其转换为商定的字符串格式并发送。不知道这是常见的做法,还是体面的,但它对我来说很有用(当时我并不关心性能,因为我没有发送很多值)。

+0

+1,因为序列化通常更可靠。 – 2011-05-21 20:35:23

+2

实际上这是很常见的做法。浮点格式的变化太多了。从IEEE转换到IEEE将会像使用'strtod'一样昂贵。如果您想发送大量数据并想要便宜的转换(声音,在实时3D游戏中的位置......),请考虑发送定点数字。 – 2011-05-21 21:59:42

+0

我已经使用'sprintf(...,“%。* e”,DBL_DECIMAL_DIG -1,x)'来唯一地转换'double',(除了有载荷的NaN)。 'sprintf(...,“%a”,x)'也很好。 – chux 2015-03-25 17:29:38