Python数据传输黏包问题
作者:长得丑就要多读书 发布时间:2023-04-21 13:05:22
1.socket黏包问题原理
黏包:指数据与数据之间没有明确的分界线,导致不能正确的读取数据。
应用数据想要发送数据就必须将数据交给操作系统,而操作系统需要同时为所有的应用程序提供数据传输服务,就意味着不可能马上将应用数据发送,就需要为程序提供一个缓冲区,用于临时存放数据。
当发送数据很快,有两条数据都在缓冲区时,操作系统可能将两个数据发给接收方,数据之间没有分界线,接收方会误认为是一条数据。
2.UDP协议
UDP在收发数据时是基于数据包的,即一个包一个包的发送,包与包之间有明确的分界,到达对方缓冲区后也是独立数据包。这种方式存在的问题:
①发送数据的长度每个操作系统会有不同的限制,数据超过限制则无法发送;
②接收方接收数据时,如果应用程序提供的缓存容量小于数据包的长度,则会造成数据的丢失,而缓冲区大小不可能无限大。
这意味着UDP不会出现黏包问题,但会丢失数据,不可靠。
3.TCP协议
TCP增加了一套校验规则来保证数据的完整性,会将超过TCP包最大长度的数据拆分为多个TCP包,并在传输数据时为每一个TCP数据包指定一个顺序号,接收方在收到TCP数据包后按照顺序将数据包进行重组,重组后的数据全都是二进制数据,且每次收到的二进制数据之间没有明显的分界。基于这种工作机制,TCP在三种情况下发生黏包问题:
①当单个数据包较小时,接收方可能一次性读取了多个包的数据;
②当整体数据较大时,接收方可能一次性仅读取了一个包的一部分内容;
③另外TCP协议为提高效率,增加了一种优化机制,会将数据小且发送间隔短的数据合并发送,该机制也会导致发送方将两个数据包粘在一起发送。
也就是说,TCP传输数据是可靠的,但是会黏包。
4.发送方出现的黏包
服务器端:
from socket import *
server_socket = socket(AF_INET,SOCK_STREAM)
server_socket.bind(('',8080))
server_socket.listen(5)
new_socket,client_addr = server_socket.accept()
data1 = new_socket.recv(1024)
data2 = new_socket.recv(1024)
print("收到的第一条数据:",data1)
print("收到的第二条数据:",data2)
new_socket.close()
server_socket.close()
客户端:
from socket import *
client_socket = socket(AF_INET,SOCK_STREAM)
client_socket.connect(('10.175.193.126',8080))
client_socket.send('hello'.encode('utf-8'))
client_socket.send('word'.encode('utf-8'))
client_socket.close()
服务器端接收到的数据:
由于客户端两条数据发送间隔太短且数据包太小,被服务器端误认为是一条数据。
5. 接收方出现的黏包
服务器端:
from socket import *
import time
server_socket = socket(AF_INET,SOCK_STREAM)
server_socket.bind(('',8080))
server_socket.listen(5)
new_socket,client_addr = server_socket.accept()
print("连接成功!",client_addr)
data1 = new_socket.recv(3) #每次只接收三个字节,接收不完整
time.sleep(6)
print("收到的第一条数据:",data1)
data2 = new_socket.recv(10)
#接收第一次未接收的数据,若有空间,会继续接收新数据
print("收到的第二条数据:",data2)
new_socket.close()
server_socket.close()
客户端:
from socket import *
#通过time模块使客户端发送多个数据包时,时间间隔变长
import time
client_socket = socket(AF_INET,SOCK_STREAM)
client_socket.connect(('10.175.193.126',8080))
client_socket.send('hello'.encode('utf-8'))
time.sleep(5) #让当前线程休眠5秒
client_socket.send('word'.encode('utf-8'))
client_socket.close()
服务器端接收到的数据:
6.黏包的成因
①服务器端出现黏包:接收方不知道消息之间的界限,不知道一个消息要提取多少字节的数据造成的;
②客户端出现黏包:TCP在发送数据少且间隔时间短的数据包时,会将几条合并一起发送。
来源:https://blog.csdn.net/qq_40523659/article/details/121695950
猜你喜欢
- 一、出错情况 有些时候当你重启了数据库服务,会发现有些数据库变成了正在恢复、置疑、可疑等情况,这个时候DBA就会很紧张了,下面是一些在实践中
- 一、通过结构(struct) 实现 接口(interface)1、在了解iris框架的时候,经常看到有这样去写的使用一个空结构体作为 * ,
- 前三篇文章中,明确了栅格系统的设计细节和适用范围。这一篇将集中讨论960栅格系统的技术实现。Blueprint的实现Blueprint是一个
- 在python中,通常通过dict和zip组合来构建键值对。比如:aid = [i for i in range(10)]name = [[
- csv是Comma-Separated Values的缩写,是用文本文件形式储存的表格数据,比如如下的表格就可以存储为csv文件,文件内容是
- 本篇的主题是 rbac权限控制的详细操作步骤,注意是操作步骤哦,关于配置与rbac的搭建,我们在yii2搭建完美后台并实现rbac权限控制实
- ERRNO: 256 TEXT: SQLSTATE[HY000]: General error: 1436 Thread stac
- 本文主要研究的是Python对内存的使用(深浅拷贝)的相关问题,具体介绍如下。浅拷贝就是对引用的拷贝(只拷贝父对象) 深拷贝就是对对象的资源
- 页面自动刷新代码大全,基本上所有要求自动刷新页面的代码都有,大家可以自由发挥做出完美的页面。 1)10表示间隔10秒刷 ...页面自动刷新代
- 本文为大家介绍了一段来源于网络上的代码实例,能够合并单元格,下面和大家分享一下,希望能够给需要的朋友或多或少带来一定的帮助。代码实例如下:&
- 1、python多进程编程背景python中的多进程最大的好处就是充分利用多核cpu的资源,不像python中的多线程,受制于GIL的限制,
- 本文实例讲述了Python列表推导式、字典推导式与集合推导式用法。分享给大家供大家参考,具体如下:推导式comprehensions(又称解
- <% Dim aData aData = Array(3,2,4,1,6
- 1.多边形的绘制案例# 多边形的绘制案例import turtledef main():turtle.color("green&q
- 要随机生成字符串代码如下: 在MySQL中定义一个随机串的方法,然后再SQL语句中调用此方法。 随机串函数定义方法: CREATE DEFI
- 安装方法一: ①进入python文件夹执行指令(前提是支持pip指令):pip3 install Beautifulsoup4②回
- 题目:一个txt文件中已知数据格式为:C4DC4D/mayaC4DC4D/suC4D/max/AE统计每个字段出现的次数,比如C4D、may
- 导言在前面三节的示例中,GridView和DetailsView控件使用的是绑定列和CheckBoxField(绑定GridView和Det
- 最近在研究pathon的命令行解析工具,argparse,它是Python标准库中推荐使用的编写命令行程序的工具。以前老是做UI程序,今天试
- 1、使用 runefunc BenchmarkSubstr1(b *testing.B) {s := "bench基准测试,121