2011-05-21 112 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