![](/img/trans.png)
[英]How to receive and assemble byte arrays with variable lengths in Python sockets?
[英]Unspecified byte lengths in Python
我正在為P2P應用程序編寫客戶端,協議的規范說每個數據包的標頭應該具有特定字節長度的每個字段,如下所示:
Version: 1 Byte
Type: 1 Byte
Length: 2 Bytes
And then the data
我已經有了打包和解包標題字段的方法(我認為)像這樣:
packed = struct.pack('cch' , '1' , '1' , 26)
這為數據長度為26的數據包構建了一個標頭,但是當解包數據時,我不確定如何在之后獲取其余數據。 要打開包裝,我們需要知道所有字段的大小,除非我遺漏了什么? 我想打包數據我會使用格式指示符'cch26s'的含義:
1 Byte char
1 Byte char
2 Byte short
26 Byte char array
但是,當我不知道數據包中將包含多少數據時,如何解壓縮數據呢?
你描述協議的方式,你應該先解包前四個字節,然后提取長度(一個16位的int)。 這告訴您在第二步中解壓縮的字節數。
version, type, length = struct.unpack("cch", packed[:4])
content, = struct.unpack("%ds" % length, packed[4:])
如果一切都結束了。 unpack()要求打包緩沖區包含與解壓縮數據完全相同的數據。 另外,檢查長度計數中是否包含4個頭字節。
您可以通過檢查len(data)
來猜測要解壓縮的字符數。
這是一個輔助函數,它為您執行此操作:
def unpack(fmt, astr):
"""
Return struct.unpack(fmt, astr) with the optional single * in fmt replaced with
the appropriate number, given the length of astr.
"""
# http://stackoverflow.com/a/7867892/190597
try:
return struct.unpack(fmt, astr)
except struct.error:
flen = struct.calcsize(fmt.replace('*', ''))
alen = len(astr)
idx = fmt.find('*')
before_char = fmt[idx-1]
n = (alen-flen)/struct.calcsize(before_char)+1
fmt = ''.join((fmt[:idx-1], str(n), before_char, fmt[idx+1:]))
return struct.unpack(fmt, astr)
你可以像這樣使用它:
unpack('cchs*', data)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.