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中列表(list)操作方法汇总
Aug 18 Python
python文件与目录操作实例详解
Feb 22 Python
Python中enumerate()函数编写更Pythonic的循环
Mar 06 Python
PyCharm鼠标右键不显示Run unittest的解决方法
Nov 30 Python
对django xadmin自定义菜单的实例详解
Jan 03 Python
详解Python3定时器任务代码
Sep 23 Python
Jupyter加载文件的实现方法
Apr 14 Python
Jupyter notebook如何修改平台字体
May 13 Python
win10+anaconda安装yolov5的方法及问题解决方案
Apr 29 Python
Python实战之疫苗研发情况可视化
May 18 Python
python爬虫之selenium库的安装及使用教程
May 23 Python
Python+Selenium实现抖音、快手、B站、小红书、微视、百度好看视频、西瓜视频、微信视频号、搜狐视频、一点号、大风号、趣头条等短视频自动发布
Apr 13 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
深入PHP数据加密详解
2013/06/18 PHP
分享PHP函数实现数字与文字分页代码
2015/07/28 PHP
永不消失的title提示代码
2007/02/15 Javascript
IE8 中使用加速器(Activities)
2010/05/14 Javascript
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
JavaScript常用脚本汇总(三)
2015/03/04 Javascript
js实现顶部可折叠的菜单工具栏效果实例
2015/05/09 Javascript
jQuery表单事件实例代码分享
2016/08/18 Javascript
微信小程序点击控件修改样式实例详解
2017/07/07 Javascript
seajs模块压缩问题与解决方法实例分析
2017/10/10 Javascript
vue2.0模拟锚点的实例
2018/03/14 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
2019/05/09 Javascript
Vue中的transition封装组件的实现方法
2019/08/13 Javascript
[53:49]LGD vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
详解Python中的join()函数的用法
2015/04/07 Python
Python中使用haystack实现django全文检索搜索引擎功能
2017/08/26 Python
Python 12306抢火车票脚本 Python京东抢手机脚本
2018/02/06 Python
Python实现k-means算法
2018/02/23 Python
Python使用Django实现博客系统完整版
2020/09/29 Python
pandas中的DataFrame按指定顺序输出所有列的方法
2018/04/10 Python
详解Python中的正斜杠与反斜杠
2019/08/09 Python
python文件读取失败怎么处理
2020/06/23 Python
女士时装鞋:Chinese Laundry
2018/08/29 全球购物
英国DIY汽车维修配件网站:DIY Car Service Parts
2019/08/30 全球购物
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
软件测试常见笔试题
2012/02/04 面试题
微观物理专业自荐信
2014/01/26 职场文书
高中生期末评语
2014/01/28 职场文书
迟到检讨书2000字(精选篇)
2014/10/07 职场文书
2015年团支书工作总结
2015/04/03 职场文书
大学生求职意向书
2015/05/11 职场文书
法定代表人免职证明
2015/06/24 职场文书
海贼王十大潜力果实,路飞仅排第十,第一可毁世界(震震果实)
2022/03/18 日漫
CSS中使用grid布局实现一套模板多种布局
2022/07/15 HTML / CSS
使用CSS实现六边形的图片效果
2022/08/05 HTML / CSS