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装饰器decorator介绍
Nov 21 Python
在Windows系统上搭建Nginx+Python+MySQL环境的教程
Dec 25 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
Jan 05 Python
Python使用MD5加密算法对字符串进行加密操作示例
Mar 30 Python
python类的实例化问题解决
Aug 31 Python
Django之使用celery和NGINX生成静态页面实现性能优化
Oct 08 Python
python中读入二维csv格式的表格方法详解(以元组/列表形式表示)
Apr 24 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
May 11 Python
keras实现VGG16 CIFAR10数据集方式
Jul 07 Python
全网最细 Python 格式化输出用法讲解(推荐)
Jan 18 Python
如何使用Python实现一个简易的ORM模型
May 12 Python
详解OpenCV曝光融合
Apr 29 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
使用JSON实现数据的跨域传输的php代码
2011/12/20 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
2015/08/16 PHP
PHP基于GD2函数库实现验证码功能示例
2019/01/27 PHP
javascript实现 在光标处插入指定内容
2007/05/25 Javascript
FormValidate 表单验证功能代码更新并提供下载
2008/08/23 Javascript
初识javascript 文档碎片
2010/07/13 Javascript
框架页面高度自动刷新的Javascript脚本
2013/11/01 Javascript
javascript实现列表滚动的方法
2015/07/30 Javascript
浅谈javascript函数式编程
2015/09/06 Javascript
javascript DIV实现跟随鼠标移动
2020/03/19 Javascript
Vue.js实现移动端短信验证码功能
2017/03/29 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
2017/09/05 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
基于iScroll实现内容滚动效果
2018/03/21 Javascript
浅谈vue3中effect与computed的亲密关系
2019/10/10 Javascript
vue $mount 和 el的区别说明
2020/09/11 Javascript
vue+elementUI中表格高亮或字体颜色改变操作
2020/11/02 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
Django集成百度富文本编辑器uEditor攻略
2014/07/04 Python
Python中多线程及程序锁浅析
2015/01/21 Python
python实现在windows服务中新建进程的方法
2015/06/30 Python
微信小程序python用户认证的实现
2019/07/29 Python
Pycharm连接远程服务器并实现远程调试的实现
2019/08/02 Python
Python 求数组局部最大值的实例
2019/11/26 Python
使用Jupyter notebooks上传文件夹或大量数据到服务器
2020/04/14 Python
python模拟哔哩哔哩滑块登入验证的实现
2020/04/24 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
html5利用canvas绘画二级树形结构图的示例
2017/09/27 HTML / CSS
家得宝加拿大家装网上商店:The Home Depot加拿大
2016/08/27 全球购物
手机促销活动方案
2014/02/05 职场文书
英语课外活动总结
2014/08/27 职场文书
2015年公路路政个人工作总结
2015/07/24 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
有关花店创业的计划书模板
2019/08/27 职场文书
Django cookie和session的应用场景及如何使用
2021/04/29 Python
详解TypeScript的基础类型
2022/02/18 Javascript