下面的巨集提供了處理fd_set的這三種描述集的方式:
fd_clr(inr fd,fd_set* set);用來清除描述片語set中相關fd 的位;
fd_isset(int fd,fd_set *set);用來測試描述片語set中相關fd 的位是否為真;
fd_set(int fd,fd_set*set);用來設定描述片語set中相關fd的位;
fd_zero(fd_set *set);用來清除描述片語set的全部位;
函式返回值:
1、成功:檔案描述詞狀態已改變的個數;
2、0:在描述詞狀態改變前已超過timeout時間,沒有返回;
3、-1:有錯誤發生,錯誤原因存於errno;
select模型的特點:
1、可監控的檔案描述符個數取決於sizeof(fd_set)的值;
2、將fd加入select監控集的同時,還要再使用乙個資料結構array儲存放到select監控集中的fd,一:是用於在select 返回後,array作為源資料和fd_set進行fd_isset判斷是否有事件發生;二:是select返回後會把以前加入的但並無事件發生的fd清空,則每次開始 select前都要重新從array取得fd逐一加入(fd_zero最先),掃瞄array的同時取得fd最大maxfd,給其+1用於select的第乙個引數。
select模型的缺點:
1、每次呼叫select,都需要把fd集合從使用者態拷貝到核心態,這個開銷在fd很多時會很大;
2、每次呼叫select都需要在核心遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大;
3、select支援的檔案描述符數量太少了,預設是1024。
使用select實現乙個tcp伺服器:
//server端:
#include
#include
#include
#include
#include
#include
#include
int array_rfds[1024];
static
void usage(const
char* proc)
int startup(const
char* _ip,int _port)
int flag = 1;
setsockopt(sock,sol_socket,so_reuseaddr,&flag,sizeof(flag));
struct sockaddr_in server;
server.sin_family = af_inet;
server.sin_port= htons(_port);
server.sin_addr.s_addr = inet_addr(_ip);
if(bind(sock,(struct sockaddr*)&server,sizeof(server))<0)
if(listen(sock,10)<0)
return sock;
}int main(int argc,const
char* argv)
int listen_sock = startup(argv[1],atoi(argv[2]));
fd_set rfds;
int maxfd = 0;
int array_rsize = sizeof(array_rfds)/sizeof(array_rfds[0]);
array_rfds[0] = listen_sock;
int i = 1;
for(;i1;
}while(1)
;fd_zero(&rfds);
maxfd = -1;
for(i=0;iif(array_rfds[i]>0)
}switch(select(maxfd+1,&rfds,null,null,/*&timeout*/null))
printf("new client--> %s:%d\n",\
inet_ntoa(client.sin_addr),\
ntohs(client.sin_port));
int k= 1;
for(;kif(array_rfds[k]<0)
}if(k == array_rsize)
}else
if(j!=0 && fd_isset(array_rfds[j],&rfds))
else
if(s ==0)
else}}
}break;}}
return
0;}
//client端:
I O多路轉接之select
什麼是i o多路轉接技術 先構建一張有關描述符的列表,然後呼叫乙個函式,直到這些描述符中的乙個已準備好進行i o時,該函式才返回,在返回時,他告訴程序哪些描述符已準備好可以進行i o。上述呼叫的函式,有select,poll,pselect及poll的增強版epoll等,本文主要介紹select。函...
IO多路轉接之select
系統提供select函式來實現多路轉接。呼叫select函式介面的特點 一次需要等待多個檔案描述符。select函式原型 include include include int select int nfds,fd set readfds,fd set writefds,fd set exceptf...
IO多路轉接之select
阻塞io,在核心將資料準備好之前,系統會一直在等待,所有的套接字,預設都是阻塞方式 非阻塞io 如果核心還沒有將資料準備好,系統會呼叫仍然直接返回,並且返回ewouldblock錯誤碼,非阻塞io需要程式設計師迴圈的方式反覆嘗試讀寫檔案描述符,看資料是否準備好,這個過程稱為輪詢,這對cpu來說是很大...