python中黏包问题的解决
python中黏包问题的解决
1.在前面我们知道tcp容易产生黏包的问题,而udp不会产生黏包的问题,但是会产生丢包的问题,tcp应用的场景很多所以黏包问题必须要解决。
1.解决黏包问题第一种方法,我们知道黏包问题是由于tcp的优化算法将两个不太大的数据包合并了一起发送的,这种情况一般出现在连续使用几个send()出现的,所以我们如果知道要发送的数据有多大我们就可以设置接收的大小,这样就可以刚好能把所有的数据接收完。下面是具体的步骤细节见代码
这是远程执行cmd命令并返回结果的程序
server端代码
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:cmd = input('>>>')conn.send(bytes(cmd,encoding='utf-8'))num = conn.recv(1024).decode('utf-8') #接收client端计算好的数据长度conn.send(bytes('ok',encoding='utf-8'))#发送一个确认防止发送num的时候跟后面的send内容合并了ret = conn.recv(num)print(ret.decode('gbk'))
conn.close()
sk.close()
client端代码
import socket
import struct
import subprocess
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:cmd = sk.recv(1024).decode('utf-8')ret = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)std_out = ret.stdout.read()std_err = ret.stderr.read()sk.send(bytes(str(len(std_err)+len(std_out)),encoding='utf-8'))#上面计算字符串的长度发送给server端在接收的时候刚好接收那么长的数据sk.recv(1024) #ok 这一步主要的目的是为了将num的发送跟后面的send分割开防止黏包现象sk.send(std_out)sk.send(std_err)
sk.close()
总结这种解决数据的黏包现象有一个问题是多了一次连接延时要接收一个没有用的数据 ok,如何不需要接收ok就能解决黏包现象呢?这就需要下面这种解决方案
2.用struct模块解决黏包现象
server端代码#tcp黏包现象的解决 struct
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:cmd = input('>>>')conn.send(bytes(cmd,encoding='utf-8'))# num = conn.recv(1024).decode('utf-8')num = conn.recv(1024) #接收数据num = struct.unpack('i',num)[0]#进行解包,解包的结果是一个元组类型取第一个数据# conn.send(bytes('ok',encoding='utf-8'))ret = conn.recv(num)print(ret.decode('gbk'))
conn.close()
sk.close()
client端代码import socket
import struct
import subprocess
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:cmd = sk.recv(1024).decode('utf-8')ret = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)std_out = ret.stdout.read()std_err = ret.stderr.read()# sk.send(bytes(str(len(std_err)+len(std_out)),encoding='utf-8'))num = len(std_err) + len(std_out)num = struct.pack('i',num) #利用struct模块将一个数据转换成bytes类型 i代表int型sk.send(num)# sk.recv(1024) #oksk.send(std_out)sk.send(std_err)
sk.close()
python中黏包问题的解决相关推荐
- python中import包报错解决方法
导入包报错的解决方法 参考链接 首先,知道一下几个概念: 项目:就是整个大文件夹,项目 包:下一级文件夹,不过包都要有__init__.py,这样才是一个包 模块:模块就是.py文件 ├─projec ...
- python中引入包的时候报错AttributeError: module ‘sys‘ has no attribute ‘setdefaultencoding‘解决方法?
python中引入包的时候报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法? 参考文章: (1)pyth ...
- 使用python中py2neo包连接neo4j(安装,连接,成功解决)
使用python中py2neo包连接neo4j neo4j下载 JDK下载 neo4j官网下载 检查安装是否成功 py2neo安装 命令行安装 测试安装是否成功 最近在研究有关知识图谱的任务,选择用图 ...
- 【Python网络开发-黏包问题(三)黏包问题的解决办法】
23_黏包问题的解决办法 一.目前较合理的处理方法: 为字节流加上一个报头,告诉发送的字节流总大小,让后接收端来一个死循环接收完所有数据.用struck将序列化的数据长度打包成4个字节. 使用stru ...
- 对于python来说、一个模块就是一个文件-PYTHON中的包和模块
为了更加友好的对python代码进行组织管理,python中出现了包和模块的概念 类似生活中整理我们的物品一样,将代码按照不同的功能进行整理整合,可以很大程度的提升代码可读性和代码质量,方便在项目中进 ...
- 基于python中jieba包的中文分词中详细使用
基于python中jieba包的中文分词中详细使用(一) 01.前言 之前的文章中也是用过一些jieba分词但是基本上都是处于皮毛,现在就现有的python环境中对其官方文档做一些自己的理解以及具体的 ...
- python怎么安装本地的egg_怎么安装python中egg包
怎么安装python中egg包 发布时间:2020-07-08 17:11:05 来源:亿速云 阅读:175 作者:Leah 怎么安装python中egg包?很多新手对此不是很清楚,为了帮助大家解决这 ...
- python xlrd安装_详解python中xlrd包的安装与处理Excel表格
一.安装xlrd 地址 下载后,使用 pip install .whl安装即好. 查看帮助: >>> import xlrd >>> help(xlrd) Help ...
- Python入门-Python中的包,impot,from,import
#Python中的包 #包(python package)是一个分层次的目录(directory)结构,它将一组功能相近的模块组织在一个目录下 #作用:1.代码规范,2.避免模块名称冲突 #包与目录的 ...
最新文章
- IOS开发UISearchBar失去第一响应者身份后,取消按钮不执行点击事件的问题
- PyTorch 1.7发布,支持CUDA 11、Windows分布式训练
- Angular路由--模块预加载
- win10家庭版远程桌面连接出现身份验证错误
- 常用机器学习算法原理及推导
- Linux中如何安装MySQL详细步骤
- redis.conf配置文件详解
- MSDTC on server 'xxx' is unavailable
- 数字图像处理(一)——彩色图像基础
- 张量(tensor)
- spring mvc 接收表单 bean
- python是哪个专业学的-专业python培训学校
- java虚拟机缓存_《深入理解Java虚拟机》-- 对缓存的理解
- 图像拼接算法(zz)
- java clone 对象_为什么阿里Java手册推荐慎用 Object 的 clone 方法来拷贝对象
- LeetCode 246. 中心对称数
- 中文分词技术(中文分词原理)
- python计算单词长度_python – 返回字符串中的单词长度
- pil库修改图片大小_python 利用PIL库进行更改图片大小的操作
- 开源社已加入群聊,思否 AIGC Hackathon 扩列