python 用struct模块解决黏包问题


Posted in Python onNovember 07, 2020

为什么会出现黏包现象:

首先只有在TCP协议中才会出现黏包现象,是因为TCP协议是面向流的协议,在发送的数据传输的过程中还有缓存机制来避免数据丢失,因此,在连续发送小数据的时候,以及接收大小不符的时候容易出现黏包现象。本质还是因为我们在接收数据的时候不知道发送的数据的长短。

解决黏包问题

在传输大量数据之前首先告诉接收端要发送的数据大小,如果想更漂亮的解决问题,可以通过struct模块来定制协议。

struct模块:

功能:可以把一个类型,如数字,转成固定长度的bytes。

import struct

ret = struct.pack('i',456872783)   #'i'代表int,就是即将要把一共数字转换成固定长度(4个字节)的bystes类型
print(ret)

num = struct.unpack('i',ret)  #转换回来,返回一个元组
print(num[0])  #提前元组中的值得到4096

解决黏包问题:

服务端:

import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:
  cmd = input('>>>')
  if cmd == 'q':   #当输入‘q'时,结束,并向客户端发送一个'q'。
    conn.send(b'q')
    break
  conn.send(cmd.encode('gbk'))  #将输入的cmd命令发送给客户端
  num = conn.recv(4)   #接收字节信息(返回的消息长度信息)。
  num = struct.unpack('i',num)[0]   #将接收的字节码转化为原来的类型并放在一个元组里面,后面加[0]是提前出元组中的值。
  res = conn.recv(int(num)).decode('gbk')   #接收长度为num 的消息。
  print(res)   #打印
conn.close()
sk.close()

客户端:

import struct
import socket
import subprocess

sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
  cmd = sk.recv(1024).decode('gbk')  #接收服务端发送来的cmd命令
  if cmd == 'q': #当接收到‘q'时,结束。
    break
  # 在客户端执行接收到的cmd命令。并将正确的消息和错误的消息分别放入stdout和stderr管道。
  res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
  std_out = res.stdout.read()   #读取管道内正确的消息
  std_err = res.stderr.read()   #读取管道内错误的消息
  len_num = len(std_out)+len(std_err)   #计算正确和错误消息的总长度
  num_by = struct.pack('i',len_num)    #将消息总长度转换成长度为4的字节码
  sk.send(num_by)   #发送消息长度信息
  sk.send(std_out)  #发送正确消息
  sk.send(std_err)   #发送错误消息

sk.close()

以上就是python 用struct模块解决黏包问题的详细内容,更多关于python struct模块的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python中json格式数据的编码与解码方法详解
Jul 01 Python
python类的继承实例详解
Mar 30 Python
完美解决python中ndarray 默认用科学计数法显示的问题
Jul 14 Python
windows下python安装小白入门教程
Sep 18 Python
python使用Pandas库提升项目的运行速度过程详解
Jul 12 Python
Python 读取xml数据,cv2裁剪图片实例
Mar 10 Python
Django框架models使用group by详解
Mar 11 Python
Windows 下python3.8环境安装教程图文详解
Mar 11 Python
Python获取对象属性的几种方式小结
Mar 12 Python
Django model class Meta原理解析
Nov 14 Python
python list的index()和find()的实现
Nov 16 Python
Python 多线程之threading 模块的使用
Apr 14 Python
python hmac模块验证客户端的合法性
Nov 07 #Python
python如何利用paramiko执行服务器命令
Nov 07 #Python
基于python模拟TCP3次握手连接及发送数据
Nov 06 #Python
如何使用Django Admin管理后台导入CSV
Nov 06 #Python
Selenium结合BeautifulSoup4编写简单的python爬虫
Nov 06 #Python
python两种获取剪贴板内容的方法
Nov 06 #Python
用python写一个带有gui界面的密码生成器
Nov 06 #Python
You might like
JavaScript 闭包深入理解(closure)
2009/05/27 Javascript
学习ExtJS accordion布局
2009/10/08 Javascript
Raphael一个用于在网页中绘制矢量图形的Javascript库
2013/01/08 Javascript
原生js实现查找/添加/删除/指定元素的class
2013/04/12 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
IE6下拉框图层问题探讨及解决
2014/01/03 Javascript
如何实现textarea里的不同文本显示不同颜色
2014/01/20 Javascript
通过url查找a元素并点击
2014/04/09 Javascript
window.location的重写及判断location是否被重写
2014/09/04 Javascript
javascript实现密码强度显示
2015/03/18 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
[14:50]2018DOTA2亚洲邀请赛开幕式
2018/04/03 DOTA
Python入门篇之字典
2014/10/17 Python
Python做智能家居温湿度报警系统
2018/09/25 Python
python 将日期戳(五位数时间)转换为标准时间
2019/07/11 Python
如何基于python实现归一化处理
2020/01/20 Python
python实现udp聊天窗口
2020/03/31 Python
Python request post上传文件常见要点
2020/11/20 Python
浅谈css3中calc在less编译时被计算的解决办法
2017/12/04 HTML / CSS
美国南部最大的家族百货公司:Belk
2017/01/30 全球购物
德国购买健身器材:AsVIVA
2017/08/09 全球购物
什么是方法的重载
2013/06/24 面试题
求职简历自荐信
2013/10/20 职场文书
采购类个人求职的自我评价
2014/02/18 职场文书
教师节宣传方案
2014/05/23 职场文书
先进党支部申报材料
2014/12/24 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
2016党员学习作风建设心得体会
2016/01/21 职场文书
2016春季运动会开幕词
2016/03/04 职场文书
Python Django ORM连表正反操作技巧
2021/06/13 Python
Python中的xlrd模块使用整理
2021/06/15 Python
浅谈PostgreSQL表分区的三种方式
2021/06/29 PostgreSQL
用Python编写简单的gRPC服务的详细过程
2021/07/04 Python
微信小程序scroll-view不能左右滑动问题的解决方法
2021/07/09 Javascript