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中使用Queue和Condition进行线程同步的方法
Jan 19 Python
使用Python读写文本文件及编写简单的文本编辑器
Mar 11 Python
Python中with及contextlib的用法详解
Jun 08 Python
详解用Python处理HTML转义字符的5种方式
Dec 27 Python
Python冲顶大会 快来答题!
Jan 17 Python
解决PyCharm同目录下导入模块会报错的问题
Oct 13 Python
Python 实现遥感影像波段组合的示例代码
Aug 04 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
Aug 09 Python
tensorflow如何继续训练之前保存的模型实例
Jan 21 Python
如何理解python面向对象编程
Jun 01 Python
python 制作本地应用搜索工具
Feb 27 Python
Django集成富文本编辑器summernote的实现步骤
May 31 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脚本的10个技巧(2)
2006/10/09 PHP
php列出一个目录下的所有文件的代码
2012/10/09 PHP
discuz加密解密函数使用方法和中文注释
2014/01/21 PHP
php清除和销毁session的方法分析
2015/03/19 PHP
阿里云的WindowsServer2016上部署php+apache
2018/07/17 PHP
由点击页面其它地方隐藏div所想到的jQuery的delegate
2013/08/29 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
2014/06/15 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
2015/03/27 Javascript
漂亮! js实现颜色渐变效果
2016/08/12 Javascript
详解Angular 4.x 动态创建组件
2017/04/25 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
Vue.js 事件修饰符的使用教程
2018/11/01 Javascript
JavaScript实现星级评价效果
2019/05/17 Javascript
小程序实现简单语音聊天的示例代码
2020/07/24 Javascript
React 条件渲染最佳实践小结(7种)
2020/09/27 Javascript
Python的装饰器使用详解
2017/06/26 Python
scrapy spider的几种爬取方式实例代码
2018/01/25 Python
对Python中创建进程的两种方式以及进程池详解
2019/01/14 Python
Pycharm学生免费专业版安装教程的方法步骤
2020/09/24 Python
使用CSS3的font-face字体嵌入样式的方法讲解
2016/05/13 HTML / CSS
财务部出纳岗位职责
2013/12/22 职场文书
小学生家长评语集锦
2014/01/30 职场文书
运动会开幕式邀请函
2014/02/03 职场文书
高中生物教学反思
2014/02/05 职场文书
小学信息技术教学反思
2014/02/10 职场文书
生日主持词
2014/03/20 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
篮球友谊赛通讯稿
2014/10/10 职场文书
2014年内勤工作总结
2014/11/24 职场文书
卡特教练观后感
2015/06/08 职场文书
我是特种兵观后感
2015/06/11 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
2019年鼓励无偿献血倡议书
2019/09/17 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP
第四次工业革命,打工人与机器人的竞争
2022/04/21 数码科技