Linux Socket學習--套接口的類型和協議


          我們首先來說一下PF_INET和AF_INET,雖然標准提倡在指定demain參數的時候,優先使用PF_INET,但是大量已經編寫的c代碼遵循舊的協議。目前情況是AF_UNIX=PF_UNIX,AF_INET=PF_INET。但是將來是不是這樣不好說啊。

          不同於socketpari函數的demain參數只能指定為PF_LOCAL,socket函數可以用於生成所支持的任何協議族的套接口,語法如下:

#include <sys/types.h>
#include <sys/socket.h>

int socket(int demain, int type , int protocol);

編程者通常為type參數取值如下:

SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW.

       當編程者想在遠程套接口上實現I/O的時候,就可以使用SOCK_STREAM套接口選項。字節流中沒有分界線,也沒有邊界,沒有記錄的長度或者塊的大小,在接受端也不存在分組的概念,在接受端獲得的所有的數據都返回到調用者的緩沖區中。

       上面可能說的不清楚,我們在詳細的解釋一下:加入本地主機想通過兩次獨立write調用遠程主機發送數據,過程如下:

        1.本地進程寫入25字節,然后發送到遠程進程。

        2.本地進程在寫入30個字節,然后發送到遠程進程。

        3.遠程進程從套接口接收數據,接受緩沖區最大為256字節,接受進程共收到2次發送的55個字節。

        也就是說本地進程執行了倆次獨立的操作,可能寫入了2個不同的消息或者數據結構,但是遠程進程並不關心本地進程進行了幾次寫操作。她只是將這55個字節作為一個整體來看待。

        從上可以看出,一個流套接口不會保留任何的消息邊界,她只是簡單地向接收進程返回他所擁有的數據。

       流套接口的另外一個重要的性質是有序性。她可以保證把字節按照寫入的順序發送到接受端。SOCK_STREWAM套接口可以確保接收程序完全按照數據發送的順序進行接收。

       下面總結一下SOCK_STREAM性質:

         1. 不保留消息邊界。2.保證接收字節順序和發送的順序一致。3.保證寫入的數據在接受端被無錯的接收。如果有錯誤發生,在嘗試玩所有的錯誤恢復措施之后,如果還是無法消除錯誤,那么流套接口就會回報錯誤。4.數據是通過一對連接的套接口傳輸的,SOCK_STREAM意味着在通信之前必須建立一個連接。

下面我們來談談SOCK_DGRAM類型:

       在不需要考慮數據絕對有序性和可靠性的時候,我們可以使用SOCK_DGRAM。下面是她的一些性質:

     1.分組發送后可能無序到達接受端。2.分組可能丟失。丟失了也不會采取措施補救,接受端也不知道有丟失。3.數據報分組有大小尺寸的限制,如果超出限制,在某些路由器或者節點上無法傳送。4.分組在不建立連接的情況下被發送到遠程的,這個也就容許本地進程每次將消息發送給不同IP地址上同樣的端口。

     需要注意的是並不是每個協議族都可以使用所有的套接口類型,例如PF_INET支持SOCK_STREAM,但是不支持SOCK_SEQPACKET類型。

選擇協議

     事實上,我們很少設定protocol參數的值,而只是簡單的設置為0 ,這個時候,Linux內核就會根據其他參數的情況自動選擇一個正確的協議。但是一些編程者習慣於明確的描述protocol參數的值,這個對於需要特定協議支持的程序來說很重要。

使用PF_LOCAL和SOCK_STREAM

     在函數socket和socketpair中,對於PF_LOCAL套接口,我們可以對protocol參數使用0值,這個是protocol參數唯一支持的值。因為到目前為止,如果函數socket和socketpair函數的domain參數為PF_LOCAL/PF_UNIX的時候,protocol的參數的唯一有效值為0.

 使用PF_LOCAL和SOCK_DGRAM

     當需要保留消息邊界的時候,我們可以在本地套接口上使用SOCK_DGRAM,在domain參數為PF_LOCAL的SOCK_DGRAM套接口中,protocol參數的唯一有效值為0、

     PS:套接口生成以后,他還處於“無名”狀態,就是說還沒有地址,編程者必須建立一個有效的地址,並通過bind函數把地址綁定到套接口。

使用PF_INET和SOCK_STREAM

      目前,在domain參數為PF_INET的SOCK_STREAN的套接口中,protocol的參數為0意味着內核選擇IPPROTO_TCP,也就是套接口使用TCP/IP協議。

使用PF_INET和SOCK_DGRAM

     這個組合告訴內核選擇UDP協議。也就是選擇IPPROTO_UDP。

下表是一個總結:

image

當然Linux支持許多的協議,此處不多說。

有關協議族的一些宏定義在sys/socket.h頭文件中,而實際上這個文件包含了另外一個定義協議宏常量的頭文件,它的路徑名是:

/usr/include/bits/sockett.h

我們可以使用grep命令將內核中可能支持的協議打印出:grep PF_ /usr/include/bits/socket.h


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM