2011-05-16 132 views
3

我正在通過網絡從C服務器接收到我的Python客戶端的結構。協議是UDP。我無法控制服務器,它是協議/數據格式。它由這個結構(是的,在IPv4 +端口)的:反序列化C數據

struct ip_s { 
    uint8_t i1; 
    uint8_t i2; 
    uint8_t i3; 
    uint8_t i4; 
    uint16_t port; // big endian 
}; 

除了將其轉化爲大端數據被髮送「原樣」,澆鑄到一個(char*)的端口。

如何將此結構接收爲可由Python處理的格式?


其它信息:

  • Python 2.7版或3.x的
  • 跨平臺
  • 最好的解決方案只使用內置模塊

回答

3

查找到struct.unpack

它w生病可能是這個樣子:

# socket setup 

(buffer, sockaddress) = mysocket.recvfrom(6) 
if len(buffer)== 6: 
    i1,i2,i3,i4, port = struct.unpack('!BBBBH', buffer) 
+0

已經發現它是正確的,但我會留下問題以供進一步參考。 – orlp 2011-05-16 22:29:47

+2

噢,''BBBBH''應該是''!BBBBH「'的大端口。 – orlp 2011-05-16 22:39:34

+0

我自由地編輯了你的答案。 – orlp 2011-05-17 00:24:51

0

我收到一個結構通過網絡

停在那兒。不要這樣做。該技術引入了以下依賴關係:

  1. 字序:big-endian或little-endian。
  2. 填充。
  3. 包裝。

(2)和(3)又取決於:

  1. 編譯器。
  2. 編譯器版本。
  3. 周圍的#pragmas。
  4. 編譯C程序時有效的編譯選項。

這相當多的依賴關係。不要這樣做。定義一個應用程序協議並使用它。或者使用像XDR這樣的解決問題的東西。

+0

也許你不應該「停在那裏」,至少不要閱讀:「我無法控制服務器,它的協議/數據格式。」 – orlp 2011-05-17 00:18:34

+0

@nightcracker因此,無論服務器是無能的設計,有人需要得到控制,或者更可能的,這只是一種描述應用協議的方式,它實際上是一個有線協議,由四個八位字節組成,後面是網絡字節順序中的一個兩字節整數。 – EJP 2011-05-17 01:15:20

+0

你的描述和我的沒有區別,因爲實現使用'uint8'和類似的東西,沒有留下空間來實現。我真的堅持服務器的設計,它是基於[此代碼]的CoD4主服務器(http://svn.icculus.org/twilight/trunk/dpmaster/src/messages.c?revision=10433&view =標記)。 – orlp 2011-05-17 01:50:14