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()

服务器端接收到的数据:

Python数据传输黏包问题

由于客户端两条数据发送间隔太短且数据包太小,被服务器端误认为是一条数据。

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()

服务器端接收到的数据:

Python数据传输黏包问题

6.黏包的成因

①服务器端出现黏包:接收方不知道消息之间的界限,不知道一个消息要提取多少字节的数据造成的;

②客户端出现黏包:TCP在发送数据少且间隔时间短的数据包时,会将几条合并一起发送。

来源:https://blog.csdn.net/qq_40523659/article/details/121695950

标签:Python,数据,传输,黏包
0
投稿

猜你喜欢

  • Python判断变量是否为Json格式的字符串示例

    2023-11-12 04:48:29
  • 关于Python 常用获取元素 Driver 总结

    2022-12-24 05:03:28
  • Python学习之自定义异常详解

    2021-05-05 18:46:20
  • php版微信公众账号第三方管理工具开发简明教程

    2024-04-30 08:47:46
  • python Tensor和Array对比分析

    2023-08-27 04:37:02
  • 利用Python将图片中扭曲矩形的复原

    2022-05-24 21:35:54
  • PHP遍历目录函数opendir()、readdir()、closedir()、rewinddir()总结

    2024-05-03 15:53:21
  • python3+selenium4实现切换窗口与iframe的方法

    2022-08-08 16:34:16
  • python 用opencv调用训练好的模型进行识别的方法

    2022-11-14 11:57:23
  • 使用Python可设置抽奖者权重的抽奖脚本代码

    2023-08-27 09:17:19
  • Python装饰器详细介绍

    2022-09-28 17:52:16
  • Python中处理字符串之endswith()方法的使用简介

    2023-02-25 09:05:36
  • python保留两位小数的3种方法实例

    2022-01-28 20:20:36
  • Python在Matplotlib图中显示中文字体的操作方法

    2023-03-30 00:29:54
  • Python爬虫包BeautifulSoup异常处理(二)

    2021-12-09 21:53:42
  • Python实现冒泡排序算法的完整实例

    2021-03-04 10:47:33
  • Windows下MySQL 5.7无法启动的解决方法

    2024-01-26 02:32:31
  • python matplotlib库绘制散点图例题解析

    2023-08-14 03:12:56
  • JavaScript中定义函数的三种方法

    2024-05-09 10:37:04
  • vue中element-ui表格缩略图悬浮放大功能的实例代码

    2024-05-29 22:44:31
  • asp之家 网络编程 m.aspxhome.com