坑边闲话:下载文件是现代人必备的技能之一,虽然现在流媒体服务越来越流行,但是在内容审查越来越严格的当下,掌握 P2P 下载技能十分必要。

1. P2P 下载服务·

自从互联网诞生之初就有了文件传输需求,后来随着 MP3 等音频文件的出现,快速共享音乐文件成为了彼时互联网的刚需。当年传输几百 KB 的音频对于低速互联网是个挑战,今天的互联网虽已有了长足的进步,千兆下行带宽已经普及,但是下载动辄数十乃至上百 GB 的 VR、4K 内容依旧对中心服务器的带宽产生了巨大的挑战。虽说此一时非彼一时,但道高一尺魔高一丈。科技进步催生了新的需求,新的需求又带来只有新科技才能解决的问题。

P2P 下载,本质就是为了文件共享而生。它依赖中心服务器做控制平面,但是不依赖中心服务器做内容获取,反而是从其他节点获取文件。因此,所谓的 PT/BT 文件下载,并非是严格意义上的 P2P 网络,但是它解放了中心化的内容分发服务器。

当我们的电脑启动 P2P 服务之后,我们可以通过 Torrent 种子里嵌入的 Tracker 服务器信息,往服务器注册自己的的意向,同时,服务器也会反馈给我们当前种子里列出的文件在网络中的分布情况,比如

  • 哪些节点已经完全下载完(做种)
  • 哪些节点依旧在下载
  • 哪些节点虽然没有下载完但是已经拥有了部分文件(仍可以上传这部分文件)

通过这些信息,我们可以与做种的用户取得联系,并自动从它的硬盘中获取文件的分块。与此同时,我们的下载情况也会被 Tracker 记录。

通过上述简短的描述可知,一个节点要加入 P2P 文件共享网络需要具备两个核心条件:

  1. 有人做种
  2. 你能连接到 Tracker 服务器

上述两个条件缺一不可。

  • 目前有基于 DHT (Dirstributed Hash Table) 网络的 Trackerless BT 网络。这种网络中的节点虽然不需要连接到中心化的 Tracker 服务器,但是依赖 DHT 网络宣告自己的状态信息,这与 Tracker 服务器本质上是一样的。

  • 此外,BitTorrent 协议还有一个名为 Peer Exchange 的功能,它允许 P2P 网络中的 peer 之间共享已知的 peer 状态信息。比如用户小迪持有种子 A 的所有文件,这个信息被小明知道后,小明也会悄悄地告诉他的朋友小亮,此时小亮使用种子 A 进行下载时,就会直接跟用户小迪索要文件。

简单总结一下,当你为一个种子做种时,你的 BitTorrent 客户端会在 DHT 网络或 Tracker 上宣告自己有此种子的完整或部分数据。这样,当其他用户试图下载这个种子时,他们的客户端会在 DHT 或 Tracker 上查询有哪些用户(即节点或 peers)可以提供这个种子的数据。以下是具体的查询工作流程:

  • 使用 Tracker:如果种子使用了 Tracker,当你开始做种时,你的客户端会定期向 Tracker 报告其状态(例如,你有哪些文件片段,你的下载和上传速度等)。当其他用户下载这个种子时,他们的客户端会从 Tracker 请求做种用户的列表,Tracker 会返回一个如你的 IP 地址的列表。
  • 使用 DHT:如果你开启了 DHT 功能,当你开始为种子做种时,你的客户端会在 DHT 网络上宣告它有该种子的数据。当其他用户下载这个种子并且他们也开启了 DHT 功能时,他们的客户端会在 DHT 网络上查询可以提供数据的节点(即用户)。DHT 网络会返回可以提供数据的节点列表,如你的 IP 地址。

2. P2P 下载软件选择·

目前,P2P 下载软件已经成为免费大众软件,网络上有许多好用的软件可用,比如

  • uTorrent
  • 迅雷
  • qBitTorrent

这些软件有的收费,有的免费;有的遵循 torrent 网络的核心思想,有的有自己的小九九。目前来看,广泛为用户接受的是 qBitTorrent,这是一款开源的功能强大的免费软件,有多种平台支持。

2.1 安装方式·

作为一种基本服务,我们希望它是 SaaS 的,即有自己的服务器端,同时能在浏览器里进行全部的控制。幸运的是,qBitTorrent 正是如此。

注意:有人希望安装容器版本的 qBitTorrent,诚然,容器作为可部署任何服务的基本工具,自然也能支持 qBitTorrent. 但是不得不承认,qBitTorrent 在做种的过程中,需要与另外的用户进行交流,因此依赖多个端口。容器部署可以选择 host 类型的网络解决这一需求,但是 host 网络在容器实现中并不常见,因此不推荐使用容器部署该服务。

这里笔者选择在 Windows Server 2022 上部署 qBitTorrent,安装只需要保持默认即可。

2.2 使用方式·

推荐使用 qBitTorrent 的 WebUI 进行操作。虽然有很多开发者做了更好看的 WebUI,但是综合来看,官方版功能最全面也没什么 bug.

图 1. qBitTorrent 开启 WebUI 访问,可以方便地通过浏览器访问。

2.3 流程自动化·

我们希望下载、元数据刮削等工作可以自动完成而无需人工介入。但是这个实现是比较困难的。此外,下载完成之后的选择也比较多样化。比如,我日常使用北邮人教育网 PT 站进行资源下载、上传。为了做状态区分,我使用了两个文件夹:

  • byr-downloading: 存放我当前尚未完成的任务
  • byr-finished: 存放我已经下载完的任务文件。

讨论

可能有读者会问,是否应该对不同状态的任务进行分类呢?有没有此必要性?

考虑一番后,我认为貌似是没有必要,毕竟 qBitTorrent 的软件里已经对任务进行了分组,通过状态标签就能快速检出。然而,如果软件元数据丢失,就有可能导致种子状态也随之丢失。当然这种概率并不大。因此,如今我并不是十分喜欢这种组织方式。

然而,对于要进行大量下载然后“断种”的用户,选择这种行为就是可取的。比如,可以将下载完的文件挪到 *-finished 目录,然后通过 rsync 命令批量将他们移动到合适的地方存储、刮削。

在下载完成之后,我们可以做的事情有很多。如果你需要在进行刮削、重命名之后继续做种,那就要保留原本的文件(连文件名都不能改)。合理的做法正是如此,因为你从别人那里获得了资源,你也有必要保持该文件,以备其他新用户获取。但这个需求与刮削、重命名矛盾。如果你做种的盘和刮削后存放的盘是同一个磁盘分区,则可通过硬链接的方式解决,这个方案的兼容性最好。反之,如果你需要把文件挪到别的盘再刮削、重命名,问题就比较难了。虽说可以通过软链接解决麻烦,但是 qBitTorrent 对软链接的兼容性不太好,指向你刮削、重命名后的新文件的链接有可能无法被识别为有效文件。因此这个问题非常棘手。

思辨

这是个矛盾的问题,将下载盘和永久存储盘分离,就是为了保证安全,防止因为频繁的读取导致永久存储阵列寿命降低。因此,在下载盘里保存指向永久存储的软链接无益于保护永久存储盘。还是直接保存两份比较好。不愿意做种的就删掉腾出下载盘的空间。

3. 添加更好用的 Tracker 服务器·

前面提到,能下载的必要条件是能连接到 Tracker 服务器。为了解释下面的内容,我们需要知晓做种的一般过程。

  1. 打开 BT 软件,比如 qBitTorrent,在制作 Torrent 的菜单里选择本地文件。随后 qBitTorrent 会计算文件的分块哈希,最终生成一个 .torrent 文件。
  2. 将生成的 Torrent 文件发布到 PT 网站上,其他用户就能看到你的发布,同时下载该种子。
  3. 其他用户打开之后,会根据种子的哈希值去 Tracker 服务器或 DHT 网络中查询哪个节点(IP 地址)拥有这个种子的全部或者部分文件,查询后将开始下载。
  4. 下载过程中,下载节点的信息也会发布到 Tracker 服务器或 DHT 网络,变成内容提供者。

了解了以上过程,我们可以发现添加更好用的 Tracker 服务器能让我们知道更多与该种子相关的用户,进而使得我们可以联系这些用户索要文件。此外,打开 DHT 功能也可以达到类似的功效。

图 2. 使用 qBitTorrent 软件创建种子文件。该功能在 webUI 里无法完成。

总结·

本文讨论了 qBitTorrent 在使用过程中的一些思考,作为流程中的重要一环,实现自动化是非常重要且合理的,但是如何确定自动化的细节需要一些方法论的指导,而本文的关注点就在于此。