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中使用HTMLParser解析HTML的教程
Apr 29 Python
在SAE上部署Python的Django框架的一些问题汇总
May 30 Python
python判断字符串编码的简单实现方法(使用chardet)
Jul 01 Python
Python在信息学竞赛中的运用及Python的基本用法(详解)
Aug 15 Python
pycharm中成功运行图片的配置教程
Oct 28 Python
pygame游戏之旅 添加icon和bgm音效的方法
Nov 21 Python
django基础学习之send_mail功能
Aug 07 Python
python shapely.geometry.polygon任意两个四边形的IOU计算实例
Apr 12 Python
python 实现任务管理清单案例
Apr 25 Python
django Model层常用验证器及自定义验证器详解
Jul 15 Python
python基本算法之实现归并排序(Merge sort)
Sep 01 Python
Python 中Operator模块的使用
Jan 30 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
linux iconv方法的使用
2011/10/01 PHP
基于php socket(fsockopen)的应用实例分析
2013/06/02 PHP
php获取twitter最新消息的方法
2015/04/14 PHP
PHP共享内存用法实例分析
2016/02/12 PHP
PHP重定向与伪静态区别
2017/02/19 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
PHP5.6读写excel表格文件操作示例
2019/02/26 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
js停止输出代码
2008/07/20 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
node.js中的fs.utimesSync方法使用说明
2014/12/15 Javascript
js实现拖拽效果
2015/02/12 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
javascript实现图片左右滚动效果【可自动滚动,有左右按钮】
2016/09/19 Javascript
深入nodejs中流(stream)的理解
2017/03/27 NodeJs
神级程序员JavaScript300行代码搞定汉字转拼音
2017/05/20 Javascript
详解webpack编译多页面vue项目的配置问题
2017/12/11 Javascript
p5.js入门教程之小球动画示例代码
2018/03/15 Javascript
jQuery实现新闻播报滚动及淡入淡出效果示例
2018/03/23 jQuery
浅谈ng-zorro使用心得
2018/12/03 Javascript
layui点击左侧导航栏,实现不刷新整个页面,只刷新局部的方法
2019/09/25 Javascript
浅析PHP与Python进行数据交互
2018/05/15 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
分享一个pycharm专业版安装的永久使用方法
2019/09/24 Python
python中Django文件上传方法详解
2020/08/05 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
Python创建自己的加密货币的示例
2021/03/01 Python
CSS3实现彩色进度条动画的示例
2020/10/29 HTML / CSS
为世界各地的女性设计和生产时尚服装:ROMWE
2016/09/17 全球购物
马来西亚网上购物平台:ezbuy
2018/02/13 全球购物
日本航空官方网站:JAL
2019/06/19 全球购物
英语专业大学生求职简历的自我评价
2013/10/18 职场文书
纠纷协议书
2014/04/16 职场文书
停发工资证明范本
2015/06/12 职场文书
庭外和解协议书
2016/03/23 职场文书
关于Javascript闭包与应用的详解
2021/04/22 Javascript