我正在尋求您的幫助,因為我已經被同樣的問題困住了 3 天。如果我有 :
Value1 = 0, Value2 = 3.10 and IPv6 = '2001::1'
我想用這個命令打包所有 3 個值: package = struct.pack(*format*, value1, value2, IPv6)
我的問題是:我不知道我可以使用 C 型別中的哪些格式字符來打包 IPv6 并保留其 16 個位元組。我知道我可以使用format = 'i f ?'i 表示整數 / f 表示浮點數,但我需要找到替換 '?' 的內容。它是一個 IPv6 地址的 C 型別格式字符,用于打包三個值。
拜托,有人可以幫助我嗎?
uj5u.com熱心網友回復:
使用它并不是那么簡單struct,因為在將 then 添加到結構之前,您必須知道 IPv6 地址的正確位元組值。'2001::1' 是一種文本表示,它遠不及為您提供這些值:您必須將字串拆分為:,用“0”替換缺失值,然后您將有一個 4 16 位數字串列打包在結構中。和它們,當然在 IPv6 字串表示中有一些極端情況和特殊語法,您必須考慮。
幸運的是,Python 已經在 . ipaddressstdlib 的模塊。
只需 import ipaddress,格式化包的第一部分的結構并將其與 IPv6Address Python 自動型別化中的“packed”屬性連接起來:
import struct
import ipaddress
Value1 = 0
Value2 = 3.10
IPv6 = '2001::1'
payload = struct.pack("if", (Value1, Value2)) ipaddress.ip_address(IPv6).packed
但是,我想知道以這種方式簡單地將一個 int 和一個浮點數與一個 IP 地址打包在一起是否會產生效果——無論將要讀取的代碼都將與您正在寫入的代碼超級耦合。如果您只是將它存盤到一個檔案中,以便由您控制的 Python 程式讀回,請pickle改用。如果您打算通過網路將這些值發送到非 Python 程式,那么像 JSON 這樣的無模式文本傳遞方式可能會簡單得多。
如果您真的想以緊湊的方式存盤這些,并且僅存盤這些以節省空間,并且有數以萬計,并且它們將被同一個程式讀回:嘗試使用numpy陣列。它們會處理每種物件型別的緊湊二進制表示,并且可以讀取和寫入二進制檔案,而 numpy 會為你處理記錄偏移量。
我能看到的唯一用例是,如果您在低級協議中有一個不受您控制的程式,該程式將完全期望這種記錄格式。由于您正在推測如何創建有效負載,并試圖將“3.10”作為浮點值傳達,因此情況似乎并非如此。談到這一點,“3.10”或其他數字可能不會像具有這樣結構的格式良好的 2 位十進制數字值那樣往返,因為浮點在內部是如何表示的。我建議你在那里回顧你的目標和需求,不要把事情復雜化。
要解壓,更簡單的方法是使用 struct 僅恢復數值,并將剩余的 16 個位元組傳遞回ip_address工廠函式 - 它會自動創建一個 IPv6 物件,其字串表示形式是人類友好的“2001::1” .
我在互動式提示中輸入“往返”:
In [30]: import struct, ipaddress
In [31]: x = ipaddress.ip_address('2001::1')
In [32]: v1 = 2;v2 = 3.10
In [33]: payload = struct.pack(">if",v1, v2) x.packed
In [34]: print(payload)
b'\x00\x00\x00\x02@Fff \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
In [35]: v3, v4, nx = struct.unpack(">if", aa[:-16]) (ipaddress.ip_address(aa[-16:]),)
In [36]: print(v3, v4, nx)
2 3.0999999046325684 2001::1
需要注意的兩件事:>結構格式化字串上添加的前綴,以確保對其內容進行編碼時的位元組順序,以及“3.10”值,如上所述,不會作為“漂亮的兩位小數”值往返。round(number, 2)如果需要,在服務器端表示數字時使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/377921.html
上一篇:型別錯誤:msg.map不是函式
下一篇:客戶端斷開連接中的段錯誤
