tracker
服務(wù)器是
BT
下載中必須的角色。一個(gè)
BT client
在下載開始以及下載進(jìn)行的過程中,要不停的與
tracker
服務(wù)器進(jìn)行通信,以報(bào)告自己的信息,并獲取其它下載
client
的信息。這種通信是通過
HTTP
協(xié)議進(jìn)行的,又被稱為
tracker HTTP
協(xié)議,它的過程是這樣的:
client
向
tracker
發(fā)一個(gè)
HTTP
的
GET
請(qǐng)求,并把它自己的信息放在
GET
的參數(shù)中;這個(gè)請(qǐng)求的大致意思是:我是
xxx
(一個(gè)唯一的
id
),我想下載
yyy
文件,我的
ip
是
aaa
,我用的端口是
bbb
。。。
tracker
對(duì)所有下載者的信息進(jìn)行維護(hù),當(dāng)它收到一個(gè)請(qǐng)求后,首先把對(duì)方的信息記錄下來(如果已經(jīng)記錄在案,那么就檢查是否需要更新),然后將一部分(并非全部,根據(jù)設(shè)置的參數(shù)已經(jīng)下載者的請(qǐng)求)參與下載同一個(gè)文件(一個(gè)
tracker
服務(wù)器可能同時(shí)維護(hù)多個(gè)文件的下載)的下載者的信息返回給對(duì)方。
Client
在收到
tracker
的響應(yīng)后,就能獲取其它下載者的信息,那么它就可以根據(jù)這些信息,與其它下載者建立連接,從它們那里下載文件片斷。
關(guān)于
client
和
tracker
之間通信協(xié)議的細(xì)節(jié),在“
BT
協(xié)議規(guī)范”中已經(jīng)給出,這里不再重復(fù)。下面我們具體分析
tracker
服務(wù)器的實(shí)現(xiàn)細(xì)節(jié)。
從哪里開始?
要建立一個(gè)
tracker
服務(wù)器,只要運(yùn)行
bttrack.py
程序就行了,它最少需要一個(gè)參數(shù),就是
–dfile
,這個(gè)參數(shù)指定了保存下載信息的文件。
Bttrack.py
調(diào)用
track.py
中的
track()
函數(shù)。因此,我們跟蹤到
track.py
中去看
track()
函數(shù)。
Track.py
:
track()
這個(gè)函數(shù)首先對(duì)命令行的參數(shù)進(jìn)行檢查;然后將這些參數(shù)保存到
config
字典中。在
BT
中所有的工具程序,都有類似的處理方式。
接下來的代碼:
r = RawServer(Event(), config['timeout_check_interval'], config['socket_timeout'])
t = Tracker(config, r)
r.bind(config['port'], config['bind'], True)
r.listen_forever(HTTPHandler(t.get, config['min_time_between_log_flushes']))
t.save_dfile()
首先是創(chuàng)建一個(gè)
RawServer
對(duì)象,這是一個(gè)服務(wù)器對(duì)象,它將實(shí)現(xiàn)一個(gè)網(wǎng)絡(luò)服務(wù)器的一些細(xì)節(jié)封裝起來。不僅
tracker
服務(wù)器用到了
RawServer
,我們以后還可以看到,由于每個(gè)
client
端也需要給其它
client
提供下載服務(wù),因此也同時(shí)是一個(gè)服務(wù)器,
client
的實(shí)現(xiàn)中,也用到了
RawServer
,這樣,
RawServer
的代碼得到了重用。關(guān)于
RawServer
的詳細(xì)實(shí)現(xiàn),在后面的小節(jié)中進(jìn)行分析。
接著是創(chuàng)建一個(gè)
Tracker
對(duì)象。
然后讓
RawServer
綁定在指定的端口上(通過命令行傳遞進(jìn)來)。
最后,調(diào)用
RawServer::listen_forever()
函數(shù),使得服務(wù)器投入運(yùn)行。
最后,在服務(wù)器因某些原因結(jié)束運(yùn)行以后,調(diào)用
Tracker::save_dfile()
保存下載信息。這樣,一旦服務(wù)器再次投入運(yùn)行,可以恢復(fù)當(dāng)前的狀態(tài)。
其它信息:
1、
BT
源碼的分布:
把
BT
的源碼展開之后,可以看到有一些
python
程序,還有一些說明文件等等,此外還有一個(gè)
BitTorrent
目錄。這些
python
程序,實(shí)際是一些小工具,比如制作
file
的
btmakefile.py
、運(yùn)行
tracker
服務(wù)器的
bttrack.py
、運(yùn)行
BT client
端的
btdownloadheadless.py
等等。而這些程序中,用到的一些
python
類的實(shí)現(xiàn),都放在子目錄
BitTorrent
下面。我們的分析工作,通常是從工具程序入手,比如
bttrack.py
,而隨著分析的展開,則重點(diǎn)是看
BitTorrenet
子目錄下的代碼。
BT
作者
Bram Cohen
在談到如何開發(fā)可維護(hù)的代碼的一篇文章中(
http://www.advogato.org/article/258.html
),其中提到的一條就是開發(fā)一些小工具以簡(jiǎn)化工作,我想
BT
的這種源碼結(jié)構(gòu),也正是作者思想的一種體現(xiàn)吧。
2、
我們看到,
python
和我們以前接觸的
c/c++
不一樣的第一個(gè)地方就是它的函數(shù)在定義的時(shí)候,不用指定參數(shù)類型。既然這樣,那么,在調(diào)用函數(shù)的時(shí)候,你可以傳遞任意類型的參數(shù)進(jìn)來。例如這樣的函數(shù):
def foo(arg):
print type(arg)
你可以這樣來調(diào)用:
a = 100
b = “hello world”
foo(a)
foo(b)
輸出結(jié)果是:
<type ‘int’>
<type ‘str’>
這是因?yàn)椋谝淮握{(diào)用
foo()
的時(shí)候,傳遞的是一個(gè)整數(shù)類型,而第二次調(diào)用的時(shí)候,傳遞的是一個(gè)字符串類型。
這種參數(shù)具有動(dòng)態(tài)類型的特性,是
c/c++
等傳統(tǒng)的語(yǔ)言是所不具備的。這也是
python
被稱為動(dòng)態(tài)語(yǔ)言的一個(gè)原因吧。
C++
的高級(jí)特性模板,雖然也使得參數(shù)類型可以動(dòng)態(tài)化,但使用起來,遠(yuǎn)沒有
python
這么簡(jiǎn)單方便。
posted on 2007-01-19 00:17
苦笑枯 閱讀(362)
評(píng)論(0) 編輯 收藏 所屬分類:
P2P