select函式詳解及其在I O復用模型中的應用

2021-08-03 13:19:57 字數 2498 閱讀 3019

一.select函式詳解

#include

#include

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *excptset, const strcut timeval *timeout)

返回:准有就緒的檔案描述數量,若超時則返回0,否者返回-1

針對select中最後乙個時間引數情況如下

struct timeval;
1.timeout = null

表示將會一直等待下去,並且堵塞。也有可能系統捕獲到了異常訊號,強制返回-1.

2.time->tv_sec != 0 && timeout->tv_usec != 0

timeout作為計時器,進行倒計時,如果超時了那麼,select函式就會返回0。也有可能系統捕獲到了異常訊號,強制返回-1.

3.time->tv_sec == 0 && timeout->tv_usec == 0

將會以輪訓的方式等待下,還沒有準備就緒的描述符。

針對select返回值詳細分析1.負值

系統捕捉到訊號,進入相應的訊號處理函式。

2.0等待超時

3.正值

表示有多少個描述符號準備就緒

fd_set的巨集操作函式

fd_zero(fd_set *fdset)//clear all bit in fdset

fd_set(int fd, fd_set *fdset)//turn on the bit for fd on fdset

fd_isset(int fd, fd_set *fdset)// is on the bit for fd on fdset ?

fd_clr(int fd, fd_set *fd_set)//turn offthe bit for fd on fdset

在sys/select函式中規定,fd_setsize的值表示描述符總數,一般值預設為1024。但是在不同64位中的值可能不同。

二.select函式的應用

針對客服端一方,我們設計了乙個select在批量輸入中的乙個模型。但是該明顯存在乙個大量的陷阱,如下分析所示

#include "unp"

void doclient_echo(file *fp, int sockfd)

if(fd_isset(sockfd, &rset))}}

在cilent的傳送速度和server相同的情況下,當在client通過迴圈傳送8個請求給server後,當打算傳送第九個請求的時候fgets函式讀取到了eof,

這個時候返回空指標,這個時候函式返回。但是client的接受端並沒有完全接受到來之server處理完的資訊函式就返回了,這樣就會造成資料的丟失。

因為雖然我們完成了從套接字的讀入,但是請求可能還在前往去伺服器的路上,或者是請求對應的處理訊息還在從伺服器到客服端的路上。

針對上訴的描述問題我們給出了如下的解決方案。

#include "unp"

#define maxline 4096

void doclient_echo(file *fp, int sockfd)

}write(stdout_fileno, recvbuf, n);

}if(stdineof == 0 && fd_isset(fileno(fp), &rset))

write(sockfd, sendbuf, n);}}

}

根據要求只有當請求傳送完畢後,然後client接收了處理的全部要求,然後才能返回函式。但是根據tcp|ip四次握手的原則,所有的請求傳送完畢後,通過呼叫shutdown函式半關閉套接字寫入埠,最後乙個資訊就是有cilent傳送乙個fin單位元組,促使server被動關閉套接字,進入tcp|ip四次揮手過程。(該過程不在詳述,請參考待定)

1.stdineof = 0,表示fp檔案指標還可以繼續讀取,請求。當fp檔案讀取完成後,readline函式返回eof表示請求讀取完畢,這個時候通過呼叫shutdown函式半關閉套接字寫入埠,然後將該檔案fp對應的檔案描述符號,從rset描述符集合中除去。

2.目前等待一直從套接字描述符號中讀取對應的請求的處理,並且答應出來,當讀寫出來的資料為「處理n」的時候表示是對「請求n」的處理結果,在sockfd讀取結果為0的時候,表示收到的連線為ack,如果stdineof = 1,那麼該ack很有可能就是由自己傳送的fin結束請求的應答,以此來表示結束函式。

select詳解及其限制

前言 筆者前幾天參加面試,被問到select 函式的限制,然後感覺一頭霧水,回來之後趕緊查詢了資料彌補知識短板,也意識到以後使用一些系統呼叫應該多想些為什麼,結合現實去思考實際中會遇到的問題。下面是對selecth 函式的一些總結 select是網路 io模型中的 io復用 在之前筆者還以為 sel...

select 函式及其應用

select 函式用於在非阻塞中,當乙個套接字或一組套接字有訊號時通知你,系統提供select函式來實現多路復用輸入 輸出模型,所在的標頭檔案為 include和 include原型 int select int maxfd,fd set rdset,fd set wrset,fd set exse...

select函式詳解

select的機制中提供了乙個fd set的資料結構,實際上是long型別的陣列,每乙個陣列元素都能與一開啟的檔案控制代碼 不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼 建立聯絡,建立聯絡的工作由程式設計師完成,當呼叫select 時,由核心根據io狀態修改fd set的內容,由...