2017-09-06 118 views
0

我無法理解「網絡字節順序」的概念。我已閱讀Network byte order and endianness issues,但仍不能。
現在我通過TCP套接字爲兩臺計算機之間的通信制定了正式的網絡協議描述。這裏是短語「...使用little-endian字節順序」。但標準的網絡字節順序是big-endian。我應該考慮網絡字節順序嗎?

是否應該考慮一個字節順序,如果在網絡兩邊的字節順序是完全定義的,而且我寫了,大致說來,void*size?網絡如何「知道」我的數據?浮動類型呢?

例如,是否我不能在我的側寫:

stream.setDevice(tcpSocket); 
stream.setByteOrder(QDataStream::LittleEndian); 
... 

struct SomeType 
{ 
    int32_t a; 
    int32_t b; 
    double c; 

    friend QDataStream& operator << (
     QDataStream& stream, const SomeType& x) 
    { 
     stream << x.a 
      << x.b 
      << x.c; 

     return stream; 
    }   
}; 

或可能只是:

SomeType x; 
tcpSocket.write(&x, size); // If known a byte order and a data structure alignment on both sides 
+2

計算機中的「網絡」或網絡堆棧並不知道您傳輸的數據,它只是來回傳遞二進制blob序列。當你必須將數據解釋成你的程序可以處理的東西時,麻煩來自你的程序。如果一個big-endian系統發送一個未修改的int到另一個恰好是little-endian的系統,那麼接收者會認爲接收到的int值是不是被髮送的。 –

+0

@Someprogrammerdude,我能否在我的例子中不考慮這個問題(如果知道主機端的字節順序和數據結構對齊)? –

+1

@VladimirBershov你可以但有一天這個錯誤將是一個問題。在任何情況下,您都會看到使用壓縮成幀協議的性能和維護優勢。谷歌的協議緩衝區就是這樣一個免費提供的協議。 –

回答

2

32比特值表示爲小端(英特爾等):

address offset 0 1 2 3 bits 0-7 bits 8-15 bits 16-23 bits 24-31


而在網絡字節序或大端表示(摩托羅拉的CPU等):

address offset 0 1 2 3 bits 24-31 bits 16-23 bits 8-15 bits 0-7


根據其架構您最早學會了寫字機器代碼(如果你這樣做)一人將進行對你比對方更有意義。對於幾乎所有45歲以下的人來說,這將是網絡字節順序相反的小端。

如果你學會了在得克薩斯州TMS9900架構就像我寫的機器代碼,它是更加混亂,因爲在得克薩斯州的土地,位0是最顯著位


更新(!):

一般來說,最好是以獨立於硬件或編譯器實現選項或甚至語言的方式對數據進行編碼。

下面是從谷歌的協議緩衝區這種編碼的一個例子:網絡

  • 每一端

    1. 通常較少的流量發送,以便更快:

      https://developers.google.com/protocol-buffers/docs/encoding

      的優點在這裏是的連接將會理解數據,而不管硬件,編譯器版本甚至是什麼 語言。

  • +0

    但是我的情況如果知道(並明確定義)了兩個主機端的字節順序和數據結構對齊情況呢? –

    +0

    @ VladimirBershov這將把你的代碼綁定到一個特定的硬件上。硬件隨着時間而改變。你仍然希望你的代碼在10年內工作嗎? –

    +0

    但是,如果我將'int'更改爲'int32_t'?在任何情況下,浮點值都沒有解決方案 –

    1

    TCP-socket只是一個字節流,根本不關心你發送的數據的字節順序。因此,對於您自己的專用網絡協議,您可以使用任何您喜歡的字節順序。如果所有使用該協議的計算機具有相同的自然字節順序,那麼將其用作序列化順序可能是一個好主意,因爲這允許您像編寫第二個示例一樣編寫代碼。

    相關問題