給套接字賦予地址過程中概念的澄清

  在使用socket編程時,我們都知道在網絡通信以前首先要建立連接,而連接的建立是通過對socket的一些操作來完成的。那麼,建立連接的過程大致可以分爲以下幾步:


  1. 建立socket套接字。


  2. 給套接字賦予地址,這個地址不是通常的網絡地址的概念。


  3. 建立socket連接。


  


  

1. 建立socket套接字

  使用socket建立套接字的時候,我們實際上是建立了一個數據結構。這個數據結構最主要的信息是指定了連接的種類和使用的協議,此外還有一些關於連接隊列操作的結構字段(這裏就先不涉及他們了)。


   當我們使用socket函數以後,如果成功的話會返回一個int型的描述符,它指向前面那個被維護在內核裏的socket數據結構。我們的任何操作都是 通過這個描述符而作用到那個數據結構上的。這就像是我們在建立一個文件後得到一個文件描述符一樣,對文件的操作都是通過文件描述符來進行的,而不是直接作 用到inode數據結構上。我之所以用文件描述符舉例,是因爲socket數據結構也是和inode數據結構密切相關,它不是獨立存在於內核中的,而是位 於一個VFS inode結構中。所以,有一些比較抽象的特性,我們可以用文件操作來不恰當的進行類比以加深理解。


  如前所述,當建立了這個套 接字以後,我們可以獲得一個象文件描述符那樣的套接字描述符。就象我們對文件進行操作那樣,我們可以通過向套接字裏面寫數據將數據傳送到我們指定的地方, 這個地方可以是遠端的主機,也可以是本地的主機。如果你有興趣的話,還可以用socket機制來實現IPC,不過效率比較低,試試也就行了(我沒有試 過)。


  


  

2. 給套接字賦予地址

  依照建立套接字的目的不同,賦予套接字地址的方式有兩種:服務器端使用bind,客戶端使用connet。


  Bind:


  我們都知道,只要使用IP, port就可以區分一個tcp/ip連接(當然這個連接指的是一個連接通道,如果要區分特定的主機間的連接,還需要第三個屬性 hostname)。


  我們可以使用bind函數來爲一個使用在服務器端例程中的套接字賦予通信的地址和端口。


  在這裏我們稱通信的IP地址和port合起來構成了一個socket地址,而指定一個socket使用特定的IP和port組合來進行通行的過程就是賦予這個socket一個地址。


   要賦予socket地址,就得使用一個數據結構來指明特定的socket地址,這個數據結構就是struct sockaddr。對它的使用我就不說了,因爲這篇文檔的目的是澄清概念而不是說明使用方法。Bind函數的作用就是將這個特定的標註有socket地址 信息的數據結構和socket套接字聯繫起來,即賦予這個套接字一個地址。但是在具體實現上,他們兩個是怎麼聯繫在一起的,我還不知道。


  一個 特定的socket的地址的生命期是bind成功以後到連接斷開前。你可以建立一個socket數據結構和socket地址的數據結構,但是在沒有 bind以前他們兩個是沒有關係的,在bind以後他們兩個纔有了關係。這種關係一直維持到連接的結束,當一個連接結束時,socket數據結構和 socket地址的數據結構還都存在,但是他們兩個已經沒有關係了。如果你要是用這個套接字在socket地址上重新進行連接時,需重新bind他們兩 個。再註明一次,我說的這個連接是一個連接通道,而不是特定的主機之間的連接。


  Bind指定的IP通常是本地IP(一般不特別指定,而使用INADDR_ANY來聲明),而最主要的作用是指定端口。在服務器端的socket進行了bind以後就是用listen來在這個socket地址上準備進行連接。


  


  connect:


   對於客戶端來說,是不會使用bind的(並不是不能用,但沒什麼意義),他們會通過connet函數來建立socket和socket地址之間的關係。 其中的socket地址是它想要連接的服務器端的socket地址。在connect建立socket和socket地址兩者關係的同時,它也在嘗試着建 立遠端的連接。


  


  

3. 建立socket連接

  對於準備建立一個連接,服務器端要兩個步驟:bind, listen;客戶端一個步驟:connct。如果服務器端accept一個connect,而客戶端得到了這個accept的確認,那麼一個連接就建立了。

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