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伺服器既要處...