黏包以及解决

Posted zhigu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了黏包以及解决相关的知识,希望对你有一定的参考价值。

技术分享图片
1 import struct
2 ret = struct.pack(i, 11111111)  #把一串数据转化成长度为4的字节
3 print(ret, len(ret))                     #b‘xc7x8axa9x00‘  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(bhello,)
 8 conn.send(bworld)
 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()
黏包的解决

 

以上是关于黏包以及解决的主要内容,如果未能解决你的问题,请参考以下文章

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

缓冲区 subprocess 黏包 黏包的解决方案

32黏包的解决方式struct模块

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

网络编程解决黏包现象

python tcp黏包和解决方法