peercast源**是我第一次看超過2萬行的**,在這期間收穫很大,也積累了一些經驗。peercast源**是我第一次看超過2萬行的**,
在這期間收穫很大,也積累了一些經驗,在此與大家分享,希望為大家看源**提供一些幫助和參考.
這裡主要介紹的是在visual stdio6.0環境下,看peercast的win32版本**的一些經驗
1.拿到源**的第乙個步驟是編譯並執行,而且你首先要對如何使用它掌握得一清二楚
這是必不可少的步驟。乙個無法編譯並執行的源**對你毫無任何幫助,而當你編譯成功後,以後你修改**的所有問題都是你的錯。要深刻理解**顯然要先理解**產生的功能,所以你必須去執行它,先會用才能進一步掌握它的內部執行機制
所以,拿到peercast原始碼後,我希望你先弄清楚如何編譯即編譯的步驟,這我在《源**編譯方法》已經給出
你所要做的就是先將其編譯一遍從而確認沒有錯誤
然後掌握peercast的執行方法,如何通過黃頁收聽廣播電台、如何通過位址方式收聽廣播電台、如何廣播***、wmv、asf等檔案,如何檢視日誌和統計資料,這些都是不可忽略的步驟
2.理解整個系統是個拼圖的過程
這正如拼圖一般,剛開始你只是在小範圍內試著拼,慢慢地你看出來整體的一些端倪,然後你不斷地通過區域性來理解整體,再從整體來理解區域性,最後拼成了最終的一幅完整的圖
所以,面對龐大的**千萬不要灰心,只要你足夠堅持,總能拼出那個完整的圖案
剛開始我也是被peercast**所嚇倒,繁雜的類和函式,實在不敢相信我什麼時候才能夠看完,而且根本不知從何看起
這裡有幾點建議:
1.當不知道從何看起時,從程式的起始點看起總是乙個不錯的手段,所以在看win32**時,一般從winmain看起
2.在看c++**時,一般要先從各個類的定義看起,先弄清楚各個類是用來完成什麼功能的,再去理清類與類之間的相互關係,當然剛開始你都是在猜測,然後是驗證
3.c++中往往是先通過幾個類產生這個類的物件,然後由這些物件再建立出其他的物件。因此對於程式初始時建立的一些物件尤其是全域性物件,你必須特別注意,因為他們貫穿整個**的始終,而且很有可能是串起整個**的核心所在。沒錯,我想如果你注意到了這三個全域性物件的話,你就知道重點在哪了,它們是sys、chanmgr、servmgr,它們永遠是我強調的重點。
4.看源**是個反覆的過程,甚而是個不斷延伸的過程。例如要理解函式a()必須去檢視b(),由於它呼叫了b(),而為了理解b()又必須去檢視c()的**,這就必須要求你要清楚地知道你要理解的是什麼,即使你看到了f(),在這個過程中你要始終知道你是為了理解函式a()的功能,千要不要迷失在**的海洋裡,你要記得抓住重點。很多函式本身就是個黑匣子,例如wsys類,剛開始的時候你不必去理解它是如何實現的,只須將其看成庫來使用就可以了。
5.分清類庫和核心類。peercast的類庫都是自己實現的,所以你必須仔細分清類庫和核心類,核心類你要仔細研究,而類庫只需關心它是如何使用的即可。例如filestream類,你只需知道filestream::write()是用來實現向檔案中寫資料就可以了,至於其內部如何實現可以不去管它。而向servent類,你自然必須對它的各個函式的內部操作理解透徹。
總之,記著看**的過程中要有一條主線,同時分清重點和次要點。
所以,看**的步驟是:
概覽全域性->找出重點->理解重點->檢視分支->理解全域性
而這是乙個迭代的過程,每個迴圈你都在向最終目標又靠近了一層
當你拼圖時,如果你能大致看看整個拼圖的樣子,是否能為你提供很大的幫助呢?
猜測是個很不錯的手段,尤其是在**質量高命名清晰的情況下,你往往可以猜到這個類或函式是完成什麼功能的
比如說你看到channel類,你會猜想這個類應該是來完成頻道的建立、刪除工作的吧,沒錯,就是如此。
那麼,多個頻道是如何管理的呢?這時你注意到了chanmgr類,chanmgr,應該是channel manager的縮寫吧,而且你甚至可以猜想到chanmgr類應該包含channel的多個物件。
好了,剩下來你要做的事情就是去驗證你的猜想是否準確了。
3.文件
文件絕對是個事半功倍的東西,所以你必須不惜任何代價去找到與這份**相關的文件
peercast沒有文件,但有個好地方你不能不去,那就是peercast的官方論壇,作者giles也在裡面發言,我從他的發言裡面學到了不少peercast的設計思想
所以我建議大家一定去www.peercast.org/forum看一下,不管是使用技巧還是程式設計版塊,你總能找出自己需要的東西。在網上大量的資訊面前找到自己真正需要的文件是一項必備技能,我們需要一針見血。
4.從日誌檔案著手是個看源**的好方法
通常開源**都會有比較詳細的日誌檔案記錄。通過檢視日誌檔案,可以很清晰地理清源**執行的流程,從而為理解源**提供方便。
例如我想理解peercast啟動的**流程:
其中日誌檔案如下:
sessionid: 002b372da1f08103c65aa48de4f28633
cmd: tip, arg: 202.205.16.102:7144"
allocated servent 1
allocated servent 2
starting servers
server started: 127.0.0.1:7144
server started: 127.0.0.1:7145
add hit: 202.205.16.102:7144/0.0.0.0:0
searching for: 634f445c6f4160f85f7829954ffa5713 ()
new channel created
這樣我在源**中依次搜尋sessionid:、cmd:、allocate servent、starting servers欄位
相應的執行函式豈不一目了然
bool servmgr::start()
void servmgr::procconnectargs(char *str,chaninfo &info)
{char arg[512];
char curr[256];
//使args等於?後面的字串,即tip=211.132.83.9:7144
char *args = strstr(str,"?");
if (args)
*args++=0;
info.initnameid(str);
if (args)
{//nextcgiarg分解字串,把"tip"儲存到curr中,"211.132.83.9"儲存到arg中
while (args=nextcgiarg(args,curr,arg))
{log_debug("cmd: %s, arg: %s",curr,arg);
而且我也可以很清楚的看到log_debug是用來輸出日誌檔案用的,而servmgr是個重要的類,可以用來提供初始化和連線等重要功能
這樣我要研究peercast**,是不是可以從servmgr著手呢,沒錯!
5.學會跨檔案搜尋是個很重要的手段
可以說跨檔案搜尋是閱讀源**的核心所在,我們想要查詢某個函式或者理解函式之間的呼叫關係,跨檔案搜尋是必要的手段
如果是vc6.0環境則比較簡單,只要選擇find in files選單,然後選擇好in folder即要查詢的資料夾的路徑即可
linux比較麻煩一點,要學會用grep命令進行搜尋,但這是必經之路
另外,推薦sourceinsight,這實在是個看原始碼的絕好工具。
6.嘗試去修改和抄寫**
你是否理解**有個很簡單的衡量尺度,那就是,如果你能很輕易地修改它並且好無錯誤,你必然很深刻地理解了這段**,否則只是紙上談兵而已,這正如看書,如果你無法對別人複述書的內容,那我也不相信你很好地理解了這本書的精髓
將你暫時難以理解的部分**原樣在電腦中敲打一遍也不失為一種好方式,這正如古人抄書一般。我當初也是把peercast的核心**重新實現了一遍才真正理解了peercast的執行流程的。
7.將難以理解的**列印出來,找乙個安靜的地方仔細研究
我們在電腦前總是容易喪失縝密思考的能力,所以你需要的是乙個安靜的地方好好思考
圖書館絕對是個好地方,是個去了就想學習和思考的好地方
《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具
檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...
原始碼閱讀 Glide原始碼閱讀之with方法(一)
前言 本篇基於4.8.0版本 原始碼閱讀 glide原始碼閱讀之with方法 一 原始碼閱讀 glide原始碼閱讀之load方法 二 原始碼閱讀 glide原始碼閱讀之into方法 三 大多數情況下,我們使用glide 就一句 但是這一句 裡面蘊含著成噸的 with方法有以下幾個過載方法 publi...
FreeRTOS原始碼閱讀 一
之前閱讀了rt thread 的原始碼,rtt原始碼是unix風格,看起來比較熟悉.最近有些空閒時間,打算閱讀freertos的原始碼,看看兩者的差別。freertos作業系統是完全免費的作業系統,具有原始碼公開 可移植 可裁減 排程策略靈活的特點,可以方便地移植到各種微控制器上執行 來自度娘 如今...