6 12多路IO轉接伺服器之select

2021-10-06 04:37:15 字數 3067 閱讀 9431

title

date

comments

categories

br#多路i/o轉接伺服器之select

2020/3/18

true

linux

linux

伺服器

6.12

多路i/o轉接伺服器也叫多工io伺服器或者i/o多路復用技術。該類伺服器實現的主旨思想是,不再由應用程式自己監聽客戶端的連線請求,取而代之的是由核心替應用程式監聽,核心一旦發現程序指定的乙個或者多個io條件滿足,它就通知該程序進行處理。與多程序和多執行緒技術相比,i/o多路復用技術的最大優勢是系統開銷小,系統不必建立程序/執行緒,也不必維護這些程序/執行緒,從而大大減小了系統的開銷。

1、select能監聽的檔案描述符個受限於fd_setsize,一般為1024,單純改變程序開啟檔案描述符個數,並不能改變select監聽的個數。 2、解決1024個以下客戶端時候非常適合使用select,但是如何連線客戶端數量過多,select採用的輪詢機制,會大大降低伺服器的響應效率。

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

#include #include int select(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均將被測試。

因為檔案描述符是從0開始的。

(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。

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

服務端實現程式的功能是:客戶端向伺服器傳送資訊,伺服器接收並小寫轉大寫後傳送給客戶端,客戶端顯示出接收到的資訊。

服務端程式如下:

#include #include #include #include #include #include "wrap.h"

#define maxline 80

#define serv_port 6666

/* 函式說明

int select(int nfds, fd_set *readfds, fd_set *writefds,

fd_set *exceptfds, struct timeval *timeout);

nfds: 監控的檔案描述符集裡最大檔案描述符加1,因為此引數會告訴核心檢測前多少個檔案描述符的狀態

readfds: 監控有讀資料到達檔案描述符集合,傳入傳出引數

writefds: 監控寫資料到達檔案描述符集合,傳入傳出引數

exceptfds: 監控異常發生達檔案描述符集合,如帶外資料到達異常,傳入傳出引數

timeout: 定時阻塞監控時間,3種情況

1.null,永遠等下去

2.設定timeval,等待固定時間

3.設定timeval裡時間均為0,檢查描述字後立即返回,輪詢

struct timeval ;

void fd_clr(int fd, fd_set *set); //把檔案描述符集合裡fd清0

int fd_isset(int fd, fd_set *set); //測試檔案描述符集合裡fd是否置1

void fd_set(int fd, fd_set *set); //把檔案描述符集合裡fd位置1

void fd_zero(fd_set *set); //把檔案描述符集合裡所有位清0

*/int main(int argc, char *ar**)

}/* 達到select能監控的檔案個數上限 1024 */

if (i == fd_setsize)

fd_set(connfd, &allset); /* 新增乙個新的檔案描述符到監控訊號集裡 */

if (connfd > maxfd)

maxfd = connfd; /* select第乙個引數需要 */

if (i > maxi)

maxi = i; /* 更新client最大下標值 */

if (--nready == 0)

continue; /* 如果沒有更多的就緒檔案描述符繼續回到上面select阻塞監聽,

負責處理未處理完的就緒檔案描述符 */

}for (i = 0; i <= maxi; i++) else

if (--nready == 0)

break;}}

}close(listenfd);

return 0;

}

I O多路轉接之poll伺服器

函式說明 include int poll struct pollfd fds,nfds t nfds,int timeout 引數說明 fds 是乙個struct pollfd結構型別的陣列,用於存放需要檢測其狀態的socket描述符 每當呼叫這個函式之後,系統不會清空這個陣列,操作起來比較方便 ...

I O多路轉接 epoll伺服器

在前面的兩篇部落格中,我們介紹了最早期的select和改進版的poll 但是,他兩都沒有改進的就是,想要快速知道事件就緒並沒有得到改進,兩個全部是遍歷陣列,我們都知道它的時間複雜度就是o n 效率不是很高,時間複雜度達到o 1 才是高效的 epoll是linux特有的i o復用函式,它在實現和使用上...

linux 多路IO轉接伺服器之select

多路io轉接伺服器也叫做多工io伺服器。該類伺服器實現的主旨思想是,不再由應用程式自己監視客戶端連線,取而代之由核心替應用程式監視檔案。1.select能監聽的檔案描述符個數受限於fd setsize,一般為1024,單純改變程序開啟的檔案描述符個數並不能改變select監聽檔案個數 2.解決102...