Python 常用模块struct

【一】介绍

  • struct 模块提供了一种处理二进制数据的方式
  • 它允许你使用类似于C语言的结构体的方式来打包(pack)和解包(unpack)数据
  • 这对于处理二进制文件、网络协议等场景非常有用

【二】使用

【1】打包

(1)讲解
  • struct.pack(fmt, v1, v2......)

  • 作用:

    • fmt是格式字符串,指定需要打包的数据格式
    • v1,v2,…是待打包的数据
    • 打包以后的数据格式为字节流
  • 格式化表格来自于官网:struct — Interpret bytes as packed binary data — Python 3.12.1 documentation

FormatC TypePython typeStandard sizeNotes
xpad byteno value(7)
ccharbytes of length 11
bsigned charinteger1(1), (2)
Bunsigned charinteger1(2)
?_Boolbool1(1)
hshortinteger2(2)
Hunsigned shortinteger2(2)
iintinteger4(2)
Iunsigned intinteger4(2)
llonginteger4(2)
Lunsigned longinteger4(2)
qlong longinteger8(2)
Qunsigned long longinteger8(2)
nssize_tinteger(3)
Nsize_tinteger(3)
e(6)float2(4)
ffloatfloat4(4)
ddoublefloat8(4)
schar[]bytes(9)
pchar[]bytes(8)
Pvoid*integer(5)
(2)代码演示
  • python基础数据类型单独打包
import structint_value = 123156456
float_value = 4561.1123
bool_value = True# 整型打包以后占用四个字节
int_struct = struct.pack('i', int_value)
print(int_struct, len(int_struct))# 浮点型打包以后占用四个字节
float_struct = struct.pack('f', float_value)
print(float_struct, len(float_struct))# 布尔型打包以后占用四个字节
bool_struct = struct.pack('?', bool_value)
print(bool_struct, len(bool_struct))
  • python字符串数据类型打包
import structstr_value = "da456q1"# 字符串格式需要转换成字节格式才可以打包,并且还需要提供字符串的长度,默认为1
# 提供的长度小于实际字符串的长度将打包部分数据,造成打包不完整
str_struct = struct.pack('7s', str_value.encode("utf8"))
print(str_struct, len(str_struct))
  • python基础数据类型一次性打包
    • 注意:fmt格式的顺序要和*v的顺序一致
import structint_value = 123156456
float_value = 4561.1123
bool_value = True
str_value = "da456q1"# 一次打包多个
all_struct = struct.pack('i f ? 2s', int_value, float_value, bool_value, str_value.encode("utf8"))
print(all_struct, len(all_struct))

【2】解包

(1)讲解
  • struct.unpack(fmt, v1, v2......)
  • 作用:
    • fmt是格式字符串,需要知道打包的格式
    • v1,v2,…是待打包的数据
    • 解包以后得到一个元组
(2)代码演示
  • 单独数据解包
    • 返回元组,数据在元组第一个位置
import structint_struct = struct.pack('i', 123156456)
float_struct = struct.pack('f', 4561.1123)
bool_struct = struct.pack('?', True)
str_struct = struct.pack('7s', "da456q1".encode("utf8"))# 解包后类型正常
int_res = struct.unpack("i", int_struct)
print(int_res, type(int_res[0]))float_res = struct.unpack("f", float_struct)
print(float_res, type(float_res[0]))bool_res = struct.unpack("?", bool_struct)
print(bool_res, type(bool_res[0]))str_res = struct.unpack("7s", str_struct)
print(str_res, type(str_res[0]))
  • 混合数据解包
    • 按照打包顺寻返回一个元组
import structint_value = 123156456
float_value = 4561.1123
bool_value = True
str_value = "da456q1"all_struct = struct.pack('i f ? 7s', int_value, float_value, bool_value, str_value.encode("utf8"))res = struct.unpack('i f ? 7s', all_struct)
print(res)
# (123156456, 4561.1123046875, True, b'da456q1')

【三】应用

  • 问题:

    • 在socket模块的TCP协议传输数据中

    • 由于接收方不知道将要收到多大的数据,而导致数据读取可能不完整

    • 出现粘包问题,struct模块就可以用来解决这个问题

  • 解决办法:

    • 在每次发送数据之前就行数据大小计算
    • 计算的结果(长度)通过struct计算得到一个四字节的字节流
    • 通过发送这个固定大小的字节流
    • 接收端可以知道将要收到的数据的大小
    • 保证了可以将数据完整读出
# 服务端
import socket
import struct# 1320KB的数据内容
big_data = ("重要信息" * 110).encode("utf8")
data_size = len(big_data)
data_size_struct = struct.pack("i", data_size)# 创建socket对象
server = socket.socket()
server.bind(("localhost", 5656))
server.listen()
conn, addr = server.accept()# 先发送大小数据
conn.send(data_size_struct)
# 发送大数据包
conn.send(big_data)# 关闭
conn.close()
server.close()
# 客户端
import socket
import structclient = socket.socket()
client.connect(("localhost", 5656))# 读取大小文件
head = client.recv(4)
total = struct.unpack("i", head)[0]# 根据大小接收数据
have = 0
data = bytes()
while have < total:data += client.recv(1024)have += 1024print(data.decode("utf8"))client.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS||Emmet语法

1、简介 ​ Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法。 ​ 快速生成HTML结构语法 ​ 快速生成CSS样式语法 2、快速生成HTML结构语法 生成标签 直接输入标签名 按tab键即可 比如 div 然后tab 键&#xff0c; 就可以生成 <…

SystemVerilog验证测试平台

2.2定宽数组 相比于 Verilog1995中的一维定宽数组, System verilog提供了更加多样的数组类型,功能上也大大增强。 2.2.1定宽数组的声明和初始化 Verilog要求在声明中必须给出数组的上下界。因为几乎所有数组都使用0作为索引下界,所以 System verilog允许只给出数组宽度的便捷声…

Pandas实战100例 | 案例 45: 删除列

案例 45: 删除列 知识点讲解 在数据预处理过程中,有时需要从 DataFrame 中删除一个或多个列。Pandas 提供了 drop 方法来删除指定的列。 删除列: 使用 drop 方法并通过 columns 参数指定要删除的列名,可以从 DataFrame 中删除列。示例代码 # 由于代码执行环境重置,需要重…

numpy中数组的操作

目录 一&#xff1a;数组的属性 二&#xff1a;翻转数组 三&#xff1a;数组的计算 一&#xff1a;数组的属性 NumPy 数组&#xff08;通常称为 ndarray&#xff09;有许多有用的属性&#xff0c;这些属性可以帮助你了解数组的各个方面。以下是一些主要的属性&#xff1a; …

数据库MySQL----索引及视图

学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;SC (Sno, Cno, Score)…

代码随想录算法训练营第二十三天| 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

669. 修剪二叉搜索树 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 解题思路&#xff1a;如果当前结点小于所给区间&#xff0c;那该节点及其左子树肯定不符合条件&#xff0c;返回其右子树作为上一结点子树&#xff1b;反之…

使用Portainer创建Nginx容器并部署本地网站结合内网穿透实现公网访问

文章目录 前言1. 安装Portainer1.1 访问Portainer Web界面 2. 使用Portainer创建Nginx容器3. 将Web静态站点实现公网访问4. 配置Web站点公网访问地址4.1公网访问Web站点 5. 固定Web静态站点公网地址6. 固定公网地址访问Web静态站点 前言 Portainer是一个开源的Docker轻量级可视…

postman后端测试时invalid token报错+token失效报错解决方案

报错信息1{“msg”:“invalid token”,“code”:401} 没有添加postman的token信息 报错信息2{“msg”: “token失效&#xff0c;请重新登录”,“code”: 401} 写了token但是token信息写的是错的,会提示token失效 解决方案如下 仅写完后端的查询,但是前端还没写的时候,可…

【Golang】实现简单队列(Queue)数据结构

在计算机科学中&#xff0c;队列是一种特殊的线性数据结构&#xff0c;它遵循FIFO&#xff08;先进先出&#xff09;原则。队列中的元素只能从一端&#xff08;称为队尾或后端&#xff09;添加&#xff0c;并且只能从另一端&#xff08;称为队头或前端&#xff09;移除。这种特…

200SMART作为智能控制器和智能设备使用

200SMART固件版本在V2.5以上的标准型CPU都支持PROFINET IO控制器和IO设备使用。 S7-200SMART作为智能设备仅支持1个IO控制器&#xff0c;可配置的输入输出存储区都为128个字节&#xff0c;地址范围分别为I(Q)1152.0到I(Q)1279.7;每个CPU支持最多8个PROFINET IO设备&#xff0c…

[字符串专题]反转|数字替换|单词反转|右旋转字符串

1.字符串反转 class Solution { public:void reverseString(vector<char>& s) {for(int i0,js.size()-1;i<j;i,j--){char tmps[j];s[j]s[i];s[i]tmp;}} }; 2. 给定一个字符串 s 和一个整数 k&#xff0c;从字符串开头算起&#xff0c;每计数至 2k 个字符&#xf…

SQL笔记 -- 数据库结构优化

1. 拆分表&#xff08;冷热数据分离&#xff09; 不常用的数据为冷数据&#xff0c;反之则为热数据。如果一个表中的数据存在明显的使用频率差异&#xff0c;那么可以将冷热数据分离。通过这种分解可以提高表的查询效率。对于字段很多且有些字段使用不频繁的表&#xff0c;可以…

$route和$router的区别

$route 对象是一个包含当前路由信息的对象&#xff0c;它提供了对当前激活的路由的访问和控制。$route 对象具有以下属性&#xff1a; $route.path&#xff1a;当前路由路径的字符串表示。 $route.params&#xff1a;一个对象&#xff0c;包含动态路由参数和查询参数。 $rout…

Rust之构建命令行程序(三):重构改进模块化和错误处理

开发环境 Windows 10Rust 1.74.1 VS Code 1.85.1 项目工程 这次创建了新的工程minigrep. 重构改进模块化和错误处理 为了改进我们的程序&#xff0c;我们将修复与程序结构及其处理潜在错误的方式有关的四个问题。首先&#xff0c;我们的main函数现在执行两项任务:解析参数和…

adb、monkey的下载和安装

adb下载 官网网址&#xff1a;Downloads - ADB Shell 尽量不要下载最新的ADB Kits&#xff0c;因为兼容性可能不太好。 点击下载 ADB Kits 作者下载的版本是1.0.36 解压adb 到指定的目录即可。 然后把adb配置 环境变量。 检查adb是否安装成功

Java的特点及解析

Java 的一些主要特点及解析&#xff1a; 面向对象编程&#xff08;OOP&#xff09;&#xff1a;Java 是一种面向对象编程语言&#xff0c;它将代码组织成多个相互关联的对象&#xff0c;每个对象具有特定的属性和行为。这种编程范式使得代码更易于理解、维护和扩展。 跨平台性…

React导航守卫(V6路由)

下载&#xff1a; npm i react-router-dom 当登录之后才可以去访问其他页面 (1)在登录页面&#xff0c;我们点击登录的时候&#xff0c;保存一个token,在登录页面引入重定向useNavigate import { useNavigate } from react-router-domconst navigate useNavigate()const l…

java数据库操作

数据库类分析 java.sql.DriverManager&#xff1a; 驱动管理器静态类&#xff0c;类加载时会自动加载配置文件中jdbc.drivers配置的驱动&#xff0c;所有数据库驱动类加载时会调用DriverManager.registerDriver注册自己到DriverManager中&#xff0c;如下代码&#xff0c;为or…

项目开发中安全问题及解决方法-----用户标识不能从客户端获取

服务端直接使用了客户端传过来的用户标识&#xff0c;导致了安全问题&#xff1a; GetMapping("wrong") public String wrong(RequestParam("userId") Long userId) {return "当前用户Id&#xff1a;" userId; }开发同学没有正确认识接口或服务…

Git学习笔记(第1章):Git概述

Git是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目。 Git易于学习&#xff0c;占地面积小&#xff0c;性能极快。它具有廉价的本地库&#xff0c;方便的暂存区域和多个工作流分支等特性。其性能优于Subversion、CVS、Perforce 和…