首页 > 编程语言 > 详细

python之struct模块

时间:2021-08-05 22:30:06      阅读:20      评论:0      收藏:0      [点我收藏+]

面对网络协议,在组包拆包时,python提供了struct模块,它可以帮助我们在python值和C语言中的结构体之间相互转换,一起来了解struct的具体用法。

假设,我们的网络协议为消息id(unsigned short类型)及消息payload(unsigned int类型)组成,那么该如何进行组包拆包呢?如下例所示:

import struct

# 组包, 其中msg_id为0x1002、msg_payload为0x10070008
packet = struct.pack(>HI, 0x1002, 0x10070008)
print("packet: %s" % packet)
# 拆包
msg_id, msg_payload = struct.unpack_from(>HI, packet)
print("msg_id: %s , msg_payload: %s" % (hex(msg_id), hex(msg_payload)))

 运行结果:

packet: b\x10\x02\x10\x07\x00\x08
msg_id: 0x1002 , msg_payload: 0x10070008

上述例子中,我们用到了pack(format, v1, v2, ...)函数组包及unpack(format, buffer)函数拆包,它们指定的消息格式为‘>HI‘,即以大端字节序排列的unsigned short+unsigned int数据。

关于字节顺序的符号,官方的定义如下:

技术分享图片

关于格式类型的符号,官方的定义如下:

技术分享图片

 为了方便我们计算format的长度,比如上例中‘>HI‘的长度,struct提供了calcsize(format)函数供我们调用,如下例所示:

import struct

fmt_len = struct.calcsize(>HI)
print("格式长度: %s" % fmt_len)

运行结果:

格式长度: 6

下面,我们进一步来了解pack_into(format, buffer, offset, v1, v2, ...)函数unpack_from(format, buffer, offset=0)函数,它们在组包拆包时,可以指定所需的偏移量,这让组包拆包变得更加灵活。本文第一个例子中,网络协议为固定长度,但是更多时候,网络协议是可变长度的。假设,网络协议由消息id(unsigned short类型)、消息size(unsigned int类型)及可变长度的消息payload(若干个unsigned int类型)组成,那么该如何操作呢?下例将为大家解答。

import struct
import ctypes

def load_packet(msg_id, msg_size, msg_payload):
    packet = ctypes.create_string_buffer(msg_size)
    struct.pack_into(>HI, packet, 0, msg_id, msg_size)
    struct.pack_into(>%dH % (int(msg_size-6)/2), packet, 6, *msg_payload)
    return packet

def unload_packet(packet):
    msg_id, msg_size = struct.unpack_from(>HI, packet, 0)
    msg_payload = struct.unpack_from(>%dH % (int(msg_size-6)/2), packet, 6)
    return msg_id, msg_size, msg_payload

if __name__ == __main__:
    packet = load_packet(0x1002, 12, (0x1003, 0x1004, 0x1005))
    print("packet: %s" % packet.raw)
    msg_id, msg_size, msg_payload = unload_packet(packet)
    print(hex(msg_id), msg_size, [hex(item) for item in msg_payload])

运行结果:

packet: b\x10\x02\x00\x00\x00\x0c\x10\x03\x10\x04\x10\x05
0x1002 12 [0x1003, 0x1004, 0x1005]

 

参考资料

  • https://docs.python.org/zh-cn/3/library/struct.html

python之struct模块

原文:https://www.cnblogs.com/zhuosanxun/p/15105256.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!