目录
1.socket黏包问题原理2.UDP协议3.TCP协议4.发送方出现的黏包5. 接收方出现的黏包6.黏包的成因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在发送数据少且间隔时间短的数据包时,会将几条合并一起发送。
到此这篇关于Python数据传输黏包问题的文章就介绍到这了,更多相关Python数据传输黏包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?