2013-02-18 52 views
2

我想用python創建一個數據包。數據包有4個字段,每個32位。我有示例代碼:用python創建使用struct.pack的數據包

import socket, sys, os, struct 
field1 = 1 
field2 = '255.255.255.0' 
field3 = 20 
field4 = '192.168.0.1' 

struct.pack=('!L4sL4s',field1,field2,field3) 

但我沒有輸出。我怎樣才能格式化這個數據包,這樣每個變量就可以有4個字節。

+1

小心,最後一行中的'='用一個元組代替'struct.pack'函數! – 2013-02-18 03:22:28

回答

4
>>> struct.pack('!L4sL4s', field1, socket.inet_aton(field2), 
          field3, socket.inet_aton(field4)) 
'\x00\x00\x00\x01\xff\xff\xff\x00\x00\x00\x00\x14\xc0\xa8\x00\x01' 
+0

好的,這工作。感謝大家! – netfreak 2013-02-18 03:58:38

3

你正在分配元組('!L4sL4s',field1,field2,field3)struct.pack。您需要像這樣撥打struct.packstruct.pack('!L4sL4s',field1,field2,field3,field4)(no = sign)。

+0

仍然沒有輸出 – netfreak 2013-02-18 03:20:04

+0

'print' it ... like this:'print struct.pack('!L4sL4s',field1,field2,field3,field4)' – tom 2013-02-18 03:21:45

+0

好吧,我用另一個解釋器(PythonWin),它發送整個結構模塊。在窗口的底部是一個消息「觸發事件」過程事件「失敗」。有誰知道我該如何格式化數據包?我需要4個字節的字段。 – netfreak 2013-02-18 03:25:16

0

pack調用的結果返回給您,您可以將它分配給一個變量。你行應該是這個樣子:

my_packet = struct.pack('!L4sL4s',field1,field2,field3) 

注意,該行預計,一個unsigned long int類型,那麼長度爲4的字符串,那麼長整型,則長度爲4 field2field4都比這長串。例如嘗試使用len(field2)來查看它有多長時間!

+0

嗨jozzas,我讀到'4'表示字節數,而不是字符串的長度。 _italic_例如'10s'表示單個10字節字符串 – netfreak 2013-02-18 03:42:44

+0

'pack('4s','255.255.255.0')'返回'255.',長度爲4.請注意,'packed'字符串會返回一個字符串,所以實際上並沒有做任何事情。你可以打包數字並完成字符串連接以獲得相同的結果。你讀的內容可能是指非打印字符也可以包含在內,例如換行符或EOF字符。 – jozzas 2013-02-18 04:33:52

0

你正在做一個奇怪的組合字符串和整數。您可以打包繩線的無符號整數這樣的:

>>> import struct 
>>> field2 = '255.255.255.0' 
>>> struct.pack('4B',*tuple(int(x) for x in field2.split('.'))) 
'\xff\xff\xff\x00' 

考慮到這一點,你可能想要做的是一樣的東西:

from itertools import chain 
f2_int = map(int,field2.split('.')) 
f4_int = map(int,field4.split('.')) 
struct.pack('L4BL4B',*chain([field1],f2_int,[field3],f4_int)) 

演示:

>>> import struct 
>>> field1 = 1 
>>> field2 = '255.255.255.0' 
>>> field3 = 20 
>>> field4 = '192.168.0.1' 
>>> from itertools import chain 
>>> f2_int = map(int,field2.split('.')) 
>>> f4_int = map(int,field4.split('.')) 
>>> struct.pack('L4BL4B',*chain([field1],f2_int,[field3],f4_int)) 
'\x01\x00\x00\x00\xff\xff\xff\x00\x14\x00\x00\x00\xc0\xa8\x00\x01' 

由於事實證明,我可能會在這裏重新發明輪子。您也可能想要查看socket.inet_aton,看起來它會像您所說的那樣將您的IP地址正確打包爲32位。

+0

'socket.inet_aton'? – 2013-02-18 03:24:05

+0

@gnibbler - 你將不得不精心製作;-) – mgilson 2013-02-18 03:25:52

+0

http://stackoverflow.com/a/14929037/174728 – 2013-02-18 03:28:31