Python之struct模块
面对网络协议,在组包拆包时,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模块的更多相关文章
- Python学习——struct模块的pack、unpack示例
he struct module includes functions for converting between strings of bytes and native Python data t ...
- c语言write与python的struct模块交互
以下讲的都是用二进制形式打开文件.网上有很多struct模块的文章,下面是我做的小实验. 1.对于c里面的fwrite写入一个单字节,写的就是它的二进制.如3,写入文件就是二进制0x03,它并不是3的 ...
- python中struct模块及packet和unpacket
转自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html 我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组 ...
- 【转】在Python的struct模块中进行数据格式转换的方法
这篇文章主要介绍了在Python的struct模块中进行数据格式转换的方法,文中还给出了C语言和Python语言的数据类型比较,需要的朋友可以参考下 Python是一门非常简洁的语言,对于数据类型的表 ...
- day30 python学习 struct模块和 subprocess 模块
import subprocess import struct aa=input('>>') obj=subprocess.Popen(aa,shell=True,#aa代表的是读取字符串 ...
- Python:struct模块的pack、unpack
mport struct pack.unpack.pack_into.unpack_from 1 # ref: http://blog.csdn<a href="http://lib. ...
- python中struct模块
# #********struct模块********# # 1.按照指定格式将Python数据转换为字符串,该字符串为字节流,如网络传输时, # 不能传输int,此时先将int转化为字节流,然后再发 ...
- Python的Struct模块
python strtuct模块主要在Python中的值于C语言结构之间的转换.可用于处理存储在文件或网络连接(或其它来源)中的二进制数据. #!/usr/bin/env python # -*- c ...
- Python struct模块
有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体. struct模块中最重 ...
随机推荐
- 深入刨析tomcat 之---第14篇 对应19章,使用manager管理 web应用
writedby 张艳涛 第19章讲的是管理程序,当一个tomcat启动的时候,能通过远程浏览器能访问tomcat,启动web应用,关闭web应用,查看web应用 怎么实现的呢? 在webapp 文件 ...
- vue知识点---element el-date-picker 插件默认时间属性default-value怎么赋值?
参考网址: http://www.imooc.com/wenda/detail/509359 默认值,你放到 v-model里面就好. v-model="time" data(){ ...
- ifix与AB PLC contrologix 5300系列的通讯
在最近一个改造项目中,由于先前的4G 平台不稳定,本公司自己组建4G VPN来实现.遇到问题:AB 高版本PLC(1769-L33ER)使用标签名直接代替了地址,ifix的ABR驱动只支持SLC500 ...
- 在Mac上安装Istio并使用,有丰富的监控Kiali、Grafana、Jaeger
我最新最全的文章都在南瓜慢说 www.pkslow.com,文章更新也只在官网,欢迎大家来喝茶~~ 1 简介 之前在文章<服务网格Istio入门-详细记录Kubernetes安装Istio并使用 ...
- Java方法02——定义与调用
方法的定义与调用 定义与调用 例子 package method; public class Demon03 { public static void main(String[] arg ...
- .user.ini和.htaccess
.user.ini .user.ini的使用条件 (1)nginx/apache/IIS,只要是以fastcgi运行的php都可以用这个方法 php配置访问级别 不同的php配置项根据其访问级别具有不 ...
- 前阿里技术总监手打:452页Android Framework 精编内核解析
众所周知,Android是一个基于Linux实现的操作系统.但对于Linux内核来说,Android也仅仅只是一个运行在内核之上的应用程序,与其他运行在内核之上的应用程序没有任何区别. 所以Andro ...
- Kotlin强化实战!这份学习手册让你的面试稳如泰山
一.引言 正如官网的slogan所描述:kotlin,是一门让程序员写代码时更有幸福的现代语言. 同时,也正如维基百科里介绍: JetBrains公司希望Kotlin能够推动IntelliJ IDEA ...
- 树莓派应用Docker
本期通过在树莓派上配置 Docker,来介绍 Docker 应用,欢迎来到"万物皆可 Docker"的时代! 什么是 Docker ? Docker 最初是 dotCloud 公司 ...
- 服务器put请求获取不到参数
问题 put请求参数映射成实体类 而参数似乎接受不到,服务器识别为null 解决 在参数前边加上RequestBody @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请 ...