【转】常见下载方式之BT下载实现过程详解

2024-01-13 05:50

本文主要是介绍【转】常见下载方式之BT下载实现过程详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Overview

    • 一、BT下载是怎么来的?
    • 二、BitTorrent的P2P下载是怎么做到的?
    • 三、BT协议之连接TrackerServer
    • 四、BT协议细节之连接Peers



转载来源:常见下载方式之BT下载实现过程详解 ?

一、BT下载是怎么来的?

在互联网上下载文件的方式大概有这么几种:FTP、HTTP、BT、eMule(电驴)等, 浏览器会直接支持FTP和HTTP下载,BT和eMule下载一般需要专用的下载软件的支持。

接下来分别简单介绍一下它们的区别:

FTP 是 File Transfer Protocol(文件传输协议)的英文简称,顾名思义,就是提供文件传输的一个协议。首先需要有一个FTP Server,负责文件的存储并接受网络请求(FTP连接和指令)提供下载,然后FTP Client 向FTP Server发起网络请求,并将接受到的文件内容保存到本地。

HTTP是HyperText Transfer Protocol (超文本传输协议)的英文简称,超文本就是我们平时所说的网页,通过网页上的链接把众多的网页组织成一个超级大的信息节点网络,所以叫超级文本。文件下载只是HTTP协议所支持的一个子功能,同样需要HTTP Server (Nginx、Apache、IIS等)和 HTTP Client (各种浏览器)来完成文件的下载。

对以上两种下载方式做一个简单总结:

img

HTTP下载

如果用户想要更快的下载速度呢?

一种选择是,Client使用多线程下载,抢占更多的服务器资源(早期的网际快车FlashGet就是这种方式)。

如果用户量很大,这样无疑对Server造成很大的压力。然后呢,Server提供商(网站方)需要提供更多的服务器和更高的带宽,但是这需要花很多钱。

那么,有没有更低成本的解决方案呢?接下来就出现了BT下载。

BT是BitTorrent的缩写,Torrent是激流、洪流的意思,Bit洪流,看名字就很牛的样子。和以上两种下载方式最大的区别就是用户不再直接从服务器下载文件,而是用户之间相互下载,这种方式叫做P2P (Peer to Peer 点对点)。从下图我们可以看出参与的人越多,下载速度越快

img

P2P下载

二、BitTorrent的P2P下载是怎么做到的?

要做到P2P下载首先需要解决如下两个问题:

1、 如何知道哪些Client在下载同一个文件?

2、 对某一个文件,如何做到同时从多个来源进行下载?

对于第一个问题的解决方案:

设计一个TrackerServer(跟踪服务器),每一个Client需要去这里上报自己正在下载的文件以及自己的ip地址和监听的端口。新来的Client先要连接到TrackerServer,根据要下载的文件查询当前正在下载这个文件的Clients (Peers)。

对于第二个问题的解决方法:

Client从TrackerServer获取Peers后,分别向他们发起连接并询问当前的下载进度,然后,同时连接多个Peers分别下载他们已完成的文件片段,最后拼接出完整的文件。

那么对于下载进度应该如何表达呢?

因为文件不是被顺序下载的(因为需要从Peers同时下载不同的片段),所以不可以通过当前已完成的字节数来表示进度。那么,最简单有效的方式就是把文件分割成相同大小的片段(Piece),片段的大小一般是2n,比如218=256K,通过已完成Pieces的序号列表来表示当前的下载进度。

另外,因为Pieces序号是连续的,可以通过BitMap的方式表示每个Piece Index是否已完成。Piece Index所在的bit位为1,表示该Piece已经下载完成。

如果下载任务是一个文件夹(包含很多文件), 可以把这些文件按照固定的顺序连接起来(逻辑上)进行Pieces切分。

当Client获取到Peers的完成列表后,就可以将不同的Pieces分配到对应的Peers进行并行下载,同时将自己已完成的Pieces提供给其他Peers来下载。

互帮互助、互通有无的和谐社会就此开启了。

到目前为止,我们还有几个关键问题没有解决:

1、怎么找到待下载文件的TrackerServer?

2、Peers对文件分片的规则是否一致?

3、在TrackerServer上怎么唯一的标识一个下载任务?

4、下载来的Pieces是否在传输过程中出现了错误或者被恶意篡改?

为了解释上面的问题,此处应该有.torrent文件(BT种子)出场了。

BT种子文件主要包括如下关键信息:

img

BT种子文件主要信息

我们找一个种子文件片段来瞧一下:

img

是不是有似曾相识却又看不懂的感觉呢?这是因为.torrent文件是bencoding编码表示的。

bencoding编码是一种对象序列化表示法(功能和json是一样的,但是规则不一样),bencoding 编码通过开头的字符来指定接下来的对象的类型,规则如下:

'd’开头表示是dict类型,可以理解为key=>value的集合,'e’表示结束

‘l’(小写字母L)开头表示是list类型,'e’表示结束

‘i’ 开头表示是integer类型,'e’表示结束,可以表示负数

数字 开头表示string类型,数字为string的长度,长度与string内容以’:'分割开

上图中标注的地方8:encoding5:UTF-84:infod5:files,按照这个规则解析后得到

encoding=>UTF-8

info => { files=> …}

至此,总结一下BT下载的基本过程, 聪明的你是否已经了解BT下载了呢?

img

BT种子下载过程

接下来是对BT 协议的一些细节描述,对细节感兴趣的话可以继续看一下

三、BT协议之连接TrackerServer

TrackerServer有HTTP和UDP协议两种,这里简单介绍一下HTTP协议的TrackerServer,BTClient通过 HTTP Get请求完成Peers获取和自身的注册。请求的URL格式如下:

Trackerserver-url?info_hash=xxxxxxxxxxxx,peer_id=xxxxxxxxxxx,ip=x.x.x.x,port=xxxx,uploaded=xx,downloaded=xx,left=xx,event=x

URL中各参数需要经过urlencode处理,各个参数的意义如下:

img

TrackerServer的返回内容为经过bencode的Dict类型,如果返回失败,会包含"failure reason" 键值,内容为可读的失败原因。

“interval”: 为向Trackerserver发起常规查询的间隔时间,BTClient需要按照这个间隔时间定期向TrackerServer报告下载状态,同时获取最新的Peers信息。

“peers” :为一个Peer List,每个Peer包含以下几项内容:

“peer id” : 为20字节的Peer自分配ID

“ip” : Peer IP地址

“port”: Peer 监听的端口

抓包得到的一个TrackerServer的返回内容, 经过bencode解析后如下:

{interval =>1800

peers => [

​ {

ip => 100.197.121.204,

peer id => -SD0100-\310\225\2576z\264U\240O\034

​ port => 14678

​ }

…//其他Peer

]

关于peers列表,当前大多数TrackerServer支持compact peers格式以减少返回内容的长度,该格式下peers属性为一个String,每六个字节为一组,每组表示一个Peer,其中前4个字节 表示PeerIP,后两个字节表示Peer Port。

四、BT协议细节之连接Peers

与Peer建立TCP连接后,首先发送HandShake消息进行协议基本信息的交换,协商成功后,紧接着开始送各自的PiecesBitmap(bitfield消息)。然后向对端发送自己缺失的Pieces请求(request消息),开启Pieces交换下载。

Handshake消息主要是协商协议名称、Info Hash和PeerID,保证对端是相兼容的Peer,如果信息协商不上(比如协议名称不是BitTorrent Protocol, 或者Info Hash不一致), TCP连接将被关闭。HandShake消息格式如下:

img

HashShake成功之后就开始通过如下一系列peer_msg消息来完成下载控制, peer_msg消息格式如下:

img

msg_len(4字节)

msg_type(1字节)

payload(若干字节)

如果msg_len = 0 , 这表示KeepAlive消息,KeepAlive用来判断对端是否仍然存活。

消息类型的取值及作用:

img

如下是一个request和一个piece消息:

img

choke, unchoke, interested, not interested消息综合完成Peers的流控策略,以期达到更好的网络吞吐以及维持下载的公平性,一个指导思想是更多的上传将获得更多的下载。

在BTClient的实现过程中还会涉及到很多的程序设计问题,比如:异步socket操作、多线程控制、流量控制、缓存策略、下载优先级、文件存储等,这里就不再一一展开了。

注:本文由点量软件整理自互联网DolitQin520(V)

这篇关于【转】常见下载方式之BT下载实现过程详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/600432

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo