Torrent文件实现

2022/11/13 Python

Torrent文件实现

种子文件本质上是文本文件,包含Tracker信息和文件信息两部分。

种子定义

BitTorrent 协议的种子文件可以保存一组文件的元数据。这种格式的文件被 BitTorrent 协议所定义。扩展名一般为“.torrent”。

种子结构

.torrent 种子文件本质上是文本文件,包含 Tracker 信息和文件信息两部分。Tracker 信息主要是 BT 下载中需要用到的 Tracker 服务器的地址和针对 Tracker 服务器的设置,文件信息是根据对目标文件的计算生成的,计算结果根据 BitTorrent 协议内的 Bencode 规则进行编码。它的主要原理是需要把提供下载的文件虚拟分成大小相等的块,块大小必须为2k的整数次方(由于是虚拟分块,硬盘上并不产生各个块文件),并把每个块的索引信息和 Hash 验证码写入种子文件中;所以,种子文件就是被下载文件的“索引”。

Tracker信息主要是BT下载中需要用到的Tracker服务器的地址和针对Tracker服务器的设置;

文件信息是根据对目标文件的计算生成的,包括以下字段:

  • announce - tracker的URL
  • info - 该条映射到一个字典,该字典的键将取决于共享的一个或多个文件:
  • name - 建议保存到的文件和目录名称
  • piece length - 每个文件块的字节数。通常为28 = 256KB = 262144B
  • pieces - 每个文件块的SHA-1的整合Hash。因为SHA-1会返回160-bit的Hash,所以pieces将会得到1个160-bit的整数倍的字符串。和一个length(相当于只有一个文件正在共享)或files(相当于当多个文件被共享):
  • length - 文件的大小(以字节为单位)
  • files - 一个字典的列表(每个字典对应一个文件)与以下的键:
  • path - 一个对应子目录名的字符串行表,最后一项是实际的文件名称
  • length - 文件的大小(以字节为单位)

它的主要原理是需要把提供下载的文件虚拟分成大小相等的块,块大小必须为2k的整数次方(由于是虚拟分块,硬盘上并不产生各个块文件),并把每个块(是块,不是整个文件)的索引信息和Hash验证码写入种子文件中;所以,种子文件就是被下载文件的“索引”。

下载启动

BT客户端首先解析种子文件得到Tracker地址,然后连接Tracker服务器。 Tracker服务器回应下载者的请求,提供下载者其他下载者(包括发布者)的IP。下载者再连接其他下载者,根据种子文件,两者分别告知对方自己已经有的块,然后交换对方所没有的数据。 此时不需要其他服务器参与,分散了单个线路上的数据流量,因此减轻了服务器负担。

防止重复下载

下载者每得到一个块,需要算出下载块的Hash验证码与种子文件中的对比,如果一样则说明块正确,不一样则需要重新下载这个块。这种规定是为了解决下载内容准确性的问题。

下载过程中的变化

用户下载的文件内容越来越完整,对应的,拥有完整种子文件的用户也会越来越多,使文件的“寿命”不断延长。

算法扩展

为了解决某些用户“下完就跑”的现象,在非官方BitTorrent协议中还存在一种慢慢开放下载内容的超级种子的算法。

网络技术扩展

DHT技术可以在无Tracker的情况下下载。 DHT全称为分布式哈希表(Distributed Hash Table),是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。使用支持该技术的BT下载软件,用户无需连上Tracker就可以下载,因为软件会在DHT网络中寻找下载同一文件的其他用户并与之通讯,开始下载任务。 有些软件(如比特精灵)还会自动通过DHT搜索种子资源,构成种子市场。

磁力链接

现在我们使用迅雷等工具下载资源的时候,基本上都只需要一个叫做磁力链接的东西就可以了,非常方便。

磁力链接格式类似于 magnet:?xt=urn:btih:E7FC73D9E20697C6C440203F5884EF52F9E4BD28

分解一下这个链接

  • magnet:协议名。
  • xt:exact topic 的缩写,表示资源定位点。BTIH(BitTorrent Info Hash)表示哈希方法名,这里还可以使用 SHA1 和 MD5。这个值是文件的标识符,是不可缺少的。 一般来讲,一个磁力链接只需要上面两个参数即可找到唯一对应的资源。也有其他的可选参数提供更加详细的信息。
  • dn:display name 的缩写,表示向用户显示的文件名。
  • tr:tracker 的缩写,表示 tracker 服务器的地址。
  • kt: 关键字,更笼统的搜索,指定搜索关键字而不是特定文件。
  • mt:文件列表,链接到一个包含磁力链接的元文件 (MAGMA - MAGnet MAnifest)。

种子-磁力联系

磁力链接的唯一标识符就是 40 个 16 进制字符码,也就是 magnet:?xt=urn:btih:E7FC73D9E20697C6C440203F5884EF52F9E4BD28中的 E7FC73D9E20697C6C440203F5884EF52F9E4BD28。这个同时也是种子文件的 info_hash,是每个种子的唯一标识码。根据它就能将磁力链接于种子联系起来,得到资源的详细信息,进而下载资源。

Tracker简介

在BT下载中,有一个非常重要的角色,那就是Tracker服务器。Tracker会追踪有多少人在下载同一文件,并把这些名单发送到BT软件上。BT软件再尝试连接这些用户,以此来给你提供下载速度,同时你也会给他们贡献速度。

简单来说,Tracker服务器起到的,就是牵线搭桥的作用,而这正是BT下载的核心。越热门、越优质的Tracker,资源解析速度及下载速度就越快。普通BT软件速度不稳定,就是因为内置的Tracker太少。

opentracker是一个linux中开源和免费的BitTorrent Tracker ,旨在实现一个最小化资源使用,并且可以在无线路由器中使用的轻量级tracker服务器。

opentracker官网地址:https://erdgeist.org/arts/software/opentracker/

DHT

BitTorrent 使用”分布式哈希表”(DHT)来为无 tracker 的种子(torrents)存储 peer 之间的联系信息。这样每个 peer 都成了 tracker。这个协议基于 Kademila 网络并且在 UDP 上实现。DHT 由节点组成,它存储了 peer 的位置。BitTorrent 客户端包含一个 DHT 节点,这个节点用来联系 DHT 中其他节点,从而得到 peer 的位置,进而通过 BitTorrent 协议下载。 peer: 一个 TCP 端口上监听的客户端/服务器,它实现了 BitTorrent 协议。 节点: 一个 UDP 端口上监听的客户端/服务器,它实现了 DHT(分布式哈希表) 协议。

Python实现下载

libtorrent是功能齐全的p2p协议开源C ++ bittorrent源码实现,专注于效率和可伸缩性。它可以在嵌入式设备和台式机上运行。它拥有完善的文档库,易于使用。 它提供了client_test可以用于解析torrent种子和磁力链接,可根据磁力链接直接下载文件,对于正在下载的视频文件,用其他播放器可边播放边下载。常见使用libtorrent库的项目有qBittorrent,deluge,Free download manager等。

import libtorrent as lt

# 创建 session 对象
ses = lt.session()
ses.listen_on(6881, 6891)

# 添加磁力链接到下载队列
params = {'save_path': 'D:/demo'}
link = 'magnet:?xt=urn:btih:...'
handle = lt.add_magnet_uri(ses, link, params)

# 等待下载完成
print('downloading metadata...')
while not handle.has_metadata():
    s = handle.status()
    progress = s.progress * 100
    print('%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d)' %
          (progress, s.download_rate / 1000, s.upload_rate / 1000, s.num_peers))


# 开始下载
print('starting', handle.name())
while not handle.is_seed():
    s = handle.status()
    progress = s.progress * 100
    print('%.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d)' %
          (progress, s.download_rate / 1000, s.upload_rate / 1000, s.num_peers))

libtorrent源码

bt协议有早起的tracker版本(俗称bt1.0)和现在常用的基于DHT的版本(俗称bt2.0),下文为整理的协议相关资料。

Search

    微信好友

    博士的沙漏

    Table of Contents