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中除法使用的注意事项
Aug 21 Python
在Python中操作字符串之replace()方法的使用
May 19 Python
老生常谈python的私有公有属性(必看篇)
Jun 09 Python
Python将8位的图片转为24位的图片实现方法
Oct 24 Python
python 文件查找及内容匹配方法
Oct 25 Python
使用python判断你是青少年还是老年人
Nov 29 Python
Python进阶之全面解读高级特性之切片
Feb 19 Python
浅谈Python中os模块及shutil模块的常规操作
Apr 03 Python
浅谈tensorflow 中的图片读取和裁剪方式
Jun 30 Python
Python读取多列数据以及用matplotlib制作图表方法实例
Sep 23 Python
Python在线和离线安装第三方库的方法
Oct 31 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
Feb 18 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在线打包程序源码
2008/07/27 PHP
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
2013/04/08 PHP
使用淘宝IP库获取用户ip地理位置
2013/10/27 PHP
destoon数据库表说明汇总
2014/07/15 PHP
PHP实现获取FLV文件的时间
2015/02/10 PHP
微信公众号实现会员卡领取功能
2017/06/08 PHP
js 匿名调用实现代码
2009/06/19 Javascript
javascript 一个函数对同一元素的多个事件响应
2009/07/25 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
2010/07/04 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
2015/03/04 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
2015/03/13 Javascript
JavaScript获取网页中第一个图片id的方法
2015/04/03 Javascript
js获取字符串字节数方法小结
2015/06/09 Javascript
JQuery用户名校验的具体实现
2016/03/18 Javascript
JS表格组件神器bootstrap table详解(强化版)
2016/05/26 Javascript
js拼接html字符串的注意事项
2016/10/13 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
Chrome调试折腾记之JS断点调试技巧
2017/09/11 Javascript
Vue在页面右上角实现可悬浮/隐藏的系统菜单
2018/05/04 Javascript
vue 实现websocket发送消息并实时接收消息
2019/12/09 Javascript
Python中关于字符串对象的一些基础知识
2015/04/08 Python
python获取当前时间对应unix时间戳的方法
2015/05/15 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
2015/05/20 Python
Python实现各种排序算法的代码示例总结
2015/12/11 Python
下载官网python并安装的步骤详解
2019/10/12 Python
tensorflow模型保存、加载之变量重命名实例
2020/01/21 Python
Python中如何添加自定义模块
2020/06/09 Python
HTML5新增的标签和属性归纳总结
2018/05/02 HTML / CSS
印尼值得信赖的在线交易网站:Bukalapak
2019/03/11 全球购物
Bibloo罗马尼亚网站:女装、男装、童装及鞋子和配饰
2019/07/20 全球购物
通用C#笔试题附答案
2016/11/26 面试题
售后客服工作职责
2014/06/16 职场文书
查摆问题对照检查材料
2014/08/28 职场文书
2014年服务员工作总结
2014/11/18 职场文书
辞职信范文大全
2015/03/02 职场文书
无保留意见审计报告
2015/06/05 职场文书