第31篇 粘包的产生原理 以及如何解决粘包问题
Posted cavalier-chen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第31篇 粘包的产生原理 以及如何解决粘包问题相关的知识,希望对你有一定的参考价值。
内容回顾:
如何与另外一台电脑连接:
ping 对方的ip地址
如何参电脑的ip配置
cmd-->ipconfig
内容概览:
粘包问题
粘包产生原理
如何解决粘包问题
粘包的产生:
#server
import socket sk = socket.socket() ip_port = (‘127.0.0.1‘,8989) sk.bind(ip_port) sk.listen() conn,addr = sk.accept() conn.send(b‘hello,‘) conn.send(b‘world‘) conn.close() sk.close()
#client
import socket sk = socket.socket() ip_port = (‘127.0.0.1‘,8989) sk.connect(ip_port) ret1 = sk.recv(2) print(ret1) ret2 = sk.recv(1024) print(ret2) sk.close()
#client端收到的结果
b‘he‘ b‘llo,‘
什么是粘包?
数据之间没有分界线,导致两个数据粘合在一起,被接收端接收的现象,就叫做粘包
-------------插入图片————————
粘包产生的原因:
发送端将两个挨得很近的数据,发送出去,在本地的缓存区粘合在一起,传输给对方,
对方接收到数据之后,由于数据没有界限,于是将两个粘合在一起的数据一起接收。
合包现象:
数据很短
时间间隔很近
拆包现象:
大数据在传输的过程中会发生拆包现象
不会一次性的将数据全部发送给对方
对方接收的时候很可能没有办法一次性接收所有的信息
对方一次没有接收完的信息,会与后面的信息粘在一起
粘包现象只会发生在TCP协议
TCP的协议是流式传输
每一条信息与信息之间是没有界限的
UDP协议中是不会发生粘包的
UDP协议适合短数据的发送
不建议发送过程的信息
数据越长,传输逇过程中,会越容易丢失
解决粘包问题的初探:
能否在发送信息的时候把信息的长度一起发送,接收方根据长度来截取信息。
#server
import socket sk = socket.socket() ip_port = (‘127.0.0.1‘,8989) sk.bind(ip_port) sk.listen() conn,addr = sk.accept() conn.send(b‘0011hello,zhuge‘) conn.send(b‘0005world‘) conn.close() sk.close()
#client
import socket sk = socket.socket() ip_port = (‘127.0.0.1‘,8989) sk.connect(ip_port) ret1 = sk.recv(4) len1 = int(ret1.decode(‘utf-8‘)) ret2 = sk.recv(len1) print(ret2.decode(‘utf-8‘)) ret3 = sk.recv(4) len2 = int(ret3.decode(‘utf-8‘)) ret4 = sk.recv(len2) print(ret4.decode(‘utf-8‘)) sk.close()
#client显示结果:
hello,zhuge world
总结一下:
上面的办法虽然解决了问题但是存在漏洞,要是长度超过9999就不好使了。
有没有一种算法,输入任意长的数字,得到的是一个四位数,
这个四位数,被接收之后,又可以根据算法反推出这个任意长的数是多少,那么问题就解决了。
struck模块
#server端
conn,addr = sk.accept() while True: s = input(‘>>>‘).encode(‘utf-8‘) pack_num = struct.pack(‘i‘,len(s))#s的长度转化成一个4位数 conn.send(pack_num) conn.send(s) conn.close() sk.close()
#client端
import socket import struct sk = socket.socket() ip_port = (‘127.0.0.1‘,8989) sk.connect(ip_port) while True: pack_num = sk.recv(4) num = struct.unpack(‘i‘,pack_num)[0]#这里有个坑,得到的是元组,(10,) ret = sk.recv(num) print(ret.decode(‘utf-8‘)) sk.close()
以上是关于第31篇 粘包的产生原理 以及如何解决粘包问题的主要内容,如果未能解决你的问题,请参考以下文章