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中 chr unichr ord函数的实例详解
Aug 06 Python
利用Python爬取微博数据生成词云图片实例代码
Aug 31 Python
Django入门使用示例
Dec 12 Python
python与sqlite3实现解密chrome cookie实例代码
Jan 20 Python
无法使用pip命令安装python第三方库的原因及解决方法
Jun 12 Python
对pyqt5之menu和action的使用详解
Jun 20 Python
Python简单处理坐标排序问题示例
Jul 11 Python
django-rest-framework解析请求参数过程详解
Jul 18 Python
python原类、类的创建过程与方法详解
Jul 19 Python
python3 requests库实现多图片爬取教程
Dec 18 Python
python 元组和列表的区别
Dec 30 Python
pytorch 中forward 的用法与解释说明
Feb 26 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
收集的DedeCMS一些使用经验
2007/03/17 PHP
php中禁止单个IP与ip段访问的代码小结
2012/07/04 PHP
php读取EXCEL文件 php excelreader读取excel文件
2012/12/06 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
php加速器eAccelerator的配置参数、API详解
2014/05/05 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
jquery判断元素的子元素是否存在的示例代码
2014/02/04 Javascript
Extjs grid panel自带滚动条失效的解决方法
2014/09/11 Javascript
JavaScript实现重置表单(reset)的方法
2015/04/02 Javascript
谈一谈JS消息机制和事件机制的理解
2016/04/14 Javascript
使用BootStrap实现表格隔行变色及hover变色并在需要时出现滚动条
2017/01/04 Javascript
详解React中的组件通信问题
2017/07/31 Javascript
认识jQuery的Promise的具体使用方法
2017/10/10 jQuery
JS中promise化微信小程序api
2018/04/12 Javascript
jQuery实现的淡入淡出与滑入滑出效果示例
2018/04/18 jQuery
vue实现2048小游戏功能思路详解
2018/05/09 Javascript
vue 路由嵌套高亮问题的解决方法
2018/05/17 Javascript
vue添加axios,并且指定baseurl的方法
2018/09/19 Javascript
JavaScript学习笔记之数组基本操作示例
2019/01/09 Javascript
vue + typescript + 极验登录验证的实现方法
2019/06/27 Javascript
基于Vue CSR的微前端实现方案实践
2020/05/27 Javascript
[52:44]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第一场 6.3
2018/06/04 DOTA
[09:34]2018DOTA2国际邀请赛寻真——永不放弃的iG
2018/08/14 DOTA
Python代码调试的几种方法总结
2015/04/15 Python
python实现手机通讯录搜索功能
2018/02/22 Python
使用Rasterio读取栅格数据的实例讲解
2019/11/26 Python
python基于win32api实现键盘输入
2020/12/09 Python
Html5页面内使用JSON动画的实现
2019/01/29 HTML / CSS
食堂员工工作职责
2013/12/18 职场文书
九年级政治教学反思
2014/02/06 职场文书
项目总经理岗位职责
2014/02/14 职场文书
乡镇信息公开实施方案
2014/03/23 职场文书
如何书写读后感?(附范文)
2019/07/26 职场文书
2019年手机市场的调研报告2篇
2019/10/10 职场文书
Redis之RedisTemplate配置方式(序列和反序列化)
2022/03/13 Redis