黏包以及解决

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协议中是不会发生黏包现象的:

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

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

扫描二维码关注公众号,回复: 3193127 查看本文章
 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()
黏包的解决

猜你喜欢

转载自www.cnblogs.com/zhigu/p/9648777.html
今日推荐