粘包现象

1 、tcp有粘包及udp无粘包

  • TCP 是面向连接的,面向流的可靠协议;发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,
    合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制面向流的通信是无消息保护边界的。
  • UDP(用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来
    记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。

注:tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,
而udp是基于数据报的,即便是你输入的是空内容(直接回车),那也不是空消息,udp协议会帮你封装上消息头

2 、产生原因:

1、接收端不知道消息的界限,不知道一次提取多少字节数据
2、TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,
通常TCP会根据优化算法(Nagle算法)把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据

产生粘包场景:(1)发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)
(2)接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

3 、解决方案
为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据
struct 模块

注:struct 模块 把一个数字类型转化为固定长度的bytes
(struct.pack)打包       (struct.unpack)解包
res=(struct.pack('i',4855524))   #b'\x04\xe6\xe4\x02' 打包
print(res)
print(struct .unpack('i',res)[0]) #解包

服务端:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import subprocess
import socket
import struct
import json
phone= socket.socket(socket.AF_INET ,socket.SOCK_STREAM )
phone.bind(('127.0.0.1',8080))
phone.listen(5)
while True :conn,client=phone.accept()while True :try:cmd = conn.recv(1024)if len(cmd) == 0: break# 远程执行命令obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,  # 解码stdout=subprocess.PIPE,  # 正确信息stderr=subprocess.PIPE  # 错误信息)stdout = obj.stdout.read()stderr = obj.stderr.read()#先制作报头head_dic= {'filename':'a.txt','total_size':len(stdout)+len(stderr),'hash':'asdf165485221'}head_json = json.dumps(head_dic)head_bytes= head_json.encode('utf-8')#1、先把报头的长度打包成四个bytes,然后发送conn.send(struct.pack('i',len(head_bytes)))#2、发送报头conn.send(head_bytes)#3、发送真实数据conn.send(stdout )conn.send(stderr)except ConnectionResetError:breakconn.close()phone.close()

客户端:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import struct
import socket
import json
phone= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone. connect(('127.0.0.1',8080))
while True :msg = input('<<<')if msg == 0:continue#phone.send(msg.encode('utf-8'))phone.send(bytes(msg,encoding='utf-8'))#1、先收4个字节,该4个字节包含报头的长度  解包header_len=struct .unpack('i',phone.recv(4))[0]#2、通过报头长度,再接受报头内容header_bytes=phone.recv(header_len) #通过报头长度,拿到bytes内容#从报头中解析出想要的内容header_json=header_bytes .decode('utf-8')  #报头内容解码得到字符串类型header_dic=json .loads(header_json)  #反序列化得到字典print(header_dic)total_size = header_dic['total_size']#3、再收真实的数据recv_size =0    #初始值长度res=b''  #接收的具体值while  recv_size< total_size:data= phone.recv(1024)res+=data  # 拼接具体的值recv_size += len(data)  #累加长度print(res.decode('gbk'))   #收到的信息用GBK解码
phone.close()

Python:粘包问题相关推荐

  1. python socket实现文件传输(防粘包)

    1.文件传输的要点: 采用iterator(迭代器对象)迭代读取,提高读取以及存取效率: 通过for line in file_handles逐行conn.send(): 2.socket粘包问题: ...

  2. 学习笔记(12):Python网络编程并发编程-解决粘包问题-简单版本

    立即学习:https://edu.csdn.net/course/play/24458/296243?utm_source=blogtoedu 粘包现象的解决:简单版 1.思路:       在服务器 ...

  3. 学习笔记(10):Python网络编程并发编程-粘包现象

    立即学习:https://edu.csdn.net/course/play/24458/296240?utm_source=blogtoedu 粘包现象:服务器接收到客户端的命令后,进行执行得到结果后 ...

  4. python D28 粘包

    一.两种粘包: MTU简单解释: MTU是Maximum Transmission Unit的缩写.意思是网络上传送的最大数据包.MTU的单位是字节. 大部分网络设备的MTU都是1500个字节,也就是 ...

  5. python/socket编程之粘包

    python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 发 ...

  6. 完美解决Python套接字编程时TCP断包与粘包问题

    首先,来看一个代码,使用TCP协议,发送端发送一句话,接收端接收并显示,运行完全正常. 接下来,把客户端代码稍微修改一下,连续发送多个数据, 按照正常的想法,在服务端输出的信息应该是分为多行的,这样才 ...

  7. python串口数据分包_python TCP Socket的粘包和分包的处理详解

    概述 在进行TCP Socket开发时,都需要处理数据包粘包和分包的情况.本文详细讲解解决该问题的步骤.使用的语言是Python.实际上解决该问题很简单,在应用层下,定义一个协议:消息头部+消息长度+ ...

  8. Python网络与并发编程 02 TCP粘包

    TCP/Socket与subprocess 我们准备做一个可以在Client端远程执行Server端的shell命令并拿到其执行结果的程序,而涉及到网络通信就必然会使用到socket模块,此外还需要s ...

  9. 小白IT:Python中的网络编程是什么样?如何传输?三次捂手四次挥手?什么又是粘包呢

    文章目录 Python 基础---网络编程 一 前引 二.软件开发的架构 1.C/S架构 2.B/S架构 三.网络通信原理* 1.前引 2.互联网的本质:一系列的网络协议 结论 3.osi七层协议** ...

最新文章

  1. 工程大小优化之图片资源
  2. php-fpm定义成集群资源时报错解决方法
  3. Focal Loss改进版 GFocal Loss
  4. C# 集合交、并、差、去重,对象集合交并差
  5. CvSVM::EPS_SVR train_auto assertion sv_count != 0 failed原因
  6. C++中输入输出的十六进制八进制
  7. 周五话分析 | 方法论难落地?来个量身定制版本吧(AARRR模型)
  8. 倚天遇到屠龙:LightGBM VS xgboost谁才是最强的梯度提升库?
  9. matlab disteclud,机器学习实战ByMatlab(四)二分K-means算法
  10. eclipse里的无参构造_构造方法及其作用
  11. 知乎超高赞:都有哪些习惯值得长期坚持?
  12. 将两大小完全相同的照片进行加权混合对比
  13. 并发容器——ConcurrentHashMap
  14. 匹配IP的正则表达式
  15. 蓝桥杯 ALGO-21算法训练 装箱问题(动态规划,01背包)
  16. c语言ch能储存多少字符,二级c语言程序设计习题与解答ch5-7函数字符(11页)-原创力文档...
  17. ubuntu20.04 显卡驱动 cuda cudnn安装
  18. yml在线格式转换工具
  19. Iptable与firewalld防火墙
  20. 基于Redisson实现的延时队列RedissonDelayedQueue实现websocket服务端心跳监听

热门文章

  1. Swift 3 网络请求+数据解析
  2. java 的对象强制转换后的调用
  3. php5.2通过saprfc扩展远程连接sap730成功案例
  4. S4的ESH Bug导致Search help巨慢
  5. ABAP-AVL-OO方法中的ALV的如何自己添加按钮及其响应
  6. 帆软正则表达式定义规则
  7. SAP修改登录桌面背景图片
  8. 企业SAP的二次开发管理之路
  9. 薅羊毛的齐家网遭增长瓶颈,互联网家装迎来破局者!1-06-13
  10. css3 3d旋转兼容模式下,前端CSS3: 3D旋转的问题 (请水神和毒舌放过)