欢迎光临BDM
一枚菜鸟码农的成仙之路

BT协议学习笔记

前言

最近对 4K 电影有需求,但 4K 电影都不景气,网上动辄 40-50 GB 的种子,无疑增大了 4K 电影的传播难度,下的人越少,下得越慢,并且高额容量也给了持续做种的人不小的压力。

月初清明节时,我把电脑开机三天三夜,终于以平均 100Kbps 的速度下了 30GB 之后彻底 0 下载速度,上传倒是没停过,我确实没什么耐性等待其他人做种了,甚至剩余的 20GB 不再有人继续做种也有可能。心疼电费又舍不得开 115 会员的我本要告别 4K 了,突然想到了自己买来闲置在那里的服务器,何不拿来搭一个自己的离线服务器呢?于是开始着手学习 BT 协议,并在这里记录下来。

BT 协议基础知识

BT 协议全称 Bit Torrent 协议,是一个基于 P2P(Peer-to-peer 点对点对等网络通讯)思想,架构在应用层上的文件传输协议。BT 下载改变了传统单点下载服务器高上传带宽,以及下载者越多速度越慢的状态,使每一个下载者能互相通讯交换数据,对于大文件有非常可观的提升效果。BT 的出现对互联网的生态产生了动荡性的改变,促使了网络各节点服务器的配置提升,以致于不太火的今日,仍然有许多非常多的局部网络提供商,禁止 P2P 下载以防止对上传带宽的高压考验。下面将简要介绍一下 BT 协议的通信原理。

BT 议基本流程

首先,由下载提供方使用“种子生成工具”将原始文件生成“种子文件”,然后将“种子”发布给BT下载者,BT 下载者根据“种子”内容,先去下载提供方的原始文件,等下载量到一定数量之后就由BT下载者相互连接并传输未下载完成的文件了。

片段机制与上传下载

那么单个大文件该如何互相传输呢?BT 协议使用虚拟的片段机制,将所有文件分成一小块一小块的片段,每个片段进行 Hash 编码,用以识别该片段并能检测该片段下载是否正确,这些 Hash 编码全部储存在种子文件中。

片段的大小可以自行设置,设置得越小,片段就越多, BT 分发的灵活度也会上升(想象一下在菜市场千张一元与十张一百的差距),但与之俱来的是种子文件会越大,片段效验的通讯成本,以及本地进行 Hash 效验的成本也会上升。

BT 客户端

每一个 BT 下载者使用的下载工具便是 BT 客户端。客户端包含了下载及上传的功能,一般也包含制作“种子文件”的功能。使用客户端能控制任务的上传及下载速度,良好的BT环境需要大家在力所能及的时候贡献上传速度。

客户端也提供了“做种”功能,在原始文件下载结束后,可选择继续上传一段时间来维持“种子”的生命力,一个“种子”若其流通的文件都凑不齐完整的原始文件,也宣告“种子”的生命结束。

种子文件

种子文件由原始文件的提供者生成,包含了文件的 Hash 字典和名称、片段等属性,以及负责分享下载者 IP 的 Tracker 服务器地址列表。种子信息采用了 Bencode 编码方法,可以将字典,数组,等编码成明文字符串文本,存储在种子文件中。种子文件在 BT 协议中有着至关重要的作用,但在其生命周期结束后,便一无是处了。

Tracker 服务器

BT 下载者们如何准确的在互联网中发现其他下载者的呢?这就要依靠中央通讯服务器 Tracker 了。Tracker 服务器维护了一个种子的在线下载者列表,实时向 BT 下载者提供所有下载者的信息。BT 客户端不断地轮询着 Tracker 来获取其他下载者的位置,再遍历对其通信以建立 P2P 连接进行数据交换。

实际上,当一个“种子”创建时,创建者需要显式地指定 Tracker 服务器的地址,然后交由 Tracker 服务器托管,并将可用的 Tracker 服务器地址存储在“种子文件”中。由于这一步大多数客户端从“做种”到“解析种子”都帮我们做了,所以在 BT 下载者的视角里没有 Tracker 服务器的存在,但需要优化种子文件的下载速度,我们需要灵活调整 Tracker 服务器列表达到目的。

BT 拓展协议

超级种子协议

当种子开始生命周期后,若下载速度很快的用户下载完成时,立即停止了继续做种,全程只提供了少量数据给其他用户,但是又占据了整个网络大部分的带宽,对整体速度产生了影响,为了避免这种情况,推出了“超级种子协议”。

超级种子协议不再一次性提供所有的文件,而是将文件分成多批放出,延长总体下载时间,这样,能使下载速度很快的用户也参与到文件的分享中,而不会只当BT网络的“吸血”者。

DHT(Distributed Hash Table)协议

传统BT协议有一个很大的问题,那就是非常依赖于 Tracker 服务器,一旦 Tracker 服务器宕机,整个 BT 网络将由此瘫痪。在这个基础上,又提出一种分布式哈希表的协议,简称 DHT。实现了 DHT 的 BT 客户端会将 Tracker 提供的信息缓存在本地中,并在与其他 BT 客户端进行 P2P 连接时交换 DHT 信息,倘若 Tracker 宕机,BT 客户端数据仍然会缓慢的在各个节点之间流通。

磁力链接

说到 BT 协议,免不了提及同样去中心化的下载方式——磁力链接。磁力链接客户端将这一串“万能”字符串转化成单一文件,接着开启 P2P 传输进行下载,同样非常神奇。实际上,磁力链接由于只支持单一文件,通常用于种子文件的下载,再从种子种解析出目标文件。磁力链接借助的是 DHT 网络进行下载,内部存储了目标文件的散列特征值,依此在 DHT 网络进行检索目标文件,然后借助 P2P 下载目标文件。

BT 协议关键算法

片段交换算法

上文提到过,BT 协议中客户端需要遍历其他节点来试图建立连接,然后互相交换未拥有的片段,这里就产生了一个问题,我该如何选择先下载哪个片段呢?一般不能选择全部同时下载,已知片段已经是BT协议的最小文件粒度了,全部同时下载会导致每个片段的速度平均变慢,一旦某些节点停止服务,将造成大量片段的失效以至于需要重新下载,得不偿失。

最少优先原则。有一个 BT 协议默认的下载逻辑是:优先下载每个节点片段总和中占比较少的那些,这样能保证不会因为拥有这些较少片段的客户端停止运行而导致整个网络的生命结束,在该原则的运行下,每个片段都能够几乎均匀的存在于网络上。

随机选取原则。在种子生命周期的一开始,如果仍然依靠最小优先原则来实行,则会导致整个网络里因为请求最小资源而效率及其底下,故在这个时候,采取强制随机的策略,让所有客户端随机选取片段进行下载,先充实整个网络为主。

就近索取原则。当从一个节点获取到片段时,优先从该节点获取临近片段。这是一个优化算法,用于减少检索的时间,因为可能需要花大部分时间来轮询网络上的节点,但是如果你从一个节点里获取到数据后,这个节点很可能有临近节点的数据并愿意传输给你。

未完待续

最近在啃 mpetazzoni/ttorrent 的 BT 片段实现,希望在另一个台机器上再实现 BT 片段合成。

另外,远程 BT 实现有一个比较好用的 jpillora/cloud-torrent, 但只适合硬盘比较大的情况。

本文遵守知识共享署名-相同方式共享 4.0 国际许可协议,未经允许不得转载BigDickMan » BT协议学习笔记

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

联系我们GitHub