如何深入學習 TCP/IP 協議,以及網路層、傳輸層、應用層各協議?
我基本把計算機網路自頂向下方法看得差不多,也搭過一些網路服務,但不大會網路編程,目前不知道該如何深入學習下去,想通過把tcp/ip原理搞懂,進一步研究哈通信系統中一些硬體的工作方式,不知可行否??希望各位給些建議,謝謝。。。
學習TCP/IP協議的終極方法是自己研究並實現一個TCP/IP協議棧。
在Linux內核層面,是要實現下圖紅框內的部分。
乍看這個做法有點不可思議,但其實並沒有看上去那麼難,下面提供一個可行的方法。
1、確定一個Linux發行版,Ubuntu、RedHat都行,uname查看內核具體版本,去The Linux Kernel Archives下載該內核源碼。
2、通過Linux相關文檔大致了解源碼中Net -&> ipv4目錄下的協議棧源碼結構與對應協議原理。
3、通過rmmod命令卸載原TCP/IP協議棧。
4、在原Linux 協議棧源碼基礎上做修改,假設新的協議棧叫ABC協議棧,編譯後利用insmod掛載到Linux內核。
5、配置ABC協議的ip地址,利用新實現的協議棧做最簡單的數據傳輸。
6、迭代研究協議棧各層的功能,並利用輸出查看各層協議頭的封裝與解析。
- 追蹤Linux TCP/IP代碼運行 北京航空航天大學出版社
- Linux內核源代碼情景分析 浙江大學出版社
- Linux 設備驅動程序 中國電力出版社
如果真有興趣實現的話可以私信聯繫。
1.網路的東西看再多數也不如動手,例如想弄懂FTP就抓包分析FTP登錄、下載過程。
2.網路能正常工作,離不開報文和狀態機的準確性
3.善用工具,而不是文檔
4.分析問題需要的是思路和方法,思路和方法來源與1)、2)
5.硬體能協同工作,和匯流排、標準、規範緊密相連,搞清楚你研究的對象屬性和範圍,很重要!!!
首先,看《TCP/IP 詳解》卷一,這本書太好了,尤其要細看前言,字斟句酌反覆看。看完之後,對於TCP/IP你就有個概念了。至於其他的協議,要不已經被淘汰,比如IPX,要不應用面太窄,比如SCTP,先不用管。
然後,先忽略交換和路由知識吧,這是另一個知識領域。
然後,網路編程,你都提了這個了,網路編程入門不難,不管是winsock還是posix api都很容易上手,調通第一個程序之後再看後續的其他東西,什麼是阻塞什麼是非阻塞,select、poll都是怎麼回事,ace還有其他的一些框架都有哪些特點怎麼用,等等。
然後,如果感興趣,可以看看網路協議棧的實現,比如看linux源代碼,或者看《TCP/IP 詳解》卷二
然後,你還提到了硬體,硬體就複雜了,種類多到令人驚奇。可以考慮看看常見網卡晶元的文檔還有驅動代碼,再看看openwrt一類的東西,就有基本概念了。
最後,回到開始,需要明確學習的目的和目標
TCP/IP協議跟硬體似乎沒有什麼關係,即使你看到了數據鏈路層,能和硬體相關的東西也不是很多,更不要說硬體的工作方式了。好好了解一些協議的原理,比如TCP、UDP、IP這樣基礎的東西,然後由這些擴展再看其他的協議就可以了。如果可以,配合使用一些嗅探器抓一些數據包來看一下格式和結構,這樣子有助於學習。
網路編程的話,從socket開始學習和了解就可以了,區分面向連接的和面向報文的兩種方式,主要是TCP和UDP。建議結合實際工作來學習;
我現在在弄數據吞吐量測試,底層和應用層都有,雖然是測試,但能看到很多流程和數據,建立FTP和UDP連接、上行下行、壓力測試、衰落測試、干擾測試等。
書得多準備幾本精品,推薦國外的翻譯版本,至少應該有本「計算機網路」吧,還有國外儀錶廠商的一些資料也值得讀讀借鑒。天朝的書大多是研究生幫著翻譯,錯很多。1. 認真看完《TCP/IP協議詳解》
2. 對照著上面的書使用tcpdump或是Wireshark抓包研究
3. 如果想進一步研究實現,看《Linux網路技術內幕》並對照Linux Kernel代碼研究
對任何事情的學習,如果你找到正確的方法(tz在知乎提這個問題就是在尋找最佳方法),並循序漸進的進行學習,並堅持下來,沒有什麼做不到的。
我說下怎麼循序漸進的進行學習,我也是網路初學者,結合自己情況說下吧!
1,首先tz對網路原理有個overview(要求:了解術語,有什麼協議,協議之間有什麼關係),推薦看《計算機網路原理----謝希仁》,有配套公開課,西交的,tcp/ip卷1也行。
2.開始實戰,socket編程。把第一步學習的術語和概念,協議之間的關係,運用到編程中,加深理解,資料在豆瓣書籍搜索「socket」關鍵字,至於平台基於自己的愛好。
3.這一步就是看協議之間的內部啦,看源碼就行啦。怎麼看呢?由點到面,根據自己的需求看源碼。它這個人你了解啦,你想探索它的心臟器官,你一定能找得到,資料google之。
我剛搜索lwip結果竟然搜到你這個問題。說明知乎也知道lwip是tcpip的一種實現方式。
你特意強調「深入」,那麼我把我的體會分享一下,儘管我掌握的不夠深入,因為正式下決心理解乙太網還不到半年。
第一,要有動力,有目標。就是什麼原因促使自己"深入"掌握這個協議。因為tcpip協議給大多數人的感覺還是有難度的。從實現方式看linux的tcpip難還是lwip難?我也不清楚,哈哈。但是lwip為了在小型設備上能完整實現tcpip,它的結構按常理講結構會更不清晰一些。
第二,要有較為紮實的基礎。從看源碼的角度說,首當其衝是c語言基礎要紮實。
第三,是方法。每個人的方法大概都會不大一樣,因為每個人的以往的經歷或者見識不一樣。這裡說下我自己的方法。我用的是在單片機stm32上跑lwip代碼。首先在淘寶買個板子,在st官網下載個demo跑起來。先會個最基本的udp通訊。查查資料,看看幀結構。大概學學各種工具,如wireshark等,混個臉熟,找找感覺。這個階段很重要。可以翻翻書,比如謝希仁的。比如知道ping是怎麼回事。這個階段我覺得可以稱作是「紙上得來終覺淺」的階段。如果你的學習只是止步於這裡,那麼很抱歉,隔一段時間如果不接觸tcpip,很快你所學就會忘光光。我想,這不應該被稱作「我的臆斷」,因為我在學其他東西有這種體會。說到這裡,這階段其實我只會了udp的應用,就是會發送和接收(當然如果你想看看tcp的握手之類的東西也是可以的,儘管我沒有這樣)。下一步我就開始精簡代碼了。從我以往經歷的讀寫代碼經驗看,即便再複雜的代碼都是由各個簡單的分支構成,如果代碼實現的優雅,那麼各個分支就會涇渭分明,透徹見底。但是一般像 os內核或者lwip組件這種代碼往往由大牛來實現,因此在大的結構上,還是優雅的,但在細節上,大牛也非完人。嗯,似乎有點跑題。好,繼續寫精簡代碼。這個過程是個逐步精簡的過程,要注意保存好各個精簡後的版本。每精簡一部分,然後運行看看udp的發送和接收還好用不。比如,可以刪除tcp,snmp,igmp,icmp……,最後讓我刪的只留下arp ,udp, ip,還有內存實現。好,我就發送udp用wireshark抓包,涉及到arp的具體實現了。對照代碼邊在線模擬看,邊查找書籍,比如謝希仁和卷123,這個arp實現還是需要一定的時間投入的,要把幾種情況都熟悉一下,比如如何過路由,如何實現arp欺騙。這個過程我覺得可以稱作「絕知此事要躬行」。回頭再看卷123的arp部分,甚至會覺得太淺顯易懂了。若arp,udp,ip都看的差不多,可以想想如果自己來寫這個協議,會如何實現呢?下一步,再逐步添加各個協議,當然是先添加較為簡單的、孤立的協議。想想看,lwip的作者寫代碼肯定也是一點點、一步步把代碼堆起來的。至於作者的實現過程我們是不得而知的,因為官網的首個版本就較為完整。另外,我個人經驗,一般寫完代碼後都有點小遺憾,但是都由於這樣或那樣的理由懶於重構,尤其是tcpip這種需求固定(協議固定)的代碼,哈哈,最後這些是真正的"臆斷",甚至是胡思亂想了。
第四,是要有恆心,要堅持住。
不知不覺,寫了這麼多。一氣呵成,痛快!
一家之言,僅作參考!
推薦你看一本書,只需要這一本書 《TCP/IP 詳解》中文版
推薦閱讀《通信網------基本概念與主體結構》
如果是理解TCP/IP協議棧建議閱讀《TCP/IP詳解》,如果是希望針對LINUX進行編程還是看LINUX源代碼比較好。不過《TCP/IP》詳解這本書寫的非常透徹對深入了解TCP/IP協議棧很有幫助。在看完這本書再來分析LINUX就會覺得比較輕鬆了。畢竟LINUX在這一塊沒有UNIX設計的優美直觀(個人覺得)
推薦閱讀:
※TCP四次分手中,主動關閉方最後為什麼要等待2MSL之後才關閉連接?
※tcp首部只有埠號沒有ip地址,那麼網路層怎麼知道目的ip地址的呢?
※關於CSMA/CD的問題?
※SCTP同時具有TCP和UDP的優點,但是為什麼應用不廣?
※如何正確關閉 tcp 連接?