select函式是來實現多路i/o復用輸入/輸出模型。比純粹的阻塞i / o模型更具有實用性,因為程式控制程式碼會停在select這裡等待,直到被監視的檔案控制代碼至少有乙個發生了狀態改變。
select函式的功能和呼叫順序
使用select函式時可以將多個檔案描述符集中到一起統一監視,專案如下:
1、是否存在套接字接受資料?
2、無需阻塞傳輸資料的套接字有那些?
3、那些套接字發生了異常?
select的函式呼叫方法和順序如下:
測試**
server:
// i/o多路轉接之select實現
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define size sizeof(fd_set)*8 //定義fds大小
int fds[size];
int startup(const
char *ip,int port)
struct sockaddr_in local; //本地位址資訊結構體
local.sin_family = af_inet; //使用ipv4進行通訊
local.sin_port = htons(port);//獲取埠
local.sin_addr.s_addr = inet_addr(ip);//獲取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 nums = sizeof(fds)/sizeof(fds[0]);
int i=0;
for(;i1;
}fds[0]=listen_sock;
while(1)
; //設定為 非阻塞狀態
switch(select(max_fd+1,&rfds,null,null,&timeout))// 呼叫select函式
if(i==0&&fd_isset(listen_sock,&rfds)) //檢測是否有新的請求
printf("get a new client:[%s:%d]\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
int j=1;
//將新的客戶端加入陣列
for(;jif(fds[j]==-1)
}if(j==nums)
else
}else
if(i!=0&&fd_isset(fds[i],&rfds))
else
if (s==0)
else
}else }}
break;}}
return
0;}
client:
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const
char *argv)
; int n = 0;
int len = sizeof(struct sockaddr_in);
if(argc != 3) // ./a.out ip port
//1.建立用於通訊的檔案描述符
sockfd = socket(af_inet,sock_stream,0);
if(sockfd < 0)
//2.填充伺服器ip和port
server_addr.sin_family = af_inet;
server_addr.sin_port = htons(atoi(argv[2])); //port
server_addr.sin_addr.s_addr = inet_addr(argv[1]); //ip
//3.向伺服器發起連線請求
if(connect(sockfd,(struct sockaddr *)&server_addr,len) < 0)
//4.傳送訊息
while(1)
if(strncmp(buf,"quit",4) == 0)
break;
printf("send %d bytes : %s\n",n,buf);
}return
0;}
測試結果
select伺服器優缺點
優點(1)select()的可移植性更好;
(2)select()對於超時值提供了更好的精度。
(3)不需要建立多個執行緒、程序就可以實現一對多的通訊。
(4)可以同時等待多個檔案描述符,效率比起多程序多執行緒來說要高很多。
缺點(1)每次呼叫選擇,都需要把fd集合從使用者態拷貝到核心態,這個開銷在fd很多時會很大 ;
(2)同時每次呼叫選擇都需要在核心遍歷傳遞進來的所有的fd,這個開銷在fd很多時也很大 ;
(3)select支援的檔案描述符數量有上限,預設是1024。
Select實現併發伺服器
併發伺服器除了可以用多執行緒和多程序實現以外,還可以用select實現單執行緒併發,下面用select實現簡單的示例,伺服器接收客戶端的連線,並將客戶發的訊息返回,如下 伺服器端 main.c include include include include include include inclu...
伺服器select與gevent
select版 tcp伺服器 1.select 原理 在多路復用的模型中,比較常用的有select模型和epoll模型。這兩個都是系統介面,由作業系統提供。當然,python的select模組進行了更高階的封裝。將需要判斷有資料傳來的 可讀的 socket 可以向外傳送資料的 可寫的 socket及...
併發伺服器 select 程式設計
1,併發伺服器,通過多路io復用,能使得乙個程序同時處理多路io,提公升伺服器吞吐量。在linux支援epoll模型之前,都使用select poll模型來實現io多路復用。select在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太愛用select寫程式,他們只是習慣...