?? emule源代碼解析-1.txt
字號:
eMule的官方首頁上寫著:2002年05月13日 一個叫做 Merkur 的人,他不滿意原始eDonkey2000客戶端并且堅信他能夠做的更好,所以他開始制作。他聚集了其它開發人員在他的周圍,并且eMule工程就此誕生。
eMule是一個典型的MFC程序,它的圖形界面等,已經和MFC緊緊融合到了一起。因此通常情況下它只能在windows平臺下運行。有一些其它的工程,如aMule等,把它進行了移植,因此跨平臺的功能要強些。
其實還有另外一個叫做xMule的工程,不過現在已經人氣快不行了。在aMule的主頁上可以看到eMule移植到linux平臺下的一些歷史,最早是有個叫做lMule的工程,他使用wxwidgets來進行eMule的跨平臺的移植,這個工程2003年就不再更新了,后來轉變成為xMule工程,它一度是linux平臺下eMule的事實上的替代品。但是他們的程序員之間由于理念不同,發生了內訌,導致aMule分裂出來,他們后來矛盾嚴重的時候曾經一度從理念問題上升到互相對對方進行人身攻擊,并且曾經對對方的網站發動過DDos。后來aMule和xMule就是兩個完全不同的工程,xMule現在只有HopeSeekr一個人在維護,基本上也沒有什么更新了。這一點不僅讓人感慨。今年寒假的時候我曾經和HopeSeekr進行過一些交流,感覺他非常自信,經常拿著aMule的一部分代碼來給我看,說你看看他們的代碼這么這么寫,這簡直就是一陀xx嘛,這種代碼在某些情況下肯定會Crash掉嘛,相反,你看看我們xMule的代碼,這里是這樣這樣,肯定就不會有這種問題了。
eMule從0.42版開始支持Kad技術,這是一個非常重要的里程碑。Kad是一種DHT的協議,它可以使節點之間互相保留一些其它節點的聯系信息,并且利用這樣一個“關系網”尋找到整個網絡中的任何一個節點以及上面的資源,整個過程不需要任何中心服務器。因此向當年搞napster那樣直接端掉中心服務器就搞跨napster網絡一樣來對付eMule的Kad網就毫無作用了。0.42版是2004年2月27日放出的,比eDonkey2000的OverNet晚了將近一年,但是它的Kad網絡的規模卻在迅速擴大。Overnet和eMule中的Kad使用的都是Kademlia結構,但是具體的消息報文的格式有區別,因此兩個DHT網絡并不能互相兼容。OverNet直到現在,用戶也仍然維持在十萬左右,這是比較近的一篇文章寫的。但是eMule的Kad網的規模有多大,目前卻沒有一個很準確的說法。由此也可以看出開源軟件的力量。目前aMule的Kad網和eMule的Kad網是兼容的,xMule中還沒有Kad的支持。Kad協議的原始paper可以在我們實驗室的機器上下到:
http://bigpc.net.pku.edu.cn:8080/paper/new/by%20conference/IPTPS/IPTPS02/Kademlia%20A%20Peer-to-Peer%20Information%20System%20Based%20on%20the%20XOR%20Metric%28IPTPS02%29.pdf
eMule的代碼結構非常合理。雖然代碼量比較大,但是各個功能模塊之間的劃分都很合理。從它的工程文件里面就可以看出這一點。eMule把表示功能的代碼文件和表示界面的代碼文件分開了,Source Files和Header Files是實現功能的代碼的源文件和頭文件,而Interface Source和Interface Header是實現圖形界面的源文件和頭文件。由于eMule的代碼量太大,本系列將跳過圖形界面的實現,著重分析eMule的功能實現部分的代碼,而且功能實現方面也主要挑主要的部分分析。本節將從emule.cpp開始分析,引出eMule中使用到的幾個主要的功能實現的類,并大體描述它們的作用。最后介紹一下如何在VS2003下編譯eMule。emule中還有不少模塊實現的功能挺有用,我說的是在其它的程序里很有用,可以考慮在其它程序中進行復用。
emule.cpp為類CemuleApp的實現。因此在運行時,首先會運行InitInstance進行一些初始化的工作。從這個函數里面我們也可以第一次看出那些即將在整個程序中發揮作用的類了。
最開始的時候是計算出程序常用的一些目錄,如配置文件,日志文件等。接下來是ProcessCommandline,它的作用有兩方面,第一是確認該eMule的運行方式,即命令行后面有沒有參數,第二是確認目前eMule是不是只有一個實例在運行。在一般的情況下,雙擊eMule可執行文件是不會帶參數的。但是通過點擊鏈接或者打開關聯文件的方式打開eMule則相當于帶參數運行eMule。通過在注冊表里添加一些項目可以讓一個程序和某種鏈接或者某個后綴的文件產生關聯。具體辦法可以參見OtherFunctions.cpp中的Ask4RegFix,BackupReg,RevertReg三個函數的功能。ProcessCommandline中通過創建帶有名稱的互斥信號量來確認是否有其它的eMule實例在運行。對于一個確定的名稱,CreateMutex只能創建一個互斥信號量。因此通過該信號量是否創建成功就可以知道是否有其它eMule實例運行。如果有的話,而且又是帶參數的那種模式,那么直接把這個參數使用Windows的消息機制發給那個窗口即可,接下來的代碼無非就是如何找到另外一個叫"eMule"的家伙以及給它發個什么消息。pstrPendingLink是一個全局變量,表示將要被處理的命令行參數。它將會在初始化完成后一段時間后被處理。
下面兩個比較重要的類是CPreferences和CStatistics。前者掌握著程序的大部分配置數據,后者則進行各種統計。它們的特點都是有很多的成員變量,而且還是靜態的,這種方式可以保證它們的唯一性,而且把這些變量統一到一個類管理。但是實際上并不需要了解每個變量的含義。thePrefs和theStats是這兩個類的唯一的實例。
在處理完其它一些事情,包括創建圖形界面對象CemuleDlg后,接下來可以看到一排一排的創建新對象的語句。這些類將會實現eMule程序運行的主要功能,后面的系列將詳細分析。
最后描述一下如何在VS2003里編譯eMule,由于eMule中用到了一些其它的庫,因此官方在提供eMule的源代碼下載的同時如果也提供這些庫的下載會使源碼包變得很大。因此eMule選擇了讓開發者去那些庫的官方網站下載它們的方式。一般來說,編譯這種工程文件,很重要的地方是要保持各個庫和主程序編譯參數的一致性。這些編譯參數中,最主要的參數有三個,字符集(多字節/Unicode),調試/發行,單線程/多線程,這樣排列組合一下就有八個版本了。因此編譯的時候如果不注意,就會出現和程序設計無關的錯誤。
eMule0.47a解壓后自帶id3lib庫,還需要下載以下的庫:
zlib:
http://www.gzip.org/zlib/
ResizableLib:
http://sourceforge.net/projects/resizablelib/
Crypto++:
http://www.eskimo.com/~weidai/cryptlib.html
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -