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 25 Python
python中实现迭代器(iterator)的方法示例
Jan 19 Python
python 表达式和语句及for、while循环练习实例
Jul 07 Python
python 中if else 语句的作用及示例代码
Mar 05 Python
Python实现重建二叉树的三种方法详解
Jun 23 Python
Python秒算24点实现及原理详解
Jul 29 Python
python批量图片处理简单示例
Aug 06 Python
用python中的matplotlib绘制方程图像代码
Nov 21 Python
pytorch 实现打印模型的参数值
Dec 30 Python
python的Jenkins接口调用方式
May 12 Python
PyCharm中配置PySide2的图文教程
Jun 18 Python
如何利用python正则表达式匹配版本信息
Dec 09 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输出缓冲控制Output Control系列函数详解
2015/07/02 PHP
PHP导出Excel实例讲解
2016/01/24 PHP
golang 调用 php7详解及实例
2017/01/04 PHP
PHP中类的自动加载的方法
2017/03/17 PHP
laravel多条件查询方法(and,or嵌套查询)
2019/10/09 PHP
发布BlueShow v1.0 图片浏览器(类似lightbox)blueshow.js 打包下载
2007/07/21 Javascript
jquery 页面全选框实践代码
2010/04/02 Javascript
js滚动条回到顶部的代码
2011/12/06 Javascript
IE的fireEvent方法概述及应用
2013/02/22 Javascript
jquery中选择块并改变属性值的方法
2013/07/31 Javascript
自己编写的类似JS的trim方法
2013/10/09 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
Spring mvc 接收json对象
2015/12/10 Javascript
js点击返回跳转到指定页面实现过程
2020/08/20 Javascript
简单的js表格操作
2016/09/24 Javascript
微信小程序 wxapp画布 canvas详细介绍
2016/10/31 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
解析JavaScript数组方法reduce
2016/12/12 Javascript
node中Express 动态设置端口的方法
2017/08/04 Javascript
JavaScript刷新页面的几种方法总结
2019/03/28 Javascript
vue中使用vue-cli接入融云实现即时通信
2019/04/19 Javascript
JS localStorage存储对象,sessionStorage存储数组对象操作示例
2020/02/15 Javascript
Vue js with语句原理及用法解析
2020/09/03 Javascript
在Python的Django框架的视图中使用Session的方法
2015/07/23 Python
致Python初学者 Anaconda入门使用指南完整版
2018/04/05 Python
查看Django和flask版本的方法
2018/05/14 Python
python写入并获取剪切板内容的实例
2018/05/31 Python
Python告诉你木马程序的键盘记录原理
2019/02/02 Python
HTML5之tabindex属性全面解析
2016/07/07 HTML / CSS
柏林通行证:Berlin Pass
2018/04/11 全球购物
平面网站制作专科生的自我评价分享
2013/12/11 职场文书
幼儿教师2014年度工作总结
2014/12/16 职场文书
2014年医务科工作总结
2014/12/18 职场文书
医德医风个人总结
2015/02/28 职场文书
母亲节感言
2015/08/03 职场文书
使用Djongo模块在Django中使用MongoDB数据库
2021/06/20 Python