面向連接的TCP程序設計
相關閱讀:Linux網絡編程:基於UDP的程序開發回顧篇 http://www.linuxidc.com/Linux/2012-07/65692.htm
基於TCP的程序開發分為服務器端和客戶端兩部分,常見的核心步驟和流程:
其實按照上面這個流程調用系統API確實可以完全實現應用層程序的開發,一點問題沒有。可隨著時間的推移,你會覺得這樣子的開發毫無激情。為什麼TCP的開發就要按照這樣的流程來呢?而且一般出的問題幾乎都不在這幾個系統調用上,原因何在?當我們弄清網絡開發的本質,協議棧的設計原理、數據流向等這些問題的答案也就會慢慢浮出水面了。接下來這幾篇博文主要是圍繞網絡編程展開,目的是引出後面對於Linux下TCP/IP協議棧的相關分析做鋪墊。
1、 創建socket
到目前為止我們知道socket的作用其實是非常大的,它不僅能夠實現不同遠端主機間的數據通信,還是可以實現不同進程間的通信,以及用戶空間和內核空間的通信等等。其函數原型定義如下:
int socket(int domain, int type, int protocol);
domain:大家習慣性將其翻譯成“協議域”或者“地址簇”,牽扯到“協議”這個詞估計很多人就又暈了。也難怪,TCP、UDP我們叫協議,IP我們也叫協議,到處都是協議。那麼到底什麼是協議?說白了,協議其實就是事先規定好的數據通信方式。例如我們經常說的TCP/IP協議默認情況下都指的是IPv4版本協議,現在還有IPv6,它屬於另外一種協議,還有在電信網裡面經常聽到的X.25協議,用戶空間和內核空間通信的netlink協議等等。每種協議都有其特定的應用場景。這裡,我們可以通俗的將domain理解成“協議種類”。
type:直譯就是“類型”的意思。因為不同種類的協議提供了不同的數據傳輸方式,我們常見的有面向連接的流式傳輸模式、無連接的數據報傳輸方式等。
protocol:才是我們具體的協議類型,如TCP、UDP之類的。怎麼理解?我們知道在IPv4協議族裡,面向連接的流式套接字一般指的都是TCP協議。在電信網中NO.7信令體系中,實現了面向連接的流式套接字的協議就有ISUP和TUP協議。為什麼平時一提到面向流式的套接字大家條件反射的就想起了TCP,那是因為我們心裡已經默認了前提是IPv4協議族了。一般情況下,對於某種具體的套接字類型(流式或數據報式)都只有一種對應的實現協議,當然你心裡必須要知道對於某些協議族有可能有多種協議。對於我們的IPv4而言,在創建socket套接字時,當指定了地址簇、套接字類型、protocol協議字段一般都設置為0。
關於socket()函數我們再打個比方:
假如說socket()函數就是個造人的機器,我們給它輸入三個指令:
OK,當我們輸入:
socket(黑種人,會說話,英文) =>馬丁路德;
socket(黑種人,會說話,英文) =>威爾史密斯;
因為黑人缺省情況下說的話都是英文,所以他們會說話的功能也就僅局限英文了,不會有二義性。
可我們高貴的黃種人就不一樣了(JP不在此范疇),所以會說話的黃種人就多了去了。所以如果我們要造一個會說話的黃種人,必須進一步限定說話的語言才行。
socket(黃種人,會說話,中文) =>孔子;
socket(黃種人,會說話,朝鮮語) =>金正日;
通過這個例子,大家就可以好好體會一下socket()函數三個參數的作用和意義。