BitTorrent协议可分为以下五个主要部分:
- MetaInfo文件 - 包含协议运行所需的所有详细信息的文件。
- Tracker - 帮助管理BitTorrent协议的服务器。
- Peers - 用户通过BitTorrent协议交换文件数据。
- Data - 通过协议传输的文件。
- 客户端 - 位于peers计算机上并实现协议的程序。
Peers使用TCP(Transport Control Protocol)来传输和发送数据。
该协议优于其他协议,如UDP(User Datagram Protocol),因为它保证了数据从发送方到接收方的可靠和按序传送。
UDP不能提供这样的保证,数据可能变得混乱,或者一起丢失。
Peers通过HTTP(超文本传输协议)通过纯文本与Tracker进行通信。
下图说明了Peers如何彼此交互,并与Tracker进行通信。
Data
BitTorrent功能非常强大,可用于传输任何数量目录中包含的任何类型的多个文件中的单个文件。 文件大小可能千差万别,从千字节到数百千兆字节。
Piece Size
Data根据bittorrent被分为较小片段在peers之间传输。这些片段的大小是固定的,这使得Tracker能够监视谁拥有哪些数据。
这也将文件分解为可验证的片段,然后可以为每个片段计算其hash值,其他peer下载时可以检查它们的数据完整性。
这些hash值被存储为'Metinfo文件'的一部分,这将在下一节讨论。
除了最后一块片段的大小是不规则的,其余片段的大小都是一致的。
最后一个片段的大小取决于文件的总大小,例如, 一个1.4Mb的文件可分为以下几个部分:
这显示了5 * 256kb的片断,并且最后一片是120kb。
当片段太大时会导致下载时的效率降低, 因为随着数据完整性检查频率的降低数据失败的概率增加了, 相反, 如果一个片段太小,那么就会需要更多的
hash检验。
随着片段数量的增加, 更多的hash值需要被存储到MetaInfo文件中。一般来说,分片段应该让MetaInfo文件不超过 50-70Kb,
其主要原因是限制索引服务器所需的主机存储量和带宽。 最常见的尺寸是256kb,512kb和1mb,那么片段数是: 总大小/片段大小。
顺便一提,片段可能与文件边界重叠。
MetaInfo File
当有人想使用BitTorrent协议发布数据时,他们必须创建一个MetaInfo文件。 这个文件是特定于他将要发布的数据的, 而且它包含了关于那个torrent的
所有信息,例如将要包含的数据,Tracker的ip地址等。Tracker是一个“管理”torrent的服务器,将在下一节中讨论。
MetaInfo文件被赋予一个'.torrent'扩展名,并且数据是由BitTorrent客户端从文件中提取的。
BitTorrent客户端是在用户计算机上运行的程序,并实现了bittorrent协议。 每个MetaInfo File都必须包含以下信息("key"):
- info:描述文件的字典。 无论是单个文件还是目录结构的更多文件。 以及SHA-1格式存储的每个数据片段的哈希。
- announce: 字符串。tracker的announce url。
可能包含的额外信息: - announce-list: 用于列出所有备份trackers
- creation date: 这个torrent的创建时间戳(unix)
- comment: 作者的评论
- created by: 用于创建此MetaInfo文件的程序名字和版本
以下是一个MetaInfo文件的例子:
{‘info’: {‘piece length’: 131072,
‘length’: 38190848L,
‘name’: ‘Cory_Doctorow_Microsoft_Research_DRM_talk.mp3’,
‘pieces’: ‘\xcb\xfaz\r\x9b\xe1\x9a\xe1\x83\x91~\xed@\…..’,
}
‘announce’: ‘http://tracker.var.cc:6969/announce’,
‘creation date’: 1089749086L
}
注意: 上面显示的并不是实际上torrent文件真正的内容, 事实上, 上述内容还需要通过一种称为"Bencoding"的方法编码。
Bencoding
BitTorrent使用Bencoding在BitTorrent客户端和tracker之间发送结构松散的数据。
Bencoding 支持字节字符串, 整数, 列表和字典四种结构。
它分别使用'i'/'l'/'d'作为整数,列表和字典的开始分隔符。 这三种类型的结束分隔符都是'e'。字节字符串没有分隔符。
Bencoding 结构:
- 字节字符串: <string length in base ten ASCII> : <string data>, 例如4:spam 表示“spam”
- 整数: i<base ten ASCII>e,例如i3e表示整数3
- 列表: l<bencoded values>e, 例如l4:spam4:eggsi3ee 表示: [“spam”,”eggs”,3]
- 字典: d<bencoded string><bencoded element>e, 例如d4spaml1:a1:bee表示 {“spam” => [“a” , “b”] }
注意: 负数也是被允许的, 例如'i-3e', 但是任何数字都不能以0开头,例如'i03e'或者'i-03'都是非法的。当然,'i0e'是合法的。
可以访问https://wiki.theory.org/index.php/BitTorrentSpecification#Bencoding 获取更详细的信息。
Metainfo File Distribution
由于torrent所需的所有信息都包含在单个文件中,因此可以通过其他协议轻松分发此文件,并且随着文件的不断复制,peers的数量可以快速地增加。
最流行的分发方法是使用托管MetaInfo文件的公共索引网页。 种子将上传文件,然后其他人可以通过HTTP协议下载文件的副本并参与到torrent中(成为一个Peer)。
Tracker
用于管理参与到Torrent的用户(即peers)。
它存储关于torrent的统计信息,但它的主要作用是允许peers'找到各自'并开始通信,即找到拥有着他们需要下载的数据的peer.
Peers不会了解其他peers直到它收到tracker的回应。无论peer何时去查询tracker, 它都会报告它拥有这哪些文件片段。
这样,当另一个peer查询tracker时,tracker可以随机提供一个参与该torrent的符合要求的peer列表。
Tracker是一个HTTP / HTTPS服务,通常在端口6969上运行。
管理torrent的tracker的url地址在MetaInfo文件中指定,单个tracker可以管理多个torrent。
也可以指定多个tracker作为备份,由用户计算机上运行的BitTorrent客户端处理。
BitTorrent客户端使用HTTP GET请求与tracker通信,客户端在URL中附加一个“?”,并用“&”分隔参数。
例如,http://tracker.com/announce.php?var1=value&var2=value
以下是合法的参数:
- info_hash: metainfo 文件的info key 的20-byte SHA1 hash值.
- peer_id: 20-byte string, 客户端的unique ID.
- port: 客户端正在监听的端口.
- uploaded: 目前上传的总数,base ten ASCII 编码.
- downloaded: 目前下载的总数,base ten ASCII 编码.
- left: 客户端仍需下载的bytes数,base ten ASCII 编码.
- compact: 指定回应中的peers的格式是二进制形式
- event: If specified, must be one of the following: started, stopped, completed.
- ip: (optional) The IP address of the client machine, in dotted format.
- numwant: (optional) The number of peers the client wishes to receive from the tracker.
- key: (optional) Allows a client to identify itself if their IP address changes.
- trackerid: (optional) If previous announce contained a tracker id, it should be set here.
tracker收到请求后,以含有以下键的“text/plain”文档进行响应:
- failure message: 如果有这个键,那么其他键都将不存在,它的值是人类可阅读的错误信息。
- warning message: 跟failure message相似, 但是响应仍有其他键.
- interval: 客户端在将常规请求发送给tracker之间应该等待的时间间隔(以秒为单位.
- min interval: 最小公告间隔。 如果出现这个键,那么客户端不能比这更频繁地重新发布消息。
- tracker id: 客户端应该在其下一个公告中发回的字符串。 如果这个键不存在并且之前的公告发送了tracker id,则继续使用旧值。
- complete: 拥有完整文件的peers数量。
- incomplete: 不作种的peers数量(leechers)
- peers(字典形式): 一个包含字典的列表
- peer id: peer's unique ID
- ip: peer的IP地址,包括IPv6 (hexed)或者 IPv4(dotted quad)或者 DNS name (string)
- port: peer的端口 (integer)
- peers(二进制形式): 除了上面的字典形式, peers的值还可以是由6个字节的倍数组成的字符串,前4个字节是IP地址,最后2个字节是端口号。 全部以网络(大端)法表示。
你可以访问https://wiki.theory.org/index.php/BitTorrentSpecification#Tracker_Request_Parameters 获取更详细的信息
Scraping
按照惯例,大多数tracker支持另一种形式的请求,该请求询问tracker正在管理的给定torrent(或所有torrents)的状态。
Scrape URL也是一种HTTP GET方法,与上面描述的类似。但是,它的基本URL是不同的。
要派生出 scrape URL,请使用以下步骤:以announce URL开始。 找到最后的'/'。 如果紧跟在“/”后面的文本不是“announce”,它将被视为该tracker不支持scrape约定的标志。
如果是,则用'scrape'替换'announce'来查找scrape页面。以下是一些例子:
Examples:
Announce URL Scrape URL
http://example.com/annnounce –> http://example.com/scrape
http://example.com/a/annnounce –> http://example.com/a/scrape
http://example.com/announce.php –> http://example.com/scrape.php
http://example.com/a –> (scrape not supported)
http://example.com/%annnounce –> (scrape not supported)
http://example.com/announce?data=2 –> http://example.com/scrape?data=2
http://example.com/announce?data=2/4 –> (scrape not supported)
tracker收到请求后,以含有以下键的“text/plain”文档进行响应:
- files: 每一个torrent组成一个键值对的字典, 每一个键是20-byte binary hash 值, 对应的值是另一个字典,由以下键组成
- complete: 拥有完整文件的peers数量(seeds)
- downloaded: 整个文件被下载过的总次数
- incomplete: 下载者的数量(lechers)
- name: (optional) 该torrent名字
以下是一个回应的例子:
d5:filesd20: ….. d8:completei5e10:downloadedi50e10:oncompletei10eeee
表示 5 seeds, 10 leechers 和 50 complete downloads. "..."表示 20-byte info hash值.
Peers
peers表示参与到此torrent中的用户,并且用户拥有部分或全部文件(seed)。文件片段是从peers请求的,但不保证被发送,具体取决于(被请求)peer的状态。
bitTorrent使用TCP(Transmission Control Protocol)端口6881-6889在peer之间发送消息和数据,不像其他协议使用的是UDP协议。
Piece Selection
todo...
[1] http://www.bittorrent.org/beps/bep_0003.html "The BitTorrent Protocol Specification"
[2] https://wiki.theory.org/index.php/BitTorrentSpecification#Queuing "Bittorrent Protocol Specification v1.0"
[3] http://www.morehawes.co.uk/the-bittorrent-protocol "The BitTorrent Protocol"