- 簡述
BT下載是采用P2P的下載方式,下載的大致形式采用如下圖所示,處於圖示中心的稱為Tracker服務器,其余稱為Peer。
缺點
1.資源的安全性
2.資源的實效性(沒有上傳者則BT也將失效)
3.版權
- 協議分析
對BT協議(1.0)的分析主要包含4個部分:
1.種子文件的分析
2.同Tracker服務器的通訊(采用HTTP協議)
3.同其他peer(配合/協同者)的通訊(采用TCP協議)
4.總結
分析前的了解
在這些分析之前,需要先了解兩點BT協議采用的基礎:
1.BT協議中采用的單位
2.BT協議中采用的編碼
1--單位說明:
下載的文件被划分成大小相同的piece(除了最后一個),以1 – 256KB (假設一個piece=256KB)稱為第1個piece,之后按順序稱呼,每個piece都有獨特的hash值,作為版本號。
piece下面又划分了block,block一般為固定值16KB,在同peer(同為下載者的對象主機)之間每次傳輸的單位為block,client(本機)需要記錄該block的是屬於那個piece的block。
Tips:
1.piece需要是16KB的整數倍
2.對piece的校驗流程:
下載完成 è 使用標准算法(Sha1)計算1的hash值 è 比較種子文件的hash值同2的hash值
2--單位說明:
種子文件又成metafile(元文件),文件內部的編碼采用BenCode(B編碼),BenCode中存在4中類型。
類型 |
格式及范例 |
字符串 |
格式:<字符串長度>:<字符串> 范例:字符串good 4:good |
整型 |
格式:i<十進制的整型數>e => i(interge)為起始符,e(end)為結束符 范例:數字5 i5e |
列表 |
格式:l<其他類型>e =>l(list)為起始符,e(end)為結束符 范例:字符串good + 字符串nihao l4:good5:nihaoe |
字典 |
格式:d<關鍵字><值>e =>d(dictionary)為起始符,e(end) 其中:關鍵字必須為字符串,值則未限定 范例:good為key,列表nihao和hello為值 d4:goodl5:nihao5:helloee |
協議分析(1)--種子文件分析
(a)枚舉文件說明
=>以文本打開單文件.torrent文件:
d8:announce35:http://192.168.73.197:8080/announce10:created by13:BitComet/1.3713:creation datei1472779924e8:encoding5:UTF-84:infod4:ed2k16:??~_x0010_€?_x001D_8_x0007_/vG8:filehash20:E氙率>w?⒂?y<?伖6:lengthi30791e4:name22:btdownloadservice.mmap10:name.utf-822:btdownloadservice.mmap12:piece lengthi32768e6:pieces20:E氙率>w?⒂?y<?伖e5:nodesll4:6881i0eel5:37049i0eel5:33281i0eel5:18021i0eel5:51413i0eel5:21793i0eel5:51413i0eel5:18672i0eel4:6881i0eel4:5712i0eee9:publisher10:hejianglin15:publisher.utf-810:hejiangline
解析情況
=>以文本打開多文件.torrent文件:
d8:announce35:http://192.168.73.197:8080/announce10:created by13:BitComet/1.3713:creation datei1472781603e8:encoding5:UTF-84:infod5:filesld4:ed2k16:鰼 *羉_x0007_実?⒚!彐o8:filehash20:碊?a?戎7暰毿警U_x0019_6?:lengthi5e4:pathl9:test1.txte10:path.utf-8l9:test1.txteed6:lengthi32763e4:pathl104:_____padding_file_0_濡傛灉鎮ㄧ湅鍒版鏂囦歡錛岃鍗囩駭鍒癇itComet(姣旂壒褰楁槦)0.85鎴栦互涓婄増鏈琠___e10:path.utf-8l104:_____padding_file_0_濡傛灉鎮ㄧ湅鍒版鏂囦歡錛岃鍗囩駭鍒癇itComet(姣旂壒褰楁槦)0.85鎴栦互涓婄増鏈琠___eed4:ed2k16:?c]獝狎褧Ao顫?:filehash20:_x0010_烱<P裝遰?浧飷f?6:lengthi5e4:pathl9:test2.txte10:path.utf-8l9:test2.txteee4:name3:dir10:name.utf-83:dir12:piece lengthi32768e6:pieces40:B橫?鬝笫Pi烴}璭鑱k_x0010_烱<P裝遰?浧飷f?e5:nodesll4:6881i0eel5:37049i0eel5:33281i0eel5:18021i0eel5:51413i0eel5:21793i0eel5:56963i0eel5:38322i0eel5:26121i0eel4:5712i0eee9:publisher10:xxxxxxxxxx15:publisher.utf-810:xxxxxxxxxxe
解析情況
關於各個關鍵key的作用請看下面(b)key的說明
(b)key說明
=>單/多文件都包含的key說明
key |
說明 |
announce |
Tracker的主服務器 |
announce-list(可選) |
Tracker服務器備用列表 |
creation date(可選) |
種子文件建立的時間 |
comment(可選): |
種子文件的注釋 |
created by(可選) |
創建人或創建程序的信息 |
info |
文件信息,二種情況:單文件結構或多文件結構 |
=>單文件中的info說明
key |
說明 |
length |
文件的大小,用byte計算 |
md5sum(可選) |
MD5校驗和,不使用 |
name |
文件名 |
piece length |
每個piece的大小,用byte計算 |
pieces |
每個piece的20個字節的SHAT Hash的值 |
=>多文件中的info說明
key |
說明 |
files |
表示文件的名字和大小下面說明 |
md5sum(可選) |
MD5校驗和,不使用 |
name |
目錄名字 |
piece length |
每個piece的大小,用byte計算 |
pieces |
每個piece的20個字節的SHAT Hash的值 |
=>多文件中的files說明
key |
說明 |
lenghth |
文件的大小,用byte計算 |
path |
文件的名字 |
path.utf-8 |
文件名的UTF-8編碼 |
有點亂,請看(c)總結
(c)總結
=>單文件torrent的種子結構信息
├─announce
├─announce-list
├─comment
├─comment.utf-8
├─creation date
├─encoding
├─info
│ ├─length
│ ├─name
│ ├─name.utf-8
│ ├─piece length
│ ├─pieces
│ ├─publisher
│ ├─publisher-url
│ ├─publisher-url.utf-8
│ └─publisher.utf-8
└─nodes //dht
=>多文件torrent的種子結構信息
├─announce
├─announce-list
├─comment
├─comment.utf-8
├─creation date
├─encoding
├─info
│ ├─files
│ │ ├─length
│ │ ├─path
│ │ └─path.utf-8
│ ├─name
│ ├─name.utf-8
│ ├─piece length
│ ├─pieces
│ ├─publisher
│ ├─publisher-url
│ ├─publisher-url.utf-8
│ └─publisher.utf-8
└─nodes //dht
BT協議分析(2)--同Tracker服務器的通訊(采用HTTP協議GET方式)
(a)目的
1.將下載進度報告給Tracker以便Tracker進行相關統計
2.獲取當前下載同一個資源的peer的IP和端口號
(b)操作
=>主機發送給Tracker服務器請求當前連接着同一文件的peer地址
格式:<Tracker服務器地址>?<parm1=value1>&<><parm2=value2>...
例如:
http://tk.greedland.net/announce?
info_hash=01234567890123456789
&peer_id=01234567890123456789
&port=3210
&compact=1
&uploaded=0
&downloaded=0
&left=8000000
&event=started
參數說明:
參數 |
意義 |
info_hash |
種子文件info對應的hash值(固定20字節) |
peer_id |
隨機標識符,表示自身的請求(固定20字節) |
port |
主機監聽端口號,用與同其他peer的連接請求 |
uploaded |
當前的上傳總量(單位Byte) |
downloaded |
當前的下載總量(單位Byte) |
left |
剩余下載量,即下載總量 - 已下載量 |
compact |
Tracker服務器的反饋當前peer的方式 1 = 每個peer占6個字節,前4字節為peer的IP地址,其余為peer的端口號 |
event |
主機的下載狀態: start = 主機開始下載(主機同Tracker首次通信時) completed = 主機已完成下載 stoped = 結束,主機即將關閉 |
ip |
可選,主機IP地址 |
numwant |
可選,Tracker服務器反饋peer的數量(默認50個) |
key |
可選,隨機標識符 |
trackerid |
可選 |
=>Tracker服務器返回結果(B編碼的字典)
d //
8:complete //..已完成數量
i100e
10:incomplete // ..未完成數量
i200e
8:interval // ..間隔時間
i1800e
5:peers // ..當前peers
300:......
e
參數說明:
關鍵字 |
意義 |
failure reason |
GET失敗的原因(human string) |
warning message |
GET警告字符串(human string) |
interval |
主機下次連接Tracker所需時間(單位:秒) |
min interval |
主機下次連接Tracker所需的最小時間(單位:秒) |
tracked id |
指明Tracker的ID |
complete |
整數,當前存在多少個peer已完成該文件的下載 |
incomplete |
整數,當前存在多少個peer未完成該文件的下載 |
peers |
各個peer的IP和端口號,字符串 |
具體分析:
URL的具體情況:/announce?info_hash=%98%13%c7%a0%87%eb%a7%a6gh%dc%86kU%03m%ff%2fr%94&peer_id=-UT348B-%03%a6%df%91%063%f8%daC%1e%02F&port=24842&uploaded=0&downloaded=0&left=13547779828&corrupt=0&key=917599C2&numwant=200&compact=1&no_peer_id=1 HTTP/1.1
回包信息:
BT協議分析(3)--同其他peer(配合/協同者)的通訊(采用TCP協議)
(a)通訊協議格式說明
主機同peer之間的通訊格式主要分為兩種:握手及其他
=>握手采用的格式和參數說明
格式:<pstrlen><pstr><reserved><info_hash><peer_id> |
||
參數 |
所占字節數 |
意義 |
pstrlen |
1 |
pstr的長度,為固定值19 |
pstr |
19 |
BitTorrent protocol,BitTorrent協議的關鍵字 |
reserved |
8 |
擴展字節,一般設置為0 |
info_hash |
20 |
同主機發送到Tracker的Get請求中的info_hash為同值 |
peer_id |
20 |
識別BT軟件類型 |
=>其他的參數說明
格式:<length prefix><message ID><payload> |
||
參數 |
所占字節數 |
意義 |
length prefix |
4 |
表示message ID 和 payload的長度和 |
message ID |
1 |
十進制整數,表示消息的編號 |
payload |
隨機 |
負載,表示消息的內容 |
message ID說明
消息類型 |
消息格式 |
所占字節數 |
意義 |
keep_alive |
<len=0000> 即:0000 |
4 |
2分鍾內沒有向peer發送任何消息,則發送此消息 |
choke |
<len=0001><id=0> 即:00010 |
5 |
阻塞接收消息的peer,即該peer無法下載主機資源 |
unchoke |
<len=0001><id=1> 即:00011 |
5 |
解除阻塞。
|
interested |
<len=0001><id=2> 即:00012 |
5 |
通知peer,peer上存在主機上沒有的資源 |
not interested |
<len=0001><id=3> 即:00013 |
5 |
通知peer,peer上存在的資源主機上都有 |
have |
<len=0005><id=4><piece index> 即:00054<piece index> |
9 |
通知所有peer,主機擁有此index的piece |
bitfield |
<len=0001 + X(見注1)><id=5><bitfield> 即:< 1(表示id長度) +bitfile的長度>5<bitfield> |
不固定 |
主機同peer端交換當前資源的信息 |
request |
<len=0013><id=6><index><begin><length> 即:000136<piece的索引><piece的偏移><請求的數據長度> |
17 |
主機請求獲取peer上的資源 |
piece |
<len=0009+X><id=7><index><begin><block> 即:<9+block的長度(見注2)>7<index><begin><block> |
不固定 |
主機上傳資源到peer上 |
cancel |
<len=0013><id=8><index><begin><length>即: 000138<piece的索引><piece的偏移><請求的數據長度> |
17 |
同request的作用相反,用於取消獲取的請求 |
port |
<len=0003><id=9><listen-port> 即:00039<監聽端口> |
7 |
只在支持DHT(見注3)的主機上使用,指明DHT監聽的端口號 |
注1:
X:表示為(Bit)位圖的長度,每個Bit代表一個Piece,假設當前文件為801個piece,則需要801個Bit來表示,也即101個字節,第一個Bit表示第一個piece,Bit為1表明當前主機擁有此piece。
注2:
9 = id(1) + index(4) + begin(4)
X表示block的長度
block表示傳輸的資源數據(一般為slice的長度)
注3:
DHT:Distributed Hash Table(分布式哈希表),每個客戶端都可以充當服務器,這樣在沒有Tarcker服務器的時候,主機仍然可以在其他peer上下載文件。采用UDP協議(采用的端口號同TCP端口號一致)
完全不知道是什么?請看(b)交互步驟
(b)交互步驟
步驟1.建立握手消息,創建針對peer的狀態變量
當前主機對成功建立連接peer都需要維護一個和peer之間的狀態信息
狀態變量 |
意義 |
am_chocking |
意義:主機阻塞標志 1 = 主機同peer信息阻塞,peer不可以獲取主機數據 0 = 非阻塞,peer可以獲取主機數據 default = 1 |
am_interested |
意義:主機數據不完整標志 1 = peer存在主機沒有的piece 0 = peer上的piece主機上都有 default = 0 |
peer_chocking |
意義:peer阻塞標志 1 = peer同當前主機阻塞,主機不可獲取peer端數據 0 = 非阻塞,主機可以獲取peer數據 default = 1 |
peer_interested |
意義:peer數據不完整標志 1 = 主機存在peer沒有的piece(數據) 0 = 主機上的piece,peer上都有 default = 0 |
步驟2.互換所擁有的資源情況
采用上述的bitfield交換數據
步驟3.交流對資源的意願信息
采用上述的choke/unchoke/interested/not interested /have 交換數據
步驟4.互相請求資源
采用上述的request / cancel / piece交換數據
步驟5.斷開連接
(c)交互算法
下載策略:
1.片段選擇法
a)向一個peer請求完整的一個piece
b)優先請求當前piece擁有者最少的piece
c)在最開始采用隨機下載piece
d)但下載中遇上某個piece傳輸速度慢的情況,客戶端向所有的piece發送該piece的block的請求
片段選擇策略:
在開始和最后的階段,隨機的去多個peer上獲取相同的block
2.阻塞算法
性能優化策略。
每個客戶端同固定數量的peer保持疏通,如何判斷保持疏通的對象? (根據與peer的連接速度)
BT協議采用每10秒計算與當前peer的連接速度,選取速度最快的4個選擇疏通.
另外在處理空閑連接是否具有更好的下載速度時,BT協議為每個peer設定一個optimistic unchoking peer,
每個主機每隔30s計算當前主機同該peer的傳輸速度,優於最優的那個則采用為4個選擇疏通對象的其中一個。
且每隔30s置換一個peer對象.
當主機下載結束后,是如何選擇4個疏通對象的?於傳輸速度最優的4個peer保持疏通關系
以圖為例,BT采取的流程大致如下。
- 參考
http://www.cnblogs.com/happyhotty/articles/2064058.html
http://www.cnblogs.com/DxSoft/archive/2012/02/11/2346314.html
http://blog.chinaunix.net/uid-26548237-id-3056731.html