2017-05-18 74 views
0

假設我們正在使用UDP套接字編寫C++網絡應用程序。我們需要傳遞數據的不那麼小的包,所以我們用這種結構,確保字節順序是網絡的一個:具有靈活陣列成員的便攜式替代包裝結構

struct [[gnu::packed]] datagram { 
    uint64_t timestamp; 
    uint8_t type; 
    uint32_t temperatures[60]; // whatever, just an example 
    uint8_t raw_data[]; 
}; 

我們使用GNU GCC,所以我們採取的優勢非標準C++特性如

  • 柔性陣列構件
  • 堆積結構

我們需要一種堆積結構,因爲我們不希望在之間的填充,因爲這可能是建築師依賴於尿液,我們的網絡程序可能運行在不同的架構上。

於是,一年後,它可能會證明,我們需要支持非GCC編譯器,它不支持這些。

是否有可能做到這一點在標準C++?

當然,我知道我們可以簡單地使用uint8_t buffer[SOME_SIZE]和memcpy數據報的每個部分,但這聽起來像是一個創建可怕的,非常難看的代碼的好方法。

+4

查找和使用序列化庫。這個問題已經解決了很多次,但人們堅持反覆做這個問題,因爲沒有任何解決方案是好的。 – nwp

回答

3

[[gnu::packed]]是任意架構之間做一個系列化可怕的方式。那裏還有大型機器。

這樣做正確的方法是在八位位組來定義一個序列化格式,然後一個八位組流(或從UDP套接字)之間進行轉換,並且一個很好的排列結構。

有許多庫,這使得這個簡單。我們在工作中使用protobuf;以前的僱主有自家釀造的解決方案。 (請注意,這樣的圖書館推薦的請求是堆棧溢出明確的題外話。)

+0

當然,所以你可以保持網絡字節順序的結構中的數據。編輯OP。 – marmistrz