select伺服器的實現

2021-08-04 17:14:40 字數 3098 閱讀 8643

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寫程式,他們只是習慣...