一、什么是粘包
所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
须知:只有TCP有粘包现象,UDP永远不会粘包
粘包不一定会发生
如果发生了:1.可能是在客户端已经粘了
2.客户端没有粘,可能是在服务端粘了
TCP协议是面向流的协议,是容易出现粘包问题的原因。(因为TCP是流式协议,不知道啥时候开始,啥时候结束)。而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的
二、发生粘包的两种情况
发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会当做一个包发出去,产生粘包)
from socket import *
phone = socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SOCK_STREAM,1)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('start running...')
coon,addr = phone.accept() #等待连接
data1 = coon.recv(10)
data2 = coon.recv(10)
print('------------>',data1.decode('utf-8'))
print('------------>',data2.decode('utf-8'))
coon.close()
phone.close()
from socket import *
import time
phone = socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
phone.send('helloworld'.encode('utf-8'))
phone.close()
接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)
from socket import *
phone = socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SOCK_STREAM,1)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('start running...')
coon,addr = phone.accept() #等待连接
data1 = coon.recv(2) #一次没有接收完整
data2 = coon.recv(1024) #下一次接收的时候会先取旧的数据(一旦发现内核的数据为空了,没右循环一直接受,代码就会终止了,剩下的数据接受不到),然后取新的
# data3 = coon.recv(1024) #接收等5秒后的信息
print('------------>',data1.decode('utf-8'))
print('------------>',data2.decode('utf-8'))
# print('------------>',data3.decode('utf-8'))
coon.close()
phone.close()
from socket import *
import time
phone = socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
phone.send('hello'.encode('utf-8'))
time.sleep(5)
phone.send('haiyan'.encode('utf-8'))
phone.close()
解决粘包的方法