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操作MySQL简单实现方法
Jan 26 Python
Python中的localtime()方法使用详解
May 22 Python
Python md5与sha1加密算法用法分析
Jul 14 Python
Python编程求解二叉树中和为某一值的路径代码示例
Jan 04 Python
Django实现组合搜索的方法示例
Jan 23 Python
python3 图片referer防盗链的实现方法
Mar 12 Python
python逆序打印各位数字的方法
Jun 25 Python
Django数据库连接丢失问题的解决方法
Dec 29 Python
opencv3/C++图像像素操作详解
Dec 10 Python
Python求两个字符串最长公共子序列代码实例
Mar 05 Python
keras自定义损失函数并且模型加载的写法介绍
Jun 15 Python
Pytorch 实现变量类型转换
May 17 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动态变静态原理
2006/11/25 PHP
PHP命名空间(namespace)的使用基础及示例
2014/08/18 PHP
php中各种定义变量的方法小结
2017/10/18 PHP
php微信扫码支付 php公众号支付
2019/03/24 PHP
Thinkphp5.0 框架Model模型简单用法分析
2019/10/11 PHP
json 实例详细说明教程
2009/10/31 Javascript
用Jquery重写windows.alert方法实现思路
2013/04/03 Javascript
ie与ff下的event事件使用介绍
2013/11/25 Javascript
javascript中attachEvent用法实例分析
2015/05/14 Javascript
简单对比分析JavaScript中的apply,call与this的使用
2015/12/04 Javascript
window.onerror()的用法与实例分析
2016/01/27 Javascript
微信小程序 常用工具类详解及实例
2017/02/15 Javascript
Vue.js递归组件构建树形菜单
2017/12/24 Javascript
JavaScript累加、迭代、穷举、递归等常用算法实例小结
2018/05/08 Javascript
js html实现计算器功能
2018/11/13 Javascript
Vue.js组件使用props传递数据的方法
2019/10/19 Javascript
[00:14]护身甲盾
2019/03/06 DOTA
介绍Python的Django框架中的QuerySets
2015/04/20 Python
Python重新加载模块的实现方法
2018/10/16 Python
Flask框架搭建虚拟环境的步骤分析
2019/12/21 Python
Win10里python3创建虚拟环境的步骤
2020/01/31 Python
卸载tensorflow-cpu重装tensorflow-gpu操作
2020/06/23 Python
CSS3实现内凹圆角的实例代码
2017/05/04 HTML / CSS
用HTML5制作数字时钟的教程
2015/05/11 HTML / CSS
html2canvas生成的图片偏移不完整的解决方法
2020/05/19 HTML / CSS
英国最大的体育&时尚零售公司:JD Sports
2017/12/13 全球购物
英国蛋糕装饰用品一站式商店:Craft Company
2019/03/18 全球购物
Unineed旗下时尚轻奢网站:FABHunt
2019/05/13 全球购物
实习生自荐信范文
2013/11/13 职场文书
新闻传播专业求职信
2014/07/22 职场文书
基层党员对照检查材料
2014/09/24 职场文书
学校党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
2014年医院个人工作总结
2014/12/09 职场文书
2014保险公司个人工作总结
2014/12/09 职场文书
详解vue中v-for的key唯一性
2021/05/15 Vue.js
python可视化之颜色映射详解
2021/09/15 Python