IO多路復用之select總結

2021-07-02 01:21:46 字數 3798 閱讀 4617

io

多路復用是指核心一旦發現程序指定的乙個或者多個io條件準備讀取,它就通知該程序。io多路復用適用如下場合:

(1)當客戶處理多個描述字時(一般是互動式輸入和網路套介面),必須使用i/o復用。

(2)當乙個客戶同時處理多個套介面時,而這種情況是可能的,但很少出現。

(3)如果乙個tcp伺服器既要處理監聽套介面,又要處理已連線套介面,一般也要用到i/o復用。

(4)如果乙個伺服器即要處理tcp,又要處理udp,一般要使用i/o復用。

(5)如果乙個伺服器要處理多個服務或多個協議,一般要使用i/o復用。

與多程序和多執行緒技術相比,

i/o多路復用技術的最大優勢是系統開銷小,系統不必建立程序

/執行緒,也不必維護這些程序

/執行緒,從而大大減小了系統的開銷。

該函式准許程序指示核心等待多個事件中的任何乙個傳送,並只在有乙個或多個事件發生或經歷一段指定的時間後才喚醒。函式原型如下:

#include select.h>

#include time.h>

intselect(int maxfdp1,

fd_set *readset,

fd_set *writeset,

fd_set *exceptset,

const

struct timeval *timeout)

返回值:就緒描述符的數目,超時返回0,出錯返回-1

函式引數介紹如下:

(1)第乙個引數maxfdp1指定待測試的描述字個數,它的值是待測試的最大描述字加1(因此把該引數命名為maxfdp1),描述字0、1、2...maxfdp1-1均將被測試。

(2)中間的三個引數readset、writeset和exceptset指定我們要讓核心測試異常條件的描述字。如果對某乙個的條件不感興趣,就可以把它設為空指標。struct fd_set可以理解為乙個集合,這個集合中存放的是檔案描述符,可通過以下四個巨集進行設定:

void fd_zero(fd_set*fdset);           //清空集合

void fd_set(int fd, fd_set *fdset);   //將檔案描述符加入集合之中

void fd_clr(int fd, fd_set *fdset);   //將檔案描述符從集合中刪除

int fd_isset(int fd, fd_set *fdset);   // 檢查指定檔案描述符是否可以讀寫 

(3)timeout告知核心等待所指定描述字中的任何乙個就緒可花多少時間。其timeval結構用於指定這段時間的秒數和微秒數。

struct timeval;

這個引數有三種可能:

(1)永遠等待下去:僅在有乙個描述字準備好i/o時才返回。為此,把該引數設定為空指標null

(2)等待一段固定時間:在有乙個描述字準備好i/o時返回,但是不超過由該引數所指向的timeval結構中指定的秒數和微秒數

(3)根本不等待:檢查描述字後立即返回,這稱為輪詢。為此,該引數必須指向乙個timeval結構,而且其中的定時器值必須為0

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ipaddress   "192.168.1.3"//環迴

#define port        2015

#define maxline     1024

#define listenq     5 

static int socket_bind(const char* ip,int port);//建立套接字並進行繫結

static void do_select(int listenfd);                     //io多路復用select

static void handle_connection(int *connfds, int num, fd_set *prset, fd_set *pallset); //處理多個連線

//主程式

int 

main(int argc,char *argv)

//監聽套接字

static int 

socket_bind(const char* ip,int port)

//初始化位址結構

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family = af_inet;               //ipv4

servaddr.sin_port = htons(port);             //埠

servaddr.sin_addr.s_addr = htonl(inaddr_any);//由核心指定ip

//inet_pton(af_inet, ip, &servaddr.sin_addr);//ip位址

//套接字與位址結構繫結

if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)

return listenfd;

}//監控多路網路鏈結

static void do_select(int listenfd)

//測試監聽描述符是否準備好

if (fd_isset(listenfd, &rset))

}char buff[16] = ;

printf("connection from %s, port %d\n",

inet_ntop(af_inet, &cliaddr.sin_addr, buff, sizeof(buff)),

ntohs(cliaddr.sin_port));

//將新的連線描述符新增到陣列中

for (i = 0; i

}//上限檢查

if (i == fd_setsize)

//將新的描述符新增到讀描述符集合中

fd_set(connfd, &allset);                  

maxfd = (connfd > maxfd ? connfd : maxfd);//描述符個數

maxi = (i > maxi ? i : maxi);             //記錄客戶連線套接字的個數

if (--nready <= 0)

continue;

}//處理客戶連線(業務處理)

handle_connection(clientfds, maxi, &rset, &allset);}}

//業務處理

static void 

handle_connection(int *connfds, int num, fd_set *prset, fd_set *pallset)

printf("read msg is: ");

write(stdout_fileno, buf, n);

//向客戶端傳送buf

write(connfds[i], buf, n);}}

}

IO多路復用之select總結

1 基本概念 io多路復用是指核心一旦發現程序指定的乙個或者多個io條件準備讀取,它就通知該程序。io多路復用適用如下場合 1 當客戶處理多個描述字時 一般是互動式輸入和網路套介面 必須使用i o復用。2 當乙個客戶同時處理多個套介面時,而這種情況是可能的,但很少出現。3 如果乙個tcp伺服器既要處...

IO多路復用之select總結

io多路復用是指核心一旦發現程序指定的乙個或者多個io條件準備讀取,它就通知該程序。io多路復用適用如下場合 1 當客戶處理多個描述字時 一般是互動式輸入和網路套介面 必須使用i o復用。2 當乙個客戶同時處理多個套介面時,而這種情況是可能的,但很少出現。3 如果乙個tcp伺服器既要處理監聽套介面,...

I O多路復用之select總結

1 基本概念 io多路復用是指核心一旦發現程序指定的乙個或者多個io條件準備讀取,它就通知該程序。io多路復用適用如下場合 1 當客戶處理多個描述字時 一般是互動式輸入和網路套介面 必須使用i o復用。2 當乙個客戶同時處理多個套介面時,而這種情況是可能的,但很少出現。3 如果乙個tcp伺服器既要處...