BitTrrent(簡稱BT,比特洪流)是壹個文件分發協議,它通過URL識別內容並且和網絡無縫結合。它在HTTP平臺上的優勢在於,同時下在壹個文件的下載者在下載的同時不斷互相上傳數據,使文件源可以在很有限的負載增加的情況下支持大量下載者同時下載。
壹個BT式文件分發需要以下實體:
·壹個普通網絡服務器
·壹個靜態元信息文件
·壹個BT Tracker
·壹個“原始”下載者
·網絡終端瀏覽者
·網絡終端下載者
這裏假設理想情況下壹個文件有多個下載者。
架設壹個BT服務器步驟如下:
1.開始運行Tracker(已運行的跳過這壹步);
2.開始運行普通網絡服務器端程序,如Apache,已運行的跳過這壹步;
3.在網絡服務器上將.torrent文件關聯到Mimetype類型application/x-bittorrent(已關聯的跳過這壹步);
4.用要發布的完整文件和Tracker的URL創建壹個元信息文件(.torrent文件);
5.將元信息文件放置在網絡服務器上;
6.在網頁上發布元信息文件(.torrent文件)鏈接;
7.原始下載者提供完整的文件(原本)。
通過BT下載步驟如下:
1.安裝BT客戶端程序(已安裝的跳過這壹步);
2.上網;
3.點擊壹個鏈到.torrent文件的鏈接;
4.選擇本地存儲路徑,選定需要下載的文件(對有選擇下載功能的BT客戶端用戶);
5.等待下載完成;
6.用戶退出下載(之前下載者不停止上傳)。
連接狀況如下:
·網站正常提供靜態文件連接,並且啟動客戶端上的BT程序;
·Tracker即時接收所有下載者信息,並且給每個下載者壹份隨機的peer列表。通過HTTP或HTTPS協議實現;
·下載者每隔壹段時間連壹次Tracher,告知自己的進度,並和那些已經直接連接上的peer進行數據的上傳下載。這些連接遵循BitTorrent peer協議,通過TCP協議進行通信。
·原始下載者只上傳不下載,他擁有整個文件,所以很必要向網絡中傳輸完文件的所有部分。在壹些人氣很旺的下載中,原始下載者經常可以在較短的時間內退出上傳,由其它已經下載到整個文件的下載者繼續提供上傳。
元信息文件和Tracker的回應信息都以壹種簡單高效可擴展的格式(Bencoding,B編碼)傳送。B編碼過的信息就是以包含字符串和整型數據的字典和列表的嵌套(像在Python中壹樣),可擴展性是指可以通過減少字典忽略的關鍵值來添加新的特性。
B編碼規則如下:
·字符串表示為十進制數的既定字符串長度加冒號再跟原字符串。
如4:spam就相當於'spam'。
·整型數據表示成前面加'i'後面加'e'中間是十進制數,如i3e就相當於3,i-3e就是-3。整型數據沒有長度限制。i-0e無效,所有以'i0'開頭的除了代表0的i0e,其它都無效。
·列表編碼為壹個'l'開頭後面跟它所包含的項目(已經編碼過)最後加壹個'e',比如l4:spam4:eggse就等於['spam', 'eggs']。
·字典編碼為壹個'd'開頭後面跟壹個交替關鍵值(key)及其對應值的列表最後加壹個'e'。
如:d3:cow3:moo4:spam4:eggse相當於{'cow': 'moo', 'spam': 'eggs'}
d4:spaml1:a1:bee相當於{'spam': ['a', 'b']}
關鍵值必須是處理過的字符串(用原始字符串編碼的,而且不是數字字母混合編碼的)。
元信息文件就是B編碼的有以下關鍵值的字典:
announce(聲明)
Tracker的URL。
info(信息)
此關鍵值對應壹個字典包含以下描述的關鍵值:
關鍵值name對應壹個字符串,代表默認的下載文件或存成目錄的名字。它是純粹建議性的。
關鍵值piece length(塊長)對應文件分割成的塊的字節數。出於傳輸需要,文件被分割成大小相等的塊,除了最後壹塊通常會小壹些。塊長壹般來說是2的權值,大部分設塊長為256K(2的18次冪)。
關鍵值pieces(塊)對應壹個字符串,此字符串長度是20的倍數。它可以再分成每20字節壹段的多個字符串,分別對應塊在索引中的SHA1校驗碼(hash)。
還有關鍵值length(長度)和files(文件),它們不能同時出現也不能都不出現。當length出現說明這個元信息文件只是單文件下載,否則說明是多文件的目錄結構下載。
單文件情況下,length對應文件長度的字節數。
多文件情況被看作是把許多單文件按文件列表中的順序連成壹個大文件下載,而關鍵值files就對應文件列表,是壹個字典的列表,其中每個字典又包含以下關鍵值:
length(長度)
文件長度的字節數。
path(路徑)
壹個包含字符串的列表,字符串就是子目錄名,最後壹項的字符串是文件名。
(壹個長度為零的length表單是錯誤的。)
在單文件情況下,關鍵值name是文件名;多文件情況下,它就成了目錄名。
Tracker質詢是雙向的。Tracker通過HTTP GET參數獲得信息,然後返回壹個B編碼後的信息。盡管Tracker需要在服務器端執行,但它運行流暢像Apache的壹個模塊。
Tracker的GET請求有如下關鍵值:
info_hash
20字節長的SHA1驗證碼,來自B編碼過的元信息文件中的info值下,是元信息文件的壹個支鏈。這個值是自動轉換的。
peer_id
壹個20字節長的字符串,是每個用戶開始下載時隨機生成的ID。這個值也是是自動轉換的。
ip
壹個可選擇的參數給出peer所在的IP(或DNS主機名),壹般是和Tracker同機器的原始下載者得到後以便散發文件。
port
監聽端口,官方默認的是從6881端口開始試,如果端口被占用則依次向後推壹個端口找空閑端口,到6889端口為止。
uploaded
目前總上傳量,編碼為十進制ASCII碼。
downloaded
目前總下載量,編碼為十進制ASCII碼。
left
未下載的字節數,編碼為十進制ASCII碼。這個數不是通過文件長度和已下載數算出來的,因為文件可能在被續傳,還有壹些已經下載的數據不能通過完整性檢查必須重新下載。
event
這是個選擇性的關鍵值,選項有started,completed或stopped(或empty,等同於沒有運行)。如果沒有運行,這個聲明會定期間隔壹定時間發出。開始下載時發出started值,完成下載時發出completed。當文件完整後再開始,沒有completed發出,下載者中止下載時發出stopped。
Tracker的回應也是B編碼字典。如果Tracker回應中有關鍵值failure reason(失敗原因),就會對應壹個人可以讀懂的字符串信息解釋質詢失敗的原因,不需要其它關鍵值。否則,回應必須有兩個關鍵值:interval(間隔)對應下載者定期發出請求的間隔秒數;peers,peer自選ID,IP地址或DNS主機名的字符串和端口號。記住peers不會完全按照計劃的間隔發送請求,假如他們發生壹個事件或者想要更多的peers。
如果妳想對元信息文件或者Tracker質詢進行擴展,請與Bram Cohen進行協調,確保所有擴展都兼容。
BitTorrent peer協議通過TCP協議進行操作。它不用調節任何socket選項就可以流暢運行。
peer之間的連接是對稱的。兩個方向送出的信息要協調壹致,數據可以流入任壹方。
peer協議指壹個peer從零開始下載,每得到元信息文件索引中所描述的壹個塊且驗證碼壹致,就向所有peer聲明已得到此塊。
連接的兩個終端有2個狀態指標,被阻塞與否,被關註與否,被阻塞(choking)是表明在恢復通暢之前數據不再發出的通知。發生阻塞的原因和技術問題稍後會提到。
數據傳輸發生在壹方關註對方且對方沒有阻塞的情況下。關註狀態必須壹致保持-如果壹個沒阻塞的peer沒有別人需要的數據,別人對他就會失去關註,轉而關註那些正在阻塞的peer。完全執行這種條件需要非常慎重,但這樣的確可以讓下載者知道哪些peer在阻塞消失後可以馬上開始下載。
連接會逐漸斷開不感興趣和阻塞的peer。
當數據傳輸時,下載者要備好多份請求排成隊列,以獲得較高的TCP傳輸效率(這叫“管運請求”)。另壹方面,不能被寫入TCP緩沖區的請求要被立即排入內存,而不是壹個應用程序級的網絡緩沖,壹旦阻塞出現,這些請求全部丟棄。
peer連線協議包括壹次握手跟著不斷的大小壹致且確定的信息流。握手的開始是字符十九(十進制),跟著是字符串'BitTorrentprotocol'。開頭的字符是長度固定的,希望其它新協議也能這樣以便區分。
此後所有送入協議的整數都編碼為4字節大中止端。
在現有的應用中頭部數據之後是8個全部預留為0的字節,若果妳想通過改變這8個預留字節以擴展協議,請與Bram Cohen協調以保證所有擴展兼容。
然後是來自元信息文件中B編碼的info值中長20字節的SHA1驗證碼(和info_hash向Tracker聲明的值相同,但這裏是原始值那裏是引用)。如果雙方的值不同,連接斷開。壹個例外是下載者想只用壹個端口進行多個連接下載,它們會先從接入連接得到壹個驗證碼,然後和列表裏面的對照,有相同的就答復。
驗證碼之後是20字節的peer id,它包含在Tracker回應的peer列表中,在向Tracker的請求中被報告。如果接受方peer id不符合發送方希望,連接斷開。
握手完畢。之後是長度固定的交互信息流。零長度信息用來保持連接,被忽略。這種信息壹般2分鐘發出壹次,但是在等待數據期間很容易超時。
所有非保持連接用信息開頭的字節給出類型,可能值如下:
·0-阻塞
·1-通暢
·2-關註
·3-不關註
·4-有
·5-比特組
·6-請求
·7-塊
·8-取消
“阻塞”、“通暢”、“關註”和“不關註”類信息沒有荷載。
“比特組”類信息僅作為首信息發出。它負載壹個比特組,下載者有索引的設為1,其它為0。開始下載時沒有任何數據的下載者跳過“比特組”信息。首字節高位到低位對應索引0-7,依次類推,第二字節對應8-15,等等。尾部的剩余的比特位設為0。
“已有”類信息負載壹個數,即剛下載並核對完驗證碼的索引數。
“請求”類信息包括包含壹個索引,開始和長度。後兩者是字節偏移。長度壹般是2的權值除非被文件尾截斷。現行壹般是2的15次冪,並且關閉大於2的17次冪長度的連接。
“取消”類信息負載和“請求”類信息有壹樣的負載。它通常在下載接近完成即“最後階段”發出。當下載快要完成時,剩下幾個塊有都從同壹個線程下載的趨向,這樣會很慢。為了確保剩余塊下載迅速,壹旦還沒有決定剩余塊的下載請求向誰發出,先向所有他正在從對方下載數據的連接者發送要求所有剩余塊的請求。為避免低效,每當壹個塊開始下載就向其他peer發出取消信息。
“塊”類信息包含壹個索引,開始和塊。記住它和“請求”類信息是相關的。當傳輸速度很慢或“阻塞”“通暢”類信息高頻率交替發出或兩者同時發生,可能會載到壹個不需要的塊。
下載者下載塊的順序是隨機的,這樣適當防止下載者與其他Peers僅有相同的塊子集或超集。
阻塞的發生有很多原因。TCP協議的信息擁擠控制在即時向多連接發送信息的過程中表現極差。同時,阻塞的存在使下載者們能夠用以牙還牙式的算法來確保穩定的下載速率。
下面描述的阻塞算法是目前基礎的配置。重要的是所有新算法不光要在包含全部擴展算法的網絡中運行良好,也要在主要包含這個基礎算法的網絡中運行良好。
壹個優秀的阻塞算法有許多標準。它必須封鎖壹定同時上傳的數量以獲得良好的TCP表現,還要避免頻繁的堵塞和通暢交替,即所謂“纖維化”。它應該用數據交換報答給自己數據的peer。最後,它還應該偶爾嘗試壹下與未使用過的peer端連接,找出比現有連接好的連接,這叫做嘗試性疏通。
現行的阻塞算法避免纖維化的手段是每10秒轉換被阻塞的名單。疏通4個自己關註且能從他們身上得到最高下載速率的peer,進行上傳和數據交換。有較高上傳速率但是不被關註下載者的peer被疏通,壹旦這些peer開始被關註,那些上傳率最低的peer的就被阻塞。如果下載者有了完整的文件,他用自己的上傳率而不是下載率來決定疏通誰的連接。
在嘗試性疏通中,任何壹次中都有壹個peer被疏通不管他的上傳率如何(如果被關註,他會成為4個提供下載的peer之壹)。被嘗試性疏通的這種peer每30秒輪換壹次。為了給它們壹個上傳整壹個塊的機會,新連接會以輪換中嘗試性疏通次數的3倍開始連接。