小知识·BitTorrent 简介

BitTorrent 简介

从 P2P 说起

经常在网上飙车的老司机应该都知道 BT 下载,但是有时候拿到了种子却下载不动,会不会很抓狂,是不是还觉得是自己网不行,那作为一个合格的老司机,我们需要探究一下下载不动的原因是什么,BT的运作方式是怎样的,如果你也有这样的疑惑,那么,系好安全带,我们一起来了解一下什么是 BT。

2001年4月,程序员布莱姆·科恩设计了一种协议,然后在2001年7月2日,他发布了 BitTorrent 客户端的第一个实现。

BT(BitTorrent)是 P2P 的一种实现,P2P也叫「对等网络」(英语:peer-to-peer, 简称P2P),是一种在对等者(Peer)之间分配任务和工作负载的分布式应用架构,是对等计算模型在应用层形成的一种网络形式。在P2P网络环境中,彼此连接的多台计算机之间都处于对等的地位,各台计算机有相同的功能,无主从之分,每个节点既充当服务器,为其他节点提供服务,也能作为客户端,享用其他节点提供的服务。

P2P有着很广泛的应用,比如 P2P金融(雾),区块链,BT下载等。它的关键字是去中心化,依靠用户群(peers)来互相传输数据,符合这种特征的都可以称之为 P2P。

BitTorrent

大家肯定有在互联网上下载各种资源的经历,比如电影电视剧,我们在网上一搜,就会搜到一些不知名的小网站,网站上通常会提供一个叫做「种子」的东西,我们使用时只需要把种子下载到电脑上,通常是一个后缀为 .torrent 的文件, 然后用迅雷或者其他的下载工具下载。

在实际操作中,如果我们使用迅雷进行下载,有时候会发现种子下不动,有时候发现下的特别慢,有时候还被提示资源敏感,无法下载,还有时候迅雷提示你开会员可以加速(这个时候开一个会员基本就可以满速下载了,因为迅雷已经把资源提前下载到自己服务器了),我们可能产生一些疑惑:

种子是什么?

为什么资源有时候下不动,有时候速度那么慢?

如何才能让我的BT下载速度变快?

为了解决这个疑问,我们需要了解一下 BT 协议,全称是 BitTorrent,这个协议被设计用来实现 P2P(Peer to Peer) 下载。普通的 HTTP/FTP 下载使用 TCP/IP 协议,BitTorrent 协议是架构于 TCP/IP 协议之上的一个P2P文件传输通信协议,是一个应用层协议。

传统的下载是客户端请求服务器获取资源,下载方和资源提供方的角色很清楚。这样做的优点是简单,易于理解,我要下载东西,我就去请求服务器,缺点也很明显:

一旦服务器故障,大家都无法下载

服务器带宽有限,下载的人多速度必然下降

而 P2P 则不一样,每一个客户端同时也是服务器,从别人那里下载资源的同时,也提供资源给到别人。这样一来,就规避了服务器模型的缺点:

每个人都是服务器,除非所有机器都故障了,否则网络依旧可以运转

不会去请求单一机器,而是从多个机器获取资源,这样可以使带宽得到最大利用

种子的格式与作用

我们对 BT 的认知,一般是从种子开始的,所以首先需要了解一下种子的格式与作用。

我们一般下载下来的文件是一个以 .torrent 结尾的文件,通过文本编辑器打开,会看见一堆乱码,它并不是一个纯文本文件,而是一个二进制文件,通过查资料,可以发现种子文件中采用了一种文件编码,叫做 Bencode ,这种编码以 ACSII 字符来进行编码,里面包含几种简单的数据结构,我们一起来了解一下:

Bencode 编码

字符串

将一个字符串的前面加上长度标识和符号(冒号),这就是 Bencode 编码后的字符串了,比如:

'hello' -> 5:hello

'How are you' -> 11:How are you

整数

一个整数起始以 i 作为标识,结尾以 e 来作为标识,把数字写在中间即可,如:

123 -> i123e

666 -> i666e

0 -> i0e

列表

列表可以类比为 Python 中的列表,是一种容器性质的数据结构,每个元素可以是四种数据结构中的任意一组,没有长度限制。语法是,列表的开头和结尾分别用 l 和 e 作为标识符,中间的值就是任意的数据结构。

[123,666,0] -> li123ei666ei0ee

[123,'hello',456] -> li123e5:helloi456ee

字典

字典的开头和结尾以 d 和 e 作为标识符,bencode中的字典,key 要求必须是字符串格式的,value 的格式可以随便。另外,编码过程,key 要根据字符串的字典序进行升序排序。比如:

{'a':1,'cd':[3,4],'b':2} -> d1:ai1e1:bi2e2:cdli3ei4eee

.torrent 种子的格式

关于种子文件的定义,在官方文档:bep_0003.rst_post 里面说的很清楚。实质上,种子文件就是一个使用 Bencode 格式编码的一个 Dictionary,里面含有一些字段,声明了关于这个种子的一些信息。

大家可以把一个种子文件理解成为一个大 Json,只不过是因为压缩需要用二进制的形式存起来了而已。

我写了一个解析器,可以把不可读的 bencode 变成可读的 json 格式:

https://github.com/riba2534/bencode

我们以 Ubuntu20.04.2 官方提供的种子为例:https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/20.04.2.0/ubuntu-20.04.2.0-desktop-amd64.iso.torrent

把这个种子解析之后,会得到一个json文件,如下:

{"announce":"https://torrent.ubuntu.com/announce","announce-list":[["https://torrent.ubuntu.com/announce"],["https://ipv6.torrent.ubuntu.com/announce"]],"comment":"Ubuntu CD releases.ubuntu.com","created by":"mktorrent 1.1","creation date":"2021-02-12 03:02:32","info_hash":"4ba4fbf7231a3a660e86892707d25c135533a16a","info":{"length":2877227008,"name":"ubuntu-20.04.2.0-desktop-amd64.iso","piece length":262144,"pieces":["d89b853053ac28e09d6d322658636d9663aa80fe","287528aae8bda9ef962918ba8db2ceb0638454e4","149987b3a98147d9b5cc1e249b2fe

2025-10-03 11:17:29
小兵去质器
Matlab常用工具箱的调用命令