socket學習第一天

理解套接口
在我們試着使用套接口之前理解套接口後面的一些內容是很重要的。這一部分描繪出圍繞着套接口的一些高級內容。
定義套接口
要與使用電話的某人進行交流,我們必須拿起話筒,撥打對方的電話號碼,並且等待對方的應答。當我們與對方通話時,就建立了兩個通信端點。
我們的電話,在我們的位置
遠方的對方電話,在他的位置。
只要我們仍在通話,就我們之間調用兩個端點,建立了一條通信線路。
Linux下的套接口也與電話相類似。套接口代表通信線路中的兩個端點。在這兩個端點之間存在着數據通信網絡。
在另一個方式上,套接口也與電話類似。當我們要打給某人,我們撥打我們要聯繫的人的電話號碼。套接口有網絡地址而不是電話號碼。通過指定遠程套接口地址,我們的程序可以在我們的本地套接口與遠程端點之間建立一條通信線路。
由此我們可以推斷,一個套接口是通信中的一個端點。有許多的Linux函數調用可以操作套接口,而我們將會慢慢的瞭解這些。

使用套接口
也許我們會認爲Linux套接口很特殊,因爲套接口有一個可以在其上進行操作的特定的函數集合。儘管套接口有一些特殊的屬性,但是他與我們十分熟悉的文件描述十分相似。
例如,當我們使用Linux的open調用打開一個文件,如果open函數調用成功,我們就會得到一個返回的文件描述符。在我們有了這個文件描述符以後,我們的程序可以使用文件描述符來read,write,lseek,以及close打開的指定文件。相似的,當創建了一個套接口時,他與文件描述符十分想似。我們可以使用相同的文件I/O函數來讀,寫以及關閉套接口。
然而在套接口與打開的文件之間也存在一些不同。下面列出了其中的一些不同之處:
我們不可以在套接口上執行lseek函數。
套接口有與其相關聯的地址。文件和管道沒有網絡地址。
套接口有可以使用ioctl函數進行查詢與設置的不同選項功能。
爲了執行輸入或輸出,套接口必須處理正確的狀態。相反,打開的磁盤文件可以在任何時候進行讀取或是寫入。

引用套接口
當我們使用open函數調用來打開一個新文件時,Linux內核就會返回下一個可用的並且是最小的文件描述符。文件描述符,或者是常稱之爲文件單元數,是零或者正的整數值,用來引用打開的文件。這個句柄會用在在打開的文件上進行操作的所有函數中。現在我們就會知道文件單元數也可以引用特定的套接口。
我們的程序已經打開了0,1和2三個文件單元(標準輸入,標準輸出,標準錯誤),接下來的程序操作將會被執行。注意內核是如何分配文件描述符的:
1 調用open函數來打開一個文件
2 返回文件單元3來引用打開的文件。因爲這個單元數當前並沒有用,並且是可用的最小的單元數,所以爲文件選擇了3作爲文件單元數。
3 通過一個合適的函數調用來創建一個新的套接口。
4 返回文件單元4來引用這個新的套接口。
5 通過調用open打開另一個文件。
6 返回文件單元5來引用這個新打開的文件。
注意:當分配單元數時,Linux內核在文件與套接口之間並沒有區別。用一個文件描述符來引用一個打開的文件或是一個網絡套接口。
這就意味着,我們作爲一個程序員,可以將套接口當作打開的文件一樣來使用。通過文件單元數交互的來引用文件和套接口的能力提供給了我們極大的靈活性。這就意味着read和write函數可以同時在打開的文件和套接口上進行操作。

套接口與管道的比較
在我們介紹任何套接口函數之前,我們來回憶一下我們已經熟悉的pipe函數調用。讓我們看一下他返回的文件描述符與套接口的不同。下面是由pipe的手冊中得到的函數概要:
#include <unistd.h>
int pipe(int filedes[2]);
當這個調用成功時,pipe函數會返回兩個文件描述符。數組元素filedes[0]包含管道讀端的文件描述符。filedes[1]元素是管道寫端的文件描述符。兩個文件描述符的這種安排提示了在每一端使用文件描述符的通信連接。這與使用套接口有何不同呢?不同就在於pipe函數創建了一個單向的通信線。信息只可以寫入filedes[1]中的文件單元數,並且只可以從filedes[0]中進行讀取。任何向相反方向寫入數據的嘗試都會得到Linux內核返回的錯誤。
另一個方面,套接口允許在兩個方向處理通信。例如,一個進程可以使用在文件單元3上打開的套接口向遠端進程發送數據。與使用管道不同,同一個本地進程也可以從文件單元3上接收到與其相通信的遠端進程發送的數據。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章