Linux Socket學習 域和套介面簡介

2021-09-23 21:29:25 字數 2596 閱讀 8784

套介面建立後,就如同乙個檔案描述符,我們可以使用同樣的io函式進行讀寫,關閉操作。其實,和引用乙個已經開啟的檔案一樣,套介面也是通過檔案描述符來引用的,而且兩者的檔案描述符共享乙個「數字空間」,比如說不能既開啟乙個檔案描述符為4的套介面,又開啟乙個檔案描述符為4的檔案。

套介面和已經開啟的檔案的區別:

1.不能在套介面上呼叫函式lseek()當然對於管道也不能呼叫這個函式。

2.套介面可以和網路位址關聯,但是檔案和管道卻不可以。

3.套介面有很多可以通過ioctl()進行查詢和設定的選項。

4.套介面必須在正確的狀態寫才能進行輸入輸出,但是已經開啟的檔案可以在任何的時候進行讀寫操作。

呼叫open()函式開啟乙個新檔案,linux核心會返回乙個當前系統可用的最小的檔案描述符。比如如果關閉了標準輸入(檔案描述符0),又立即開啟乙個新檔案,那麼新檔案的檔案描述符就是0.

另外要注意的是linux核心在分配檔案描述符的時候,並不區分這個描述符是分配給套介面還是給已經開啟的檔案的。      

我們知道,使用int pipe(int fileds[2]);函式可以建立管道,如果這個函式呼叫成功,核心會返回兩個檔案描述符,fileds[0]表示管道讀出端的檔案描述符,fileds[1]表示管道寫入端的檔案描述符。所以可以看出管道是單向的,任何的反方向操作會導致錯誤。

但是套介面不同,他可以進行雙向通訊。這個也是他和管道的根本差異。

建立乙個套介面使用以下的函式:

#include #include int socketpair(int domain,int type,int protocol,int sv[2]);

下面我們來展示乙個socketpair的例子:

#include #include #include #include #include #include #include int main(int argc, char const *ar**)

printf("s[0]=%d\n", s[0]);

printf("s[1]=%d\n", s[1]);

return 0;

}

其中af_local套介面又被稱為是unix套介面,所以使用af_unix和使用af_local都是一樣的。不過建議使用af_local。

下面我們來展示一下使用套介面實現i/o

………………undone(此處**待新增)

我們來看看如何關閉套介面

當我們從管道讀取輸入的時候,讀取程序受到檔案結束標識以後就知道沒有後續檔案了,因為檔案描述符是由寫程序關閉管道的寫段的時候傳送的。套介面的關閉類似,當在套介面傳送端關閉後,接受端就會受到檔案結束標識,但是這種關閉方式不適用所有的情況。close終止了資料傳送的兩個方向:讀和寫,由於tcp是全雙工的,在很多的情況下,本地程序要通知遠端端點已經完成了資料的傳送工作,但是仍然等待從遠端端點接受資料,在這種情況下,我們需要對套介面進行半關閉操作,就需要用到shutdown函式:

#include int shutdown(int s, int how);

其中s是需要進行半關閉的套介面,需要進行關閉的方式是how,引數how的取值請看下表:值巨集

描述0shut_rd

程序不能對指定套介面進行讀操作

1shut_wr

進行不能對指定套介面進行寫操作

2shut_rdwr

程序不能對指定套介面進行讀寫操作

大家可以看出,當how引數的取值為2的時候,shutdown函式和close函式一樣了。下面舉乙個例子:

int state;

int s;

state=shutdown(s,shut_wr);

if(z == -1)

下面我們來看看如何處理複製套介面的情況:

如果呼叫函式dup或者dup2的話,那麼只有最後乙個close呼叫才可以關閉套介面,系統這樣做,是因為他認為其他複製的檔案描述符仍然在使用中,如下所示:

int s;   //已經存在的套介面

int d;    //被複製的套介面

d=dup(s); //複製套介面

close(s) // 套介面並未被關閉

close(d) //套介面被關閉

在上面的例子中,第乙個close函式呼叫並沒有關閉套介面,其實無論先關閉s還是先關閉d,沒任何區別。而只有當最後乙個檔案描述符被關閉的時候,套介面才是被真正的關閉了。但是如果使用shutdown函式的話,就沒有這個問題。:

int s

int d;

d=dup(s);

shutdown(s,shut_rdwr);

即使套介面s仍然通過檔案描述符d開啟,shutdown函式仍然立即將套介面徹底關閉。

建議:總是使用shutdown函式來代替close函式。

當呼叫shutdown函式的時候,如果給定的套介面不是有效的檔案描述符,返回ebadf錯誤。

如果給定的檔案描述符不是套介面,返回enotsock錯誤

如果套介面出於非連線狀態,返回enotconn錯誤。

注意:即便是使用引數為shut_rdwr的時候,函式shutdown也不會釋放檔案描述符,在使用close釋放檔案描述符之前,他一直可用。

Linux Socket學習 域和套介面簡介

套介面建立後,就如同乙個檔案描述符,我們可以使用同樣的io函式進行讀寫,關閉操作。其實,和引用乙個已經開啟的檔案一樣,套介面也是通過檔案描述符來引用的,而且兩者的檔案描述符共享乙個 數字空間 比如說不能既開啟乙個檔案描述符為4的套介面,又開啟乙個檔案描述符為4的檔案。套介面和已經開啟的檔案的區別 1...

Linux socket 傳輸和接受結構體

linux程式設計 linux socket send and recevie structure 最近在開發乙個linux下的聊天軟體,好久沒有做c語言的開發了,感覺到很多東西已經生疏了,這下又碰到用socket傳遞結構體的問題,google了一下,發現也有不少朋友遇到同樣的問題,所以就打算寫出自...

Linux Socket學習 為套介面繫結位址

當我們使用socket函式建立乙個套介面之後,這個套介面就處於無名狀態,雖然之前我們提到即使沒有位址,套介面也能使用,但是這個只限於套介面對在同乙個linux核心中,如果位於兩台不同的主機的套介面需要連線,而又沒有位址,那麼就無法工作。函式bind的作用就是為無名套介面分配位址,語法如下 inclu...