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抓取网页中的图片示例
Feb 28 Python
使用Python内置的模块与函数进行不同进制的数的转换
Mar 12 Python
Python编程中归并排序算法的实现步骤详解
May 04 Python
Python实现PS图像抽象画风效果的方法
Jan 23 Python
理论讲解python多进程并发编程
Feb 09 Python
python实现树形打印目录结构
Mar 29 Python
详解Python如何生成词云的方法
Jun 01 Python
Python3+Appium安装使用教程
Jul 05 Python
Django如何实现网站注册用户邮箱验证功能
Aug 14 Python
解决Django中修改js css文件但浏览器无法及时与之改变的问题
Aug 31 Python
python3 deque 双向队列创建与使用方法分析
Mar 24 Python
Python selenium爬取微信公众号文章代码详解
Aug 12 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
paypal即时到账php实现代码
2010/11/28 PHP
PHP采集腾讯微博的实现代码
2012/01/19 PHP
php htmlspecialchars()与shtmlspecialchars()函数的深入分析
2013/06/05 PHP
php实现webservice实例
2014/11/06 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
php 从一个数组中随机的取出若干个不同的数实例
2016/12/31 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
一直复略了的一个问题,关于表单重复提交
2007/02/15 Javascript
关于jquery动态增减控件的一些想法和小插件
2010/08/01 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
2016/09/23 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
2017/02/08 Javascript
js实现导航吸顶效果
2017/02/24 Javascript
微信小程序之数据双向绑定与数据操作
2017/05/12 Javascript
angular中使用Socket.io实例代码
2017/06/03 Javascript
JS查找数组中重复元素的方法详解
2017/06/14 Javascript
node.js基于express使用websocket的方法
2017/11/09 Javascript
JavaScript实现求最大公共子串的方法
2018/02/03 Javascript
jQuery实现的滑块滑动导航效果示例
2018/06/04 jQuery
JS实现匀速与减速缓慢运动的动画效果封装示例
2018/08/27 Javascript
vue 本地环境跨域请求proxyTable的方法
2018/09/19 Javascript
vue 父组件给子组件传值子组件给父组件传值的实例代码
2019/04/15 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
基于JS实现table导出Excel并保留样式
2020/05/19 Javascript
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
Python实现定时精度可调节的定时器
2018/04/15 Python
解决python3 urllib 链接中有中文的问题
2018/07/16 Python
html5构建触屏网站之网站尺寸探讨
2013/01/07 HTML / CSS
美国室内和室外装饰花盆购物网站:ePlanters
2019/03/22 全球购物
世界上最大的艺术社区:SAA
2020/12/30 全球购物
日语求职信范文
2013/12/17 职场文书
公司委托书格式范文
2014/04/04 职场文书
班长竞选演讲稿
2014/04/24 职场文书
项目建议书怎么写
2014/05/15 职场文书
新闻通讯稿模板
2015/07/22 职场文书
导游词之徐州云龙湖
2019/11/19 职场文书
CSS3实现的水平标题菜单
2021/04/14 HTML / CSS