posts - 56,  comments - 12,  trackbacks - 0
          tracker 服務器是 BT 下載中必須的角色。一個 BT client 在下載開始以及下載進行的過程中,要不停的與 tracker 服務器進行通信,以報告自己的信息,并獲取其它下載 client 的信息。這種通信是通過 HTTP 協議進行的,又被稱為 tracker  HTTP 協議,它的過程是這樣的:

                 client tracker 發一個 HTTP GET 請求,并把它自己的信息放在 GET 的參數中;這個請求的大致意思是:我是 xxx (一個唯一的 id ),我想下載 yyy 文件,我的 ip aaa ,我用的端口是 bbb 。。。

                 tracker 對所有下載者的信息進行維護,當它收到一個請求后,首先把對方的信息記錄下來(如果已經記錄在案,那么就檢查是否需要更新),然后將一部分(并非全部,根據設置的參數已經下載者的請求)參與下載同一個文件(一個 tracker 服務器可能同時維護多個文件的下載)的下載者的信息返回給對方。

                 Client 在收到 tracker 的響應后,就能獲取其它下載者的信息,那么它就可以根據這些信息,與其它下載者建立連接,從它們那里下載文件片斷。

           

          關于 client tracker 之間通信協議的細節,在“ BT 協議規范”中已經給出,這里不再重復。下面我們具體分析 tracker 服務器的實現細節。

           

          從哪里開始?

                 要建立一個 tracker 服務器,只要運行 bttrack.py 程序就行了,它最少需要一個參數,就是 –dfile ,這個參數指定了保存下載信息的文件。 Bttrack.py 調用 track.py 中的 track() 函數。因此,我們跟蹤到 track.py 中去看 track() 函數。

           

          Track.py track()

                 這個函數首先對命令行的參數進行檢查;然后將這些參數保存到 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()

           

          首先是創建一個 RawServer 對象,這是一個服務器對象,它將實現一個網絡服務器的一些細節封裝起來。不僅 tracker 服務器用到了 RawServer ,我們以后還可以看到,由于每個 client 端也需要給其它 client 提供下載服務,因此也同時是一個服務器, client 的實現中,也用到了 RawServer ,這樣, RawServer 的代碼得到了重用。關于 RawServer 的詳細實現,在后面的小節中進行分析。

          接著是創建一個 Tracker 對象。

          然后讓 RawServer 綁定在指定的端口上(通過命令行傳遞進來)。

          最后,調用 RawServer::listen_forever() 函數,使得服務器投入運行。

          最后,在服務器因某些原因結束運行以后,調用 Tracker::save_dfile() 保存下載信息。這樣,一旦服務器再次投入運行,可以恢復當前的狀態。

           

           

          其它信息:

          1、  BT 源碼的分布:

          BT 的源碼展開之后,可以看到有一些 python 程序,還有一些說明文件等等,此外還有一個 BitTorrent 目錄。這些 python 程序,實際是一些小工具,比如制作 file btmakefile.py 、運行 tracker 服務器的 bttrack.py 、運行 BT client 端的 btdownloadheadless.py 等等。而這些程序中,用到的一些 python 類的實現,都放在子目錄 BitTorrent 下面。我們的分析工作,通常是從工具程序入手,比如 bttrack.py ,而隨著分析的展開,則重點是看 BitTorrenet 子目錄下的代碼。

          BT 作者 Bram Cohen 在談到如何開發可維護的代碼的一篇文章中( http://www.advogato.org/article/258.html ),其中提到的一條就是開發一些小工具以簡化工作,我想 BT 的這種源碼結構,也正是作者思想的一種體現吧。

           

          2、  我們看到, python 和我們以前接觸的 c/c++ 不一樣的第一個地方就是它的函數在定義的時候,不用指定參數類型。既然這樣,那么,在調用函數的時候,你可以傳遞任意類型的參數進來。例如這樣的函數:

          def foo(arg):

                  print type(arg)

                

                 你可以這樣來調用:

                 a = 100

                 b = “hello world”

                 foo(a)

                 foo(b)

           

                 輸出結果是:

                 <type ‘int’>

                 <type ‘str’>

           

                 這是因為,第一次調用 foo() 的時候,傳遞的是一個整數類型,而第二次調用的時候,傳遞的是一個字符串類型。

           

          這種參數具有動態類型的特性,是 c/c++ 等傳統的語言是所不具備的。這也是 python 被稱為動態語言的一個原因吧。 C++ 的高級特性模板,雖然也使得參數類型可以動態化,但使用起來,遠沒有 python 這么簡單方便。

          posted on 2007-01-19 00:17 苦笑枯 閱讀(367) 評論(0)  編輯  收藏 所屬分類: P2P
          收藏來自互聯網,僅供學習。若有侵權,請與我聯系!

          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(2)

          隨筆分類(56)

          隨筆檔案(56)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 措美县| 阳曲县| 两当县| 甘肃省| 宣恩县| 宣化县| 郓城县| 夹江县| 扎兰屯市| 醴陵市| 阳东县| 大城县| 余干县| 西华县| 海宁市| 张家港市| 松江区| 瑞金市| 读书| 神池县| 道真| 石泉县| 陕西省| 岱山县| 循化| 平罗县| 石柱| 钟山县| 盘锦市| 天全县| 娄烦县| 淮滨县| 特克斯县| 即墨市| 汉源县| 山丹县| 邢台市| 福鼎市| 遂平县| 英山县| 镇平县|