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入门_浅谈逻辑判断与运算符
May 16 Python
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
Sep 22 Python
Django REST为文件属性输出完整URL的方法
Dec 18 Python
解决pandas中读取中文名称的csv文件报错的问题
Jul 04 Python
解决Python内层for循环如何break出外层的循环的问题
Jun 24 Python
Python基础之变量基本用法与进阶详解
Jan 03 Python
关于TensorFlow新旧版本函数接口变化详解
Feb 10 Python
基于Python计算圆周率pi代码实例
Mar 25 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
Python实现小黑屋游戏的完整实例
Jan 06 Python
用python-webdriver实现自动填表的示例代码
Jan 13 Python
浅析Python中的随机采样和概率分布
Dec 06 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对字符串的递增运算分析
2010/08/08 PHP
php中去除所有js,html,css代码
2010/10/12 PHP
php内嵌函数用法实例
2015/03/20 PHP
PHP结合Mysql数据库实现留言板功能
2016/03/04 PHP
php利用ZipArchive类操作文件的实例
2020/01/21 PHP
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2011/09/27 Javascript
ExtJS中文乱码之GBK格式编码解决方案及代码
2013/01/20 Javascript
js的image onload事件使用遇到的问题
2014/07/15 Javascript
js事件监听机制(事件捕获)总结
2014/08/08 Javascript
javascript学习笔记(一)基础知识
2014/09/30 Javascript
ionic cordova一次上传多张图片(类似input file提交表单)的实现方法
2016/12/16 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
2017/01/21 Javascript
微信小程序使用canvas自适应屏幕画海报并保存图片功能
2019/07/25 Javascript
layui添加动态菜单与选项卡
2019/07/26 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
JavaScript多种滤镜算法实现代码实例
2019/12/10 Javascript
[04:28]2014DOTA2国际邀请赛 采访小兔子LGD挺进钥匙体育馆
2014/07/14 DOTA
[01:00:11]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第一场 2月7日
2021/03/11 DOTA
python解析xml模块封装代码
2014/02/07 Python
Python中运算符"=="和"is"的详解
2016/10/08 Python
Python正则表达式非贪婪、多行匹配功能示例
2017/08/08 Python
Python GUI编程 文本弹窗的实例
2019/06/11 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
pytorch在fintune时将sequential中的层输出方法,以vgg为例
2019/08/20 Python
python两个list[]相加的实现方法
2020/09/23 Python
python实现代码审查自动回复消息
2021/02/01 Python
css3动画效果小结(推荐)
2016/07/25 HTML / CSS
Expedia爱尔兰:酒店、机票、租车及廉价假期
2017/01/02 全球购物
酒店司机岗位职责
2013/12/14 职场文书
员工工作表扬信范文
2014/01/13 职场文书
商业房地产广告语
2014/03/13 职场文书
项目经理任命书
2014/06/04 职场文书
学生安全责任书模板
2014/07/25 职场文书
创优争先心得体会
2014/09/11 职场文书
领导班子在批评与自我批评座谈会上的发言
2014/09/28 职场文书
《全神贯注》教学反思
2016/02/22 职场文书