bittorrent协议简介

BitTorrent协议可分为以下五个主要部分:

  • MetaInfo文件 - 包含协议运行所需的所有详细信息的文件。
  • Tracker - 帮助管理BitTorrent协议的服务器。
  • Peers - 用户通过BitTorrent协议交换文件数据。
  • Data - 通过协议传输的文件。
  • 客户端 - 位于peers计算机上并实现协议的程序。

Peers使用TCP(Transport Control Protocol)来传输和发送数据。
该协议优于其他协议,如UDP(User Datagram Protocol),因为它保证了数据从发送方到接收方的可靠和按序传送。
UDP不能提供这样的保证,数据可能变得混乱,或者一起丢失。
Peers通过HTTP(超文本传输协议)通过纯文本与Tracker进行通信。
下图说明了Peers如何彼此交互,并与Tracker进行通信。

The interactions between peers and the tracker over the TCP and HTTP protocols.

Data

BitTorrent功能非常强大,可用于传输任何数量目录中包含的任何类型的多个文件中的单个文件。 文件大小可能千差万别,从千字节到数百千兆字节。

Piece Size

Data根据bittorrent被分为较小片段在peers之间传输。这些片段的大小是固定的,这使得Tracker能够监视谁拥有哪些数据。
这也将文件分解为可验证的片段,然后可以为每个片段计算其hash值,其他peer下载时可以检查它们的数据完整性。
这些hash值被存储为'Metinfo文件'的一部分,这将在下一节讨论。
除了最后一块片段的大小是不规则的,其余片段的大小都是一致的。
最后一个片段的大小取决于文件的总大小,例如, 一个1.4Mb的文件可分为以下几个部分:

A file split into 6 pieces.

这显示了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列表。

A tracker providing a list of peers with the required data

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"

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容