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装饰器入门学习教程(九步学习)
Jan 28 Python
Python+django实现简单的文件上传
Aug 17 Python
详解 Python 读写XML文件的实例
Aug 02 Python
基于python 爬虫爬到含空格的url的处理方法
May 11 Python
多个应用共存的Django配置方法
May 30 Python
Windows下Python3.6安装第三方模块的方法
Nov 22 Python
Python3爬虫学习之应对网站反爬虫机制的方法分析
Dec 12 Python
python读取txt文件中特定位置字符的方法
Dec 24 Python
解决python tkinter界面卡死的问题
Jul 17 Python
Django 外键的使用方法详解
Jul 19 Python
Python中filter与lambda的结合使用详解
Dec 24 Python
PyTorch 实现L2正则化以及Dropout的操作
May 27 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可逆加密解密算法实例代码
2014/01/21 PHP
php实现的太平洋时间和北京时间互转的自定义函数分享
2014/08/19 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
2016/05/28 PHP
PHP入门教程之上传文件实例详解
2016/09/11 PHP
phpMyAdmin无法登陆的解决方法
2017/04/27 PHP
PHP7下协程的实现方法详解
2017/12/17 PHP
Yii框架Session与Cookie使用方法示例
2019/10/14 PHP
javascript,jquery闭包概念分析
2010/06/19 Javascript
jquery解析JSON数据示例代码
2014/03/17 Javascript
javascript实现动态加载CSS
2015/01/26 Javascript
模仿password输入框的实现代码
2016/06/07 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
基于js中document.cookie全面解析
2017/09/14 Javascript
vue+element实现批量删除功能的示例
2018/02/28 Javascript
json对象及数组键值的深度大小写转换问题详解
2018/03/30 Javascript
nodejs 日志模块winston的使用方法
2018/05/02 NodeJs
vue iview多张图片大图预览、缩放翻转
2019/07/13 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
Vue中添加滚动事件设置的方法详解
2020/09/14 Javascript
Django中模版的子目录与include标签的使用方法
2015/07/16 Python
python paramiko模块学习分享
2017/08/23 Python
python性能测量工具cProfile使用解析
2019/09/26 Python
python随机数分布random均匀分布实例
2019/11/27 Python
CSS3中动画属性transform、transition和animation属性的区别
2016/09/25 HTML / CSS
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
俄罗斯连接商品和买家的在线平台:goods.ru
2020/11/30 全球购物
园长自我鉴定
2013/10/06 职场文书
党员思想汇报范文
2013/12/30 职场文书
总经理工作职责范文
2014/03/14 职场文书
演讲稿的格式及范文
2014/08/22 职场文书
优秀教研组申报材料
2014/12/26 职场文书
2015年乡镇环保工作总结
2015/04/22 职场文书
大学优秀学生主要事迹材料
2015/11/04 职场文书
2016年大学生暑期社会实践方案
2015/11/26 职场文书
如何设计高效合理的MySQL查询语句
2021/05/26 MySQL