如何學習網絡編程

 如何學習網絡編程?這是我的經驗之談,我從來就沒有系統的學習過網絡編程(非科班麼),學習過程中走了不少彎路。最近在讀經典的《Linux程序設計(第3版)》,第十五章講的是套接字Socket編程,讀完之後,產生了一些想法,覺得有必要寫下來。

學習網絡編程我遇到的主要兩個困惑是:  
    第一:計算機網絡中的一個個協議都是抽象的,怎麼和具體實際結合起來呢?   
    第二:知道了socket編程的一般步驟後,如何能夠寫成複雜的服務器程序?(如Web服務器)

我的學習過程是這樣子的: 
  ●先是利用WinInet函數庫寫了幾個簡單的網絡應用程序:簡易登錄、查詢新書RSS等;瞭解了HTTP協議的一些內容。  
  ●後來又看了孫鑫的VC視頻教程,image ,雖然照着視頻能夠寫出實例代碼來,但是僅僅是會用,其中很多原理都不理解,比如說WSA開頭的異步函數,Winsock2對socket的一些增強或者改進等。  

  ●後來是一邊上《計算機網絡》的課,一邊讀《C++網絡編程》。通過計算機網絡課我知道了所謂的協議分析是怎麼一回事情,通過wireshark抓包分析,“協議”就如同這個詞本身意思是一樣的,是通信過程中的一種約定,規定了數據包中的每個或每幾個字節代表了什麼意思;   

  ●至於《C++網絡編程》,十分慚愧,我最大的收穫不是如何進行網絡編程,而是ACE框架的設計原則,通過實際的例子明白了設計模式是怎麼一回事情,可以去我的豆瓣書評 看看。  
  
● 再後來,偶然的發現了《計算機網絡高級編程技術》,我初略的翻了翻,看到裏面的基礎、提高、綜合訓練篇、突然反應過來:socket和操作系統提供的系統調用,基本上都是C語言接口的,協議字段的具體表現,不就是用結構體嗎?協議中的幾個字節代表什麼與C語言基本數據類型就能對應了起來(-_-!這是缺少實踐造成的遲鈍啊)。 

  ●再後來,瞭解了下Boost.asio,Java的MINA框架,這些都是異步I/O前攝器模式的實現,當然還有ACE_Proactor 

  ●再後來由於參加比賽的需要,飛快的閱讀了《深入理解MySQL核心技術》和Linux程序設計(第3版)》,就這樣從把整個知識體系都聯繫起來,從socket到完整網絡服務器程序,我的網絡編程纔算正式進入了門道。

所以,正常的學習路徑應該是:C/C++語言 -->>計算機網絡 -->>協議分析 -->>BSD Socket、OS API ( fork()、pthread_create()、select() ) -->>Reactor、Proactor模式

在這個過程我的體會是,最好是從Linux下或者Unix底下學習,比起Windows,Linux的編程接口設計更很簡潔,使用的基本上都是標準的數據類型,很多源代碼是開放的,而且我比較習慣於看小寫的英文單詞。。。我發現,如果最一開始能夠從整體上了解網絡編程的全景,就會知道應該學習什麼,下一步該學什麼,循序漸進纔是好的學習方法。

我所理解的“全景”:

--計算機網絡種類有很多種:ATM、X.25、Internet(大大小小的局域網互聯而成,以太網、令牌網等等)

---- Internet通信的協議也有很多種,其中最核心的是TCP/IP協議

---- 網絡編程接口也有很多種,BSD UNIX提出了socket,是一種通信機制,是管道概念的擴展

-------- socket有三種屬性:域(或協議族)、類型、協議

-------- 最常用的協議族有AF_UNIX和AF_INET(對應現在的Internet),AF_INET的類型又有兩種:數據流(tcp)和數據報 (udp)

------------ 在<sys/types.h>和<sys/socket.h>定義了socket編程的系統調用:socket()、struct sockaddr、bind()、listen()、accept()、connect()、close()、sendto()、recvfrom()

------------ 其中bind()是用來給創建的socket命名的,如果是AF_UNIX會關聯到文件系統的一個路徑上,如果是AF_INET則會綁定到IP的端口號上;listen()用來保存未處理的客戶請求的隊列;accept()等待客戶端的連接,會創建新的socket用來處理客戶端連接。

------------ 由於歷史原因,不同的計算機使用不同的字節序來表示整數,Intel和Motorola的處理器的字節序就不一樣,所以要轉換爲網絡序(好像Unicode中的Little-Endian、Big-Endian也是這麼個情況。。)

------------ 服務器必然爲多客戶服務的,爲了提高運行效率,高效利用系統資源,就出現多進程、多線程的服務端程序,這就需要用到fork()和pthread_create()了,再往下就是select()、pull()等多路複用和異步I/O機制了。

----------------爲了簡化網絡應用程序的開發,增加代碼的複用性、擴展性、可謂性;出現了Reacotr、Preactor等設計模式,出現了ACE、Boost.asio等框架、進一步簡化網絡開發的難度,出現了WinInet、libcurl這樣的面向應用層的函數庫。

最後我試着回答最開始的兩個問題:

    第一:描述協議基本上是C/C++中的結構體、協議中規定的多少字節代表什麼,對應中C/C++中的標準數據類型。這是因爲操作系統基本上都是用C語言編寫的,提供的接口也是C語言的接口。上層的一些協議如HTTP、SOAP、XMPP基本上純文本的,字符串就能表示。

    第二:複雜的服務器程序複雜之處在於對高性能、執行效率的要求,這就需要利用操作系統提供的一些機制,比如多進程、多線程、原生支持的異步I/O機制。針對軟件開發的複用性等要求,需要利用面向對象的設計思想,分層的思想、設計模式等


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章