黏包以及解决

1 import struct
2 ret = struct.pack(‘i‘, 11111111)  #把一串数据转化成长度为4的字节
3 print(ret, len(ret))                     #b‘\xc7\x8a\xa9\x00‘  4
4 num = struct.unpack(‘i‘, ret)
5 print(num)               #(11111111,)  返回的是一个元组,所以要取第一个
6 print(num[0])          #11111111

struct 模块

黏包:同时执行多条命令之后,得到的结果很有可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就叫做黏包

 1 #server
 2 import socket
 3 sk = socket.socket()
 4 sk.bind((‘127.0.0.1‘, 8888))
 5 sk.listen()
 6 conn, addr = sk.accept()
 7 conn.send(b‘hello,‘)
 8 conn.send(b‘world‘)
 9 conn.close()
10 sk.close()
11
12 #client
13 import socket
14 sk = socket.socket()
15 sk.connect((‘127.0.0.1‘, 8888))
16 ret1 = sk.recv(4)
17 print(ret1)                  #b‘hell‘
18 ret2 = sk.recv(1024)
19 print(ret2)                  #b‘o,‘     传输的内容与速度有关
20 sk.close()
21
22 #client
23 import socket
24 sk = socket.socket()
25 sk.connect((‘127.0.0.1‘, 8888))
26 ret1 = sk.recv(1024)
27 print(ret1)                 #b‘hello,‘
28 ret2 = sk.recv(1024)
29 print(ret2)                 #b‘world‘
30 sk.close()

黏包示例

同时执行多条命令,会产生合包和拆包现象

合包现象:数据很短  时间间隔很短

拆包现象:数据大的时候会发生拆分  不会一次性的全部发送给对方

     对方在接收的时候很可能没有办法一次性接收到所有的信息

     那么没有接受完的信息很可能和后面的信息黏在一起

黏包现象只发生在TCP协议:

  tcp协议的传输是 流式传输 ,每一条信息与信息之间是没有边界的

UDP协议中是不会发生黏包现象的:

  适合短数据的发送,不建议发送过长的数据,会增大数据丢失的几率

在程序中出现黏包的原因:收发数据的边界不清晰  接收数据的这一端不知道接收数据的长度到底是多少

 1 #server
 2 import socket
 3 import struct #引用struct模块,将一个数据(不论长度)打包成一个4长度
 4 sk = socket.socket()
 5 sk.bind((‘127.0.0.1‘, 8899))
 6 sk.listen()
 7 conn, addr = sk.accept()
 8 while True:
 9     st_msg = input(‘>>>‘).encode(‘utf-8‘)
10     ret = struct.pack(‘i‘, len(st_msg))  #把要传送的内容打包
11     conn.send(ret)                             #把包传过去
12     conn.send(st_msg)                      #把包里的内容传过去
13 conn.close()
14 sk.close()
15 #client
16 import socket
17 import struct
18 sk = socket.socket()
19 sk.connect((‘127.0.0.1‘, 8899))
20 while True:
21     pack_num = sk.recv(4)               #接收长度为4的包
22     num = struct.unpack(‘i‘, pack_num)[0]   #打开包。取包里第一组数字
23     ret = sk.recv(num)                 #接收和数字等长度的内容
24     print(ret.decode(‘utf-8‘))          #打印此内容
25 sk.close()

黏包的解决

原文地址:https://www.cnblogs.com/zhigu/p/9648777.html

时间: 2024-08-30 17:23:29

黏包以及解决的相关文章

python tcp黏包和解决方法

一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息. import subprocess sub_obj = subprocess.Popen( 'ls', #系统指令 shell=True, #固定 stdout=subprocess

网络通信中TCP出现的黏包以及解决方法 socket 模拟黏包

粘包问题概述 1.1  描述背景 采用TCP协议进行网络数据传送的软件设计中,普遍存在粘包问题.这主要是由于现代操作系统的网络传输机制所产生的.我们知道,网络通信采用的套接字(socket)技术,其实现实际是由系统内核提供一片连续缓存(流缓冲)来实现应用层程序与网卡接口之间的中转功能.多个数据包被连续存储于连续的缓存中,在对数据包进行读取时由于无法确定发生方的发送边界,而采用某一估测值大小来进行数据读出,若双方的size不一致时就会使数据包的边界发生错位,导致读出错误的数据分包,进而曲解原始数据

黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载

黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数据会直接丢失,俗称丢包) #面试 #首先只有在TCP协议中才有黏包现象,是因为TCP协议是面向流的协议, #在发送的数据传输的过程中还有缓存机制来避免数据丢失 #因此在连续发送小数据的时候,以及接收大小不符的时候,都容易产生黏包现象 #本质是不知道客户端发送的数据长度 面试中解释黏包 #连续send

网络编程-----黏包问题

一,黏包现象 我们通过一段简单程序来看看黏包现象: import socket sk=socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr=sk.accept() while True: cmd=input(">>>") if cmd=='q': conn.send(b'q') break conn.send(cmd.encode('gbk')) res=conn.recv(1024).de

网络编程- 解决黏包现象方案一(六)

队列 利用队列的思路来解决黏包问题 总结 原文地址:https://www.cnblogs.com/mys6/p/10797907.html

tcp协议黏包问题的解决方式

# 出现黏包的场景 # 连续send两个小数据 # 两个recv,第一个recv特别小# 本质上:你不知道到底要接受多大的数据 # 解决# 首先:发送一下这个数据到底有多大# 再按照数据的长度接收数据 #这种解决方式的好处: #确定了我到底要接收多大的数据 #在文件中配置一个配置项:就是每一次recv的大小 buffer=4096 # 当我们要发送大数据的时候,要明确的告诉接收方要发送多大的数据,以便接收方能够 # 准确的接收到所有的数据 # 多在文件的传输过程中 # 大文件的传输一定是按照字节

使用struct模块解决黏包问题

1 ''' 2 远程执行cmd命令程序 3 如果不使用struct模块,ipconfig等会返回长数据的命令会发生黏包现象 4 ''' 5 import socket 6 import struct 7 8 sk = socket.socket() 9 sk.bind(("127.0.0.1", 8080)) 10 sk.listen() 11 conn, addr = sk.accept() 12 while True: 13 cmd = input(">>&g

网络编程中黏包的解决方案

解决方案一 问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据. #_*_coding:utf-8_*_ import socket,subprocess ip_port=('127.0.0.1',8080) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_

网络编程之黏包

当我们同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种现象就是黏包. 黏包成因 TCP协议中的数据传递: tcp协议的拆包机制 当发送端缓冲区的长度大于网卡的MTU时,tcp会将这次发送的数据拆成几个数据包发送出去. MTU是Maximum Transmission Unit的缩写.意思是网络上传送的最大数据包.MTU的单位是字节. 大部分网络设备的MTU都是1500.如果本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会