面对网络协议,在组包拆包时,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模块的更多相关文章

  1. Python学习——struct模块的pack、unpack示例

    he struct module includes functions for converting between strings of bytes and native Python data t ...

  2. c语言write与python的struct模块交互

    以下讲的都是用二进制形式打开文件.网上有很多struct模块的文章,下面是我做的小实验. 1.对于c里面的fwrite写入一个单字节,写的就是它的二进制.如3,写入文件就是二进制0x03,它并不是3的 ...

  3. python中struct模块及packet和unpacket

    转自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html 我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组 ...

  4. 【转】在Python的struct模块中进行数据格式转换的方法

    这篇文章主要介绍了在Python的struct模块中进行数据格式转换的方法,文中还给出了C语言和Python语言的数据类型比较,需要的朋友可以参考下 Python是一门非常简洁的语言,对于数据类型的表 ...

  5. day30 python学习 struct模块和 subprocess 模块

    import subprocess import struct aa=input('>>') obj=subprocess.Popen(aa,shell=True,#aa代表的是读取字符串 ...

  6. Python:struct模块的pack、unpack

    mport struct pack.unpack.pack_into.unpack_from 1 # ref: http://blog.csdn<a href="http://lib. ...

  7. python中struct模块

    # #********struct模块********# # 1.按照指定格式将Python数据转换为字符串,该字符串为字节流,如网络传输时, # 不能传输int,此时先将int转化为字节流,然后再发 ...

  8. Python的Struct模块

    python strtuct模块主要在Python中的值于C语言结构之间的转换.可用于处理存储在文件或网络连接(或其它来源)中的二进制数据. #!/usr/bin/env python # -*- c ...

  9. Python struct模块

    有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体. struct模块中最重 ...

随机推荐

  1. 【LeetCode】面试题62. 圆圈中最后剩下的数字

    题目:面试题62. 圆圈中最后剩下的数字 这题很有意思,也很巧妙,故记录下来. 官方题解思路,是约瑟夫环的数学解法: 我们将上述问题建模为函数 f(n, m),该函数的返回值为最终留下的元素的序号. ...

  2. 凯撒密码(Caesar cipher) 详解

    ------------恢复内容开始------------ 最近训练CTF的时候,发现密码学这块的知识不太系统,所以自己接下来会陆陆续续整理出来 就先从古典密码中的凯撒密码说起吧 凯撒密码内容比较简 ...

  3. 学废了系列 - WebGL与Node.js中的Buffer

    WebGL 和 Node.js 中都有 Buffer 的使用,简单对比记录一下两个完全不相干的领域中 Buffer 异同,加强记忆. Buffer 是用来存储二进制数据的「缓冲区」,其本身的定义和用途 ...

  4. Appium自动化测试(1)-安装&环境

    需要链接appium自动化测试教程 http://www.cnblogs.com/fnng/p/4540731.htmlappium中文文档:https://github.com/appium/app ...

  5. Android逆向工程师的黑科技

    你们发现了吗?Android逆向.安全方面的工程师真的越来越"稀有"了. 以腾讯.美团.百度为代表的大厂们,在某招聘网站上居然薪酬高达30-60k. 现在移动端市场越来越火热,AP ...

  6. 工作中后端是如何将API提供出去的?swaggo很不错

    工作中后端是如何将API提供出去的?swaggo很不错 咱们上一次简单分享了 GO 权限管理之 Casbin ,他一般指根据系统设置的安全规则或者安全策略 分享了权限管理是什么 Casbin 是什么 ...

  7. 面试官:实现一个带值变更通知能力的Dictionary

    如题, 你知道字典KEY对应的Value什么时候被覆盖了吗?今天我们聊这个刚性需求. 前文提要: 数据获取组件维护了业务方所有(在用)的连接对象,DBA能在后台无侵入的切换备份库. 上文中:DBA在为 ...

  8. 超详细 Java 15 新功能介绍

    点赞再看,动力无限.微信搜「程序猿阿朗 」,认认真真写文章. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Java 15 在 2 ...

  9. 跟我一起写 Makefile(六)

    书写命令 ---- 每条规则中的命令和操作系统Shell的命令行是一致的.make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟在依赖规则后面的分号后的.在命令行 ...

  10. 关于shell脚本——echo、for语句、while语句、until语句

    目录 一.echo 1.1.echo命令用法 1.2.echo截取字符 二.for语句 2.1.实例 创建用户名文件 创建脚本文件 运行脚本 三.while语句 3.1.实例 创建脚本文件 运行脚本 ...