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编写函数装饰器
Mar 18 Python
python3使用urllib模块制作网络爬虫
Apr 08 Python
Python科学画图代码分享
Nov 29 Python
Python实现的根据文件名查找数据文件功能示例
May 02 Python
python 实时得到cpu和内存的使用情况方法
Jun 11 Python
在Python文件中指定Python解释器的方法
Feb 18 Python
Python3之手动创建迭代器的实例代码
May 22 Python
Python二元赋值实用技巧解析
Oct 25 Python
python 并发下载器实现方法示例
Nov 22 Python
Python3 assert断言实现原理解析
Mar 02 Python
Python接口测试环境搭建过程详解
Jun 29 Python
Python中logging日志的四个等级和使用
Nov 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
URL Rewrite的设置方法
2007/01/02 PHP
php数组的一些常见操作汇总
2011/07/17 PHP
codeigniter中view通过循环显示数组数据的方法
2015/03/20 PHP
php微信高级接口调用方法(自定义菜单接口、客服接口、二维码)
2016/11/28 PHP
为数据添加append,remove功能
2006/10/03 Javascript
js几个不错的函数 $$()
2006/10/09 Javascript
疯掉了,尽然有js写的操作系统
2007/04/23 Javascript
JavaScript Event学习第二章 Event浏览器兼容性
2010/02/07 Javascript
jquery退出each循环的写法
2014/02/26 Javascript
扒一扒JavaScript 预解释
2015/01/28 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
对Js OOP编程 创建对象的一些全面理解
2016/07/26 Javascript
vue元素实现动画过渡效果
2017/07/01 Javascript
关于js中的鼠标事件总结
2017/07/11 Javascript
JS+canvas动态绘制饼图的方法示例
2017/09/12 Javascript
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
2017/09/19 NodeJs
图片加载完成再执行事件的实例
2017/11/16 Javascript
微信小程序个人中心的列表控件实现代码
2020/04/26 Javascript
vue+axios 拦截器实现统一token的案例
2020/09/11 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
11个Javascript小技巧帮你提升代码质量(小结)
2020/12/28 Javascript
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
在Django的模型中添加自定义方法的示例
2015/07/21 Python
pandas数值计算与排序方法
2018/04/12 Python
python 命令行传入参数实现解析
2019/08/30 Python
给我一面国旗 python帮你实现
2019/09/30 Python
Python生成随机验证码代码实例解析
2020/06/09 Python
python实现简单的五子棋游戏
2020/09/01 Python
松下电器美国官方商店:Panasonic美国
2016/10/14 全球购物
linux面试题参考答案(9)
2016/01/29 面试题
家长给幼儿园的表扬信
2014/01/09 职场文书
学校节能减排方案
2014/06/13 职场文书
大学生学生会工作总结2015
2015/05/26 职场文书
队列队形口号
2015/12/25 职场文书
九年级化学教学反思
2016/02/22 职场文书
如何解决.cuda()加载用时很长的问题
2021/05/24 Python