Linux網路程式設計之select伺服器

2021-08-03 04:02:51 字數 2454 閱讀 3841

一、關於i/o       

一次i/o分兩個部分(①等待資料就緒 ②進行i/o),減少等的比重,增加i/o的比重就可以達到高效伺服器的目的。select工作原理就是這個,同時監控多個檔案描述符(或者說檔案控制代碼),一旦其中某乙個進入就緒狀態,就進行i/o操作。監控多個檔案控制代碼可以達到提高就緒狀態出現的概率,就可以使cpu在大多數時間下都處於忙碌狀態,大大提高cpu的效能。達到高效伺服器的目的。

可以理解為select輪詢監控多個檔案控制代碼或套接字。

二、關於select函式

fd_set是檔案描述符集,本身是一種位圖結構,下面的巨集提供了對這個檔案描述符集的操作:

三、關於select模型

對於檔案描述符集合fd_set,fd_set中的每乙個位元位都對於乙個檔案描述符fd,假設fd_set長度為一位元組,則:

1)執行fd_set set,fd_zero(&set);則set用位表示為0000,0000;

2)fd = 5時,執行fd_set(fd, &set);此時set位表示為0001,0000;

3)再加入fd = 2,fd = 1,set位表示為0001,0011;

4)執行select(6,&set,0, 0 , 0)阻塞等待;

5)fd = 1和fd = 2上都發生可讀事件,select返回,此時set變為0000,0011(沒有事件發生的fd=5被清空)

從上面可以看出select模型的特點:

(1)可監控的檔案描述符的個數由sizeof(fd_set)決定,(我用的centos6.5虛擬機器上為1024)

(2)將fd加入select監控集的同時,需要用乙個array來儲存這些檔案描述符,一是用於select返回後,array作為源資料和fd_set進行fd_isset判斷,二是select返回後會把之前加入的但並無事件發生的檔案描述符清空,則每次開始select之前都要從array中取得fd再加入,掃瞄array時取得fd最大值maxfd作為select的第乙個引數

(3)每次select之前都要迴圈array(加fd,取maxfd),select返回之後還要再迴圈array(進行fd_isset判斷)

這樣也就可以看出select模型的缺陷:

1、每次進行select都要把檔案描述符集fd由使用者態拷貝到核心態,這樣的開銷會很大。 

2、實現select伺服器,內部要不斷對檔案描述符集fd進行迴圈遍歷,當fd很多時,開銷也很大,實現也較為複雜 

3、select能監控檔案描述符的數量有限。

四、實現select伺服器

為了實現簡單,我這裡只考慮了讀檔案描述符:

select_server.c:

#include #include #include #include #include #include #include #include int fds_array_read[sizeof(fd_set)*8];

//int fds_array_write[sizeof(fd_set)*8];

int startup(const char* _ip, int _port)

//int opt = 1;

//setsockopt(sock, sol_socket, so_reuseaddr, &opt, sizeof(opt));

struct sockaddr_in local;

local.sin_family = af_inet;

local.sin_port = htons(_port);

local.sin_addr.s_addr = inet_addr(_ip);

if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)

if(listen(sock, 10) < 0)

return sock;

}static void usage(const char* proc)

int main(int argc, char* argv)

int listen_sock = startup(argv[1], atoi(argv[2]));

int i = 0;

int nums = sizeof(fds_array_read)/sizeof(fds_array_read[0]);

for(; i0)

else if(s == 0)

else}}

}}} }}

執行結果:

(使用telnet命令遠端登入本地環迴實現通訊)

linux 網路程式設計 三 非阻塞通訊select

int select int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout 說明 int maxfdp是乙個整數值,是指集合中所有檔案描述符的範圍,即所有檔案描述符的最大值加1。fd set r...

linux 網路程式設計 三 非阻塞通訊select

int select int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout 說明 int maxfdp是乙個整數值,是指集合中所有檔案描述符的範圍,即所有檔案描述符的最大值加1。fd set r...

Linux網路程式設計之廣播

1.概念 前面介紹的tcp,udp都是單播方式,即一對一.而廣播是一台主機向區域網內的所有主機傳送資料。這時,同一網段的所有主機都能接收到資料。傳送廣播包的步驟大致如下 1 確定乙個傳送廣播的介面,如eth0 2 確定廣播的位址,通過ioctl函式,請求碼設定為siocgifbrdaddr得到廣播的...