struct作用
struct模塊的作用是將數據長度轉換成固定長度的內容
一般默認是4個字節
import struct
# 關於struct模塊
res = struct.pack('i', 1230165465)
print(res, type(res), len(res))
# 這裏的"i"表示int,整型
# 輸出結果:b'\xce\x04\x00\x00' <class 'bytes'> 4
# 而1230轉成16進制的結果爲4CE,所以struct接收的結果是反向的
obj = struct.unpack('i', res)
print(obj)
# b'\xd9\xd5RI' <class 'bytes'> 4
# (1230165465,)
# unpack後,結果就是正向的,所以不需要在意這些細節,只要關注傳輸的是4字節就可以了
需要注意的是,struct模塊是缺點的,就是struct的int類型或別的類型不是無限制的
當整數大於一定值後,會失敗,即int或相關類型是有大小限制的
官方文檔:https://docs.python.org/3/library/struct.html
struct支持的類型
Format | C Type | Python type | Standard size | Notes |
---|---|---|---|---|
x | pad byte | no value | ||
c | char | bytes of length 1 | 1 | |
b | signed char | integer | 1 | (1),(3) |
B | unsigned char | integer | 1 | (3) |
? | _Bool | bool | 1 | (1) |
h | short | integer | 2 | (3) |
H | unsigned short | integer | 2 | (3) |
i | int | integer | 4 | (3) |
I | unsigned int | integer | 4 | (3) |
l | long | integer | 4 | (3) |
L | unsigned long | integer | 4 | (3) |
q | long long | integer | 8 | (2), (3) |
Q | unsigned long long | integer | 8 | (2), (3) |
n | ssize_t | integer | (4) | |
N | size_t | integer | (4) | |
e | (7) | float | 2 | (5) |
f | float | float | 4 | (5) |
d | double | float | 8 | (5) |
s | char[] | bytes | ||
p | char[] | bytes | ||
P | void * | integer | (6) |
struct的應用
在網絡傳輸時,可以用作報頭文件的大小計算
製作特定的報頭,以字典格式,接收後,進行unpack後,獲得大小,然後獲取指定的大小,避免了粘包問題
僞代碼:
import socket
import struct
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 9901))
phone.send(cmd.encode('utf-8'))
obj = phone.recv(4)
print("obj是: ", obj)
print("obj的type: ", type(obj))
header_size = struct.unpack('i', obj)[0]
print('struct.unpack(\'i\', obj)是:', struct.unpack('i', obj))
print('header_size是:', header_size)
print('header_size類型是:', type(header_size))
僞代碼執行結果:
# obj是: b';\x00\x00\x00'
# obj的type: <class 'bytes'>
# struct.unpack('i', obj)是: (59,)
# header_size是: 59
# header_size類型是: <class 'int'>
對方將數據進行struct化,然後進行傳輸,接收數據
obj = phone.recv(4) # 這裏獲取的額結果是一個對象,將對象進行struct.unpack(\'i\', obj)
後的結果是一個元組,(59,),所以需要struct.unpack('i', obj)[0]
進行數據處理