I O復用 select函式實現併發伺服器

2021-08-19 22:11:06 字數 2997 閱讀 7036

多程序伺服器端模型:(乙個程序對應乙個客戶端)

在模型中引入復用技術,減少程序數。無論連線多少客戶端,提供服務的程序只有1個。

select函式呼叫過程:

利用select函式可以同時監視多個檔案描述符。監視檔案描述符可以視為監視套接字。

將要監視的檔案描述符集中到一起。集中時也要按照監視項(接收,傳輸,異常)進行區分,將3種監視項分為3類

使用fd_set陣列變數執行此項操作,陣列是存有0和1的位陣列。

位設定為1表示該檔案描述符是監視物件。

在fd_set變數中註冊或更改值的操作都由下列巨集完成:

fd_isset用於驗證select函式的呼叫結果

select函式驗證3種監視項的變化情況。根據監視項宣告3個fd_set型變數,分別向其註冊檔案描述符資訊,並把變數的位址值傳遞到上述函式的第二到第四個引數。

檔案描述符的監視範圍是?

答:檔案描述符的監視範圍與select函式的第乙個引數有關。sekect函式要求通過第乙個引數傳遞監視物件  檔案描述符的物件。

如何設定select函式的超時時間?

答:select函式的超時時間與select函式的最後乙個引數有關。其中timeval結構體定義如下:

struct timeval

呼叫select函式時,除發生變化的檔案描述符對應位外,剩下的所有位將初始化為0。因此,只要呼叫select函式後,值仍為1的位置上的檔案描述符發生了變化。

select函式返回大於0的整數,說明相應數量的檔案描述符發生變化。

/* select函式呼叫示例 */

#include#include#include#include#define buf_size 30

int main(int argc, char *argv)

else if(result == 0)

else //檔案描述符發生了變化

}} return 0;

}

執行結果:

設定的超時時間為5秒,若5秒標準輸入沒有變化,則超時。

示例:基於i/o復用的回聲伺服器端

#include#include#include#include#include#include#include#include#define buf_size 100

void error_handling(char *message);

int main(int argc, char *argv)

serv_sock = socket(pf_inet,sock_stream,0); //serv_sock檔案描述符的值為3

memset(&serv_adr,0,sizeof(serv_adr));

serv_adr.sin_family = af_inet;

serv_adr.sin_addr.s_addr = htonl(inaddr_any);

serv_adr.sin_port = htons(atoi(argv[1]));

if (bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1)

error_handling("bind() error!");

if (listen(serv_sock,5) == -1)

error_handling("listen() error!");

fd_zero(&reads);

fd_set(serv_sock, &reads); //註冊伺服器端套接字資訊。接收資料情況的監視物件就包含了伺服器套接字

fd_max = serv_sock;

while(1)

else //read message

else }}

} }close(serv_sock);

return 0;

}void error_handling(char *message)

執行結果:

客戶端1:

客戶端2:

......................(可以連多個客戶端,併發伺服器)

伺服器端:

伺服器端輸出的數字從4開始,因為此程式中:

標準輸入-----------0;

標準輸出-----------1;

標準錯誤-----------2;

serv_sock---------3;

與客戶端連線的套接字描述符的值是從4開始,依次遞增。

select實現I O復用

select 系統提供select函式來實現多路復用輸入 輸出模型。select系統呼叫是用來讓我們的程式監視多個檔案控制代碼的狀態變化的。程式會停在select這裡等待,直到被監視的檔案控制代碼有乙個或 多個發生了狀態改變。關於檔案控制代碼,其實就是乙個整數,我們最熟悉的控制代碼是0 1 2三 個...

I O復用 select 學習

最近在學習網路程式設計,覺得select這塊的知識點確實比較難以理解,在學習socket網路通訊機制時,只是習慣寫諸如connect accept recv或recvfrom這樣的阻塞程式,所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果事件沒有發生,...

I O復用 select和poll函式 一

我們看到上面的tcp客戶同時處理兩個輸入 標準輸入和tcp套接字。我們遇到的問題就是在客戶阻塞於 標準輸入上的 fgets呼叫期間,伺服器程序會被殺死。伺服器tcp雖然正確地給客戶tcp傳送乙個fin,但是既然客戶程序阻塞於從標準輸入讀入的過程,它將看不到這個rof,知道從套接字讀時為止 可能已經過...