Python数据传输黏包问题

目录
  • 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数据传输黏包内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 在python环境下运用kafka对数据进行实时传输的方法

    背景: 为了满足各个平台间数据的传输,以及能确保历史性和实时性.先选用kafka作为不同平台数据传输的中转站,来满足我们对跨平台数据发送与接收的需要. kafka简介: Kafka is a distributed,partitioned,replicated commit logservice.它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现.kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外ka

  • 使用python实现http及ftp服务进行数据传输的方法

    服务器之间的http数据传输 直接使用python内置的http服务: python -m SimpleHTTPServer 8000 此时,输入指令的目录就已经开启了http服务,8000为端口(如不指定,默认为8000),如果我们需要在其他机器下垃取该目录下的文件,只需在目标机器运行: wget ip:port/文件名 速度杠杆的. 开启ftp上传文件 安装ftp的python第三方组件 pip install pyftpdlib 编写启动脚本 from pyftpdlib.authoriz

  • python实现udp数据报传输的方法

    本文实例讲述了Python实现UDP数据报传输的方法,非常具有实用价值.分享给大家供大家参考.具体方法分析如下: 服务端代码: import socket port = 8081 s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #从给定的端口,从任何发送者,接收UDP数据报 s.bind(("",port)) print 'waiting on port:',port while True: data,addr = s.recvf

  • Python爬虫抓取手机APP的传输数据

    大多数APP里面返回的是json格式数据,或者一堆加密过的数据 .这里以超级课程表APP为例,抓取超级课程表里用户发的话题. 1.抓取APP数据包 方法详细可以参考这篇博文:Fiddler如何抓取手机APP数据包 得到超级课程表登录的地址:http://120.55.151.61/V2/StudentSkip/loginCheckV4.action 表单: 表单中包括了用户名和密码,当然都是加密过了的,还有一个设备信息,直接post过去就是. 另外必须加header,一开始我没有加header得

  • python使用tcp传输图片数据

    本文实例为大家分享了python使用tcp传输图片数据的具体代码,供大家参考,具体内容如下 数据包格式如下 客户端: import socket import sys HOST,PORT = "172.18.0.3",19984 def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((HOST, PORT)) #包头标志 arrBuf = bytearray(b'\xff\xa

  • 对python中基于tcp协议的通信(数据传输)实例讲解

    阅读目录 tcp协议:流式协议(以数据流的形式通信传输).安全协议(收发信息都需收到确认信息才能完成收发,是一种双向通道的通信) tcp协议在OSI七层协议中属于传输层,它上承用户层的数据收发,下启网络层.数据链路层.物理层.可以说很多安全数据的传输通信都是基于tcp协议进行的. 为了让tcp通信更加方便需要引入一个socket模块(将网络层.数据链路层.物理层封装的模块),我们只要调用模块中的相关接口就能实现传输层下面的繁琐操作. 简单的tcp协议通信模板:(需要一个服务端和一个客户端) 服务

  • python网络编程之数据传输UDP实例分析

    本文实例讲述了python网络编程之数据传输UDP实现方法.分享给大家供大家参考.具体分析如下: 一.问题: 你觉得网络上像msn,qq之类的工具在多台机器之间互相传输数据神秘吗?你也想玩一下在两台机器之间传数据吗?今天让python告诉我们基本原理吧,当然只是做简单的了解,实际情况复杂的多.      我们今天用python实现一个简单的udp程序. 二.程序实现: 1) 使用模块 (socket)套接字模块: 套接字模块是一个非常简单的基于对象的接口,它提供对低层BSD套接字样式网络的访问

  • python使用socket高效传输视频数据帧(连续发送图片)

    目录 遇到的问题 代码问题记录(需要代码的可以直接文末) 代码 客户端clien.py 服务端server.py 遇到的问题 网上找了一些代码,都是只能建立一次socket传输一张图片,然后断开重新连重新传.而建立一次socket代价不小,反复建立会非常消耗系统资源,因此尝试自己通过一次socket连续传输多张图片 代码问题记录(需要代码的可以直接文末) 在做的过程中发现了一些问题: socket在传一张图片时是以二进制流的形式传输,图片的二进制流比较大,一般一次传不完,要传很多次.那么接受者是

  • python 中Arduino串口传输数据到电脑并保存至excel表格

    起因:学校运河杯报了个项目,制作一个天气预测的装置.我用arduino跑了BME280模块,用蓝牙模块实现两块arduino主从机透传.但是为了分析,还需要提取出数据.因此我用python写了个上位机程序,用pyserial模块实现arduiho和电脑的串口通讯,再用xlwt模块写入excel表格,用time模块获取时间作为excel的文件名. import xlwt import time import serial #设置表格样式 def set_style(name,height,bold

  • Python数据传输黏包问题

    目录 1.socket黏包问题原理 2.UDP协议 3.TCP协议 4.发送方出现的黏包 5. 接收方出现的黏包 6.黏包的成因 1.socket黏包问题原理 黏包:指数据与数据之间没有明确的分界线,导致不能正确的读取数据. 应用数据想要发送数据就必须将数据交给操作系统,而操作系统需要同时为所有的应用程序提供数据传输服务,就意味着不可能马上将应用数据发送,就需要为程序提供一个缓冲区,用于临时存放数据. 当发送数据很快,有两条数据都在缓冲区时,操作系统可能将两个数据发给接收方,数据之间没有分界线,

  • python 用struct模块解决黏包问题

    为什么会出现黏包现象: 首先只有在TCP协议中才会出现黏包现象,是因为TCP协议是面向流的协议,在发送的数据传输的过程中还有缓存机制来避免数据丢失,因此,在连续发送小数据的时候,以及接收大小不符的时候容易出现黏包现象.本质还是因为我们在接收数据的时候不知道发送的数据的长短. 解决黏包问题 在传输大量数据之前首先告诉接收端要发送的数据大小,如果想更漂亮的解决问题,可以通过struct模块来定制协议. struct模块: 功能:可以把一个类型,如数字,转成固定长度的bytes. import str

  • python中numpy包使用教程之数组和相关操作详解

    前言 大家应该都有所了解,下面就简单介绍下Numpy,NumPy(Numerical Python)是一个用于科学计算第三方的Python包. NumPy提供了许多高级的数值编程工具,如:矩阵数据类型.矢量处理,以及精密的运算库.专为进行严格的数字处理而产生.下面本文将详细介绍关于python中numpy包使用教程之数组和相关操作的相关内容,下面话不多说,来一起看看详细的介绍: 一.数组简介 Numpy中,最重要的数据结构是:多维数组类型(numpy.ndarray) ndarray由两部分组成

  • 浅谈Python中用datetime包进行对时间的一些操作

    1. 计算给出两个时间之间的时间差 import datetime as dt # current time cur_time = dt.datetime.today() # one day pre_time = dt.date(2016, 5, 20) # eg: 2016.5.20 delta = cur_time - pre_time # if you want to get discrepancy in days print delta.days # if you want to get

  • Python的pycurl包用法简介

    pycurl是功能强大的python的url包,是用c语言写的,速度很快,比urllib和httplib都快 调用方法: import pycurl c = pycurl.Curl() c.setopt(pycurl.URL, 'http://api.minicloud.com.cn/statuses/public_timeline.xml') import StringIO #这个用到里面的write函数 b = StringIO.StringIO() c.setopt(pycurl.WRIT

  • 详解Python编程中包的概念与管理

    Python中的包 包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的Python的应用环境. 考虑一个在Phone目录下的pots.py文件.这个文件有如下源代码: #!/usr/bin/python # -*- coding: UTF-8 -*- def Pots(): print "I'm Pots Phone" 同样地,我们有另外两个保存了不同函数的文件: Phone/Isdn.py 含有函数Isdn() Phone/G3.py 含有函数G3() 现

  • python查看zip包中文件及大小的方法

    本文实例讲述了python查看zip包中文件及大小的方法.分享给大家供大家参考.具体实现方法如下: #!/usr/bin/env python import zipfile z = zipfile.ZipFile("test.zip","r") for filename in z.namelist(): print 'File:',filename, bytes = z.read(filename) print 'has',len(bytes),'bytes' 希望

  • Python基于PyGraphics包实现图片截取功能的方法

    本文实例讲述了Python基于PyGraphics包实现图片截取功能的方法.分享给大家供大家参考,具体如下: 先安安装PyGraphics包 (python import media模块) 有一段代码要import media,打开python自带的IDLE,输入: >>>import media 就会提示没有media这个模块! 原来media模块不是系统的标准模块,需要安装第三方软件后才能用.这个库是在PyGraphics里,不过PyGraphics依赖一些别的库.可以这样安装(可参

  • Python科学计算包numpy用法实例详解

    本文实例讲述了Python科学计算包numpy用法.分享给大家供大家参考,具体如下: 1 数据结构 numpy使用一种称为ndarray的类似Matlab的矩阵式数据结构管理数据,比python的列表和标准库的array类更为强大,处理数据更为方便. 1.1 数组的生成 在numpy中,生成数组需要指定数据类型,默认是int32,即整数,可以通过dtype参数来指定,一般用到的有int32.bool.float32.uint32.complex,分别代表整数.布尔值.浮点型.无符号整数和复数 一

  • python通过elixir包操作mysql数据库实例代码

    本文研究的主要是python通过elixir包操作mysql数据库的相关实例,具体如下. python操作数据库有很多方法,下面介绍elixir来操作数据库.elixir是对sqlalchemy lib的一个封装,classes和tables是一一对应的,能够一步定义classes,tables和mappers,支持定义多个primary key. 定义model.py from elixir import sqlalchemy from elixir import * engine =sqla

随机推荐