BitTorrent協(xié)議可分為以下五個主要部分:
- MetaInfo文件 - 包含協(xié)議運行所需的所有詳細信息的文件泊藕。
- Tracker - 幫助管理BitTorrent協(xié)議的服務(wù)器榕栏。
- Peers - 用戶通過BitTorrent協(xié)議交換文件數(shù)據(jù)。
- Data - 通過協(xié)議傳輸?shù)奈募?/li>
- 客戶端 - 位于peers計算機上并實現(xiàn)協(xié)議的程序厚脉。
Peers使用TCP(Transport Control Protocol)來傳輸和發(fā)送數(shù)據(jù)。
該協(xié)議優(yōu)于其他協(xié)議,如UDP(User Datagram Protocol),因為它保證了數(shù)據(jù)從發(fā)送方到接收方的可靠和按序傳送螺戳。
UDP不能提供這樣的保證,數(shù)據(jù)可能變得混亂折汞,或者一起丟失。
Peers通過HTTP(超文本傳輸協(xié)議)通過純文本與Tracker進行通信盖腿。
下圖說明了Peers如何彼此交互爽待,并與Tracker進行通信损同。
Data
BitTorrent功能非常強大,可用于傳輸任何數(shù)量目錄中包含的任何類型的多個文件中的單個文件鸟款。 文件大小可能千差萬別膏燃,從千字節(jié)到數(shù)百千兆字節(jié)。
Piece Size
Data根據(jù)bittorrent被分為較小片段在peers之間傳輸何什。這些片段的大小是固定的组哩,這使得Tracker能夠監(jiān)視誰擁有哪些數(shù)據(jù)。
這也將文件分解為可驗證的片段处渣,然后可以為每個片段計算其hash值伶贰,其他peer下載時可以檢查它們的數(shù)據(jù)完整性。
這些hash值被存儲為'Metinfo文件'的一部分罐栈,這將在下一節(jié)討論黍衙。
除了最后一塊片段的大小是不規(guī)則的,其余片段的大小都是一致的荠诬。
最后一個片段的大小取決于文件的總大小琅翻,例如, 一個1.4Mb的文件可分為以下幾個部分:
這顯示了5 * 256kb的片斷柑贞,并且最后一片是120kb方椎。
當片段太大時會導(dǎo)致下載時的效率降低, 因為隨著數(shù)據(jù)完整性檢查頻率的降低數(shù)據(jù)失敗的概率增加了钧嘶, 相反棠众, 如果一個片段太小,那么就會需要更多的
hash檢驗康辑。
隨著片段數(shù)量的增加摄欲, 更多的hash值需要被存儲到MetaInfo文件中。一般來說疮薇,分片段應(yīng)該讓MetaInfo文件不超過 50-70Kb胸墙,
其主要原因是限制索引服務(wù)器所需的主機存儲量和帶寬。 最常見的尺寸是256kb按咒,512kb和1mb迟隅,那么片段數(shù)是: 總大小/片段大小。
順便一提励七,片段可能與文件邊界重疊智袭。
MetaInfo File
當有人想使用BitTorrent協(xié)議發(fā)布數(shù)據(jù)時,他們必須創(chuàng)建一個MetaInfo文件掠抬。 這個文件是特定于他將要發(fā)布的數(shù)據(jù)的吼野, 而且它包含了關(guān)于那個torrent的
所有信息,例如將要包含的數(shù)據(jù)两波,Tracker的ip地址等瞳步。Tracker是一個“管理”torrent的服務(wù)器闷哆,將在下一節(jié)中討論。
MetaInfo文件被賦予一個'.torrent'擴展名单起,并且數(shù)據(jù)是由BitTorrent客戶端從文件中提取的抱怔。
BitTorrent客戶端是在用戶計算機上運行的程序,并實現(xiàn)了bittorrent協(xié)議嘀倒。 每個MetaInfo File都必須包含以下信息("key"):
- info:描述文件的字典屈留。 無論是單個文件還是目錄結(jié)構(gòu)的更多文件。 以及SHA-1格式存儲的每個數(shù)據(jù)片段的哈希测蘑。
- announce: 字符串灌危。tracker的announce url。
可能包含的額外信息: - announce-list: 用于列出所有備份trackers
- creation date: 這個torrent的創(chuàng)建時間戳(unix)
- comment: 作者的評論
- created by: 用于創(chuàng)建此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@\…..’,
}
‘a(chǎn)nnounce’: ‘http://tracker.var.cc:6969/announce’,
‘creation date’: 1089749086L
}
注意: 上面顯示的并不是實際上torrent文件真正的內(nèi)容帮寻, 事實上乍狐, 上述內(nèi)容還需要通過一種稱為"Bencoding"的方法編碼。
Bencoding
BitTorrent使用Bencoding在BitTorrent客戶端和tracker之間發(fā)送結(jié)構(gòu)松散的數(shù)據(jù)固逗。
Bencoding 支持字節(jié)字符串, 整數(shù), 列表和字典四種結(jié)構(gòu)浅蚪。
它分別使用'i'/'l'/'d'作為整數(shù),列表和字典的開始分隔符烫罩。 這三種類型的結(jié)束分隔符都是'e'惜傲。字節(jié)字符串沒有分隔符。
Bencoding 結(jié)構(gòu):
- 字節(jié)字符串: <string length in base ten ASCII> : <string data>贝攒, 例如4:spam 表示“spam”
- 整數(shù): i<base ten ASCII>e盗誊,例如i3e表示整數(shù)3
- 列表: l<bencoded values>e, 例如l4:spam4:eggsi3ee 表示: [“spam”,”eggs”,3]
- 字典: d<bencoded string><bencoded element>e隘弊, 例如d4spaml1:a1:bee表示 {“spam” => [“a” , “b”] }
注意: 負數(shù)也是被允許的哈踱, 例如'i-3e', 但是任何數(shù)字都不能以0開頭,例如'i03e'或者'i-03'都是非法的梨熙。當然开镣,'i0e'是合法的。
可以訪問https://wiki.theory.org/index.php/BitTorrentSpecification#Bencoding 獲取更詳細的信息咽扇。
Metainfo File Distribution
由于torrent所需的所有信息都包含在單個文件中邪财,因此可以通過其他協(xié)議輕松分發(fā)此文件,并且隨著文件的不斷復(fù)制质欲,peers的數(shù)量可以快速地增加树埠。
最流行的分發(fā)方法是使用托管MetaInfo文件的公共索引網(wǎng)頁。 種子將上傳文件嘶伟,然后其他人可以通過HTTP協(xié)議下載文件的副本并參與到torrent中(成為一個Peer)怎憋。
Tracker
用于管理參與到Torrent的用戶(即peers)。
它存儲關(guān)于torrent的統(tǒng)計信息九昧,但它的主要作用是允許peers'找到各自'并開始通信绊袋,即找到擁有著他們需要下載的數(shù)據(jù)的peer.
Peers不會了解其他peers直到它收到tracker的回應(yīng)赠橙。無論peer何時去查詢tracker, 它都會報告它擁有這哪些文件片段愤炸。
這樣,當另一個peer查詢tracker時掉奄,tracker可以隨機提供一個參與該torrent的符合要求的peer列表规个。
Tracker是一個HTTP / HTTPS服務(wù),通常在端口6969上運行姓建。
管理torrent的tracker的url地址在MetaInfo文件中指定诞仓,單個tracker可以管理多個torrent。
也可以指定多個tracker作為備份速兔,由用戶計算機上運行的BitTorrent客戶端處理墅拭。
BitTorrent客戶端使用HTTP GET請求與tracker通信,客戶端在URL中附加一個“涣狗?”谍婉,并用“&”分隔參數(shù)。
例如镀钓,http://tracker.com/announce.php?var1=value&var2=value
以下是合法的參數(shù):
- info_hash: metainfo 文件的info key 的20-byte SHA1 hash值.
- peer_id: 20-byte string穗熬, 客戶端的unique ID.
- port: 客戶端正在監(jiān)聽的端口.
- uploaded: 目前上傳的總數(shù),base ten ASCII 編碼.
- downloaded: 目前下載的總數(shù)丁溅,base ten ASCII 編碼.
- left: 客戶端仍需下載的bytes數(shù)唤蔗,base ten ASCII 編碼.
- compact: 指定回應(yīng)中的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”文檔進行響應(yīng):
- failure message: 如果有這個鍵窟赏,那么其他鍵都將不存在妓柜,它的值是人類可閱讀的錯誤信息。
- warning message: 跟failure message相似, 但是響應(yīng)仍有其他鍵.
- interval: 客戶端在將常規(guī)請求發(fā)送給tracker之間應(yīng)該等待的時間間隔(以秒為單位.
- min interval: 最小公告間隔涯穷。 如果出現(xiàn)這個鍵棍掐,那么客戶端不能比這更頻繁地重新發(fā)布消息。
- tracker id: 客戶端應(yīng)該在其下一個公告中發(fā)回的字符串求豫。 如果這個鍵不存在并且之前的公告發(fā)送了tracker id塌衰,則繼續(xù)使用舊值。
- complete: 擁有完整文件的peers數(shù)量蝠嘉。
- incomplete: 不作種的peers數(shù)量(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個字節(jié)的倍數(shù)組成的字符串蚤告,前4個字節(jié)是IP地址努酸,最后2個字節(jié)是端口號。 全部以網(wǎng)絡(luò)(大端)法表示杜恰。
你可以訪問https://wiki.theory.org/index.php/BitTorrentSpecification#Tracker_Request_Parameters 獲取更詳細的信息
Scraping
按照慣例获诈,大多數(shù)tracker支持另一種形式的請求仍源,該請求詢問tracker正在管理的給定torrent(或所有torrents)的狀態(tài)。
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”文檔進行響應(yīng):
- files: 每一個torrent組成一個鍵值對的字典控淡, 每一個鍵是20-byte binary hash 值嫌吠, 對應(yīng)的值是另一個字典,由以下鍵組成
- complete: 擁有完整文件的peers數(shù)量(seeds)
- downloaded: 整個文件被下載過的總次數(shù)
- incomplete: 下載者的數(shù)量(lechers)
- name: (optional) 該torrent名字
以下是一個回應(yīng)的例子:
d5:filesd20: ….. d8:completei5e10:downloadedi50e10:oncompletei10eeee
表示 5 seeds, 10 leechers 和 50 complete downloads. "..."表示 20-byte info hash值.
Peers
peers表示參與到此torrent中的用戶逸寓,并且用戶擁有部分或全部文件(seed)居兆。文件片段是從peers請求的,但不保證被發(fā)送竹伸,具體取決于(被請求)peer的狀態(tài)泥栖。
bitTorrent使用TCP(Transmission Control Protocol)端口6881-6889在peer之間發(fā)送消息和數(shù)據(jù),不像其他協(xié)議使用的是UDP協(xié)議勋篓。
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"