基於select模型的udp客戶端實現超時機制

2021-07-22 21:53:58 字數 3064 閱讀 5226

參考:

多路選擇i/o — select模型

其思想在於使用乙個集合,該集合中包含需要進行讀寫的fd,通過輪詢這個集合,直到有乙個fd可讀寫,才返回。與阻塞i/o不同的是,阻塞i/o僅使用了一次系統呼叫,就是對fd的讀寫,如果沒有fd處於就緒狀態,則程序一直阻塞,而多路選擇i/o使用了兩次系統呼叫,第一次是輪詢並返回可讀寫fd數,第二次是對fd進行讀寫,阻塞只發生在輪詢fd的過程。

select函式的原型(sys/select.h)

1 int select (int __nfds, fd_set *__restrict __readfds,

2 fd_set *__restrict __writefds,

3 fd_set *__restrict __exceptfds,

4 struct timeval *__restrict __timeout);

(1)__nfds

需輪詢的最大檔案描述符數。如__nfds = 10,則輪詢值為0~9的fd,單個程序中,最多可開啟1024個fd,該值在sys/select.h中的fd_setsize定義。使用者可通過「ulimit -n」檢視該值,通過列印/proc/sys/fs/file-max中的值檢視系統可開啟的最大fd數。

分別代表使用者關心的可讀、可寫、異常的fd,這三個引數的資料型別是fd_set *,這是一組檔案描述符的集合,使用乙個位來代表乙個fd。

fd_set位向量操作函式包括

1 #define fd_set(fd, fdsetp)   __fd_set (fd, fdsetp)   //將指定的fd置1

2 #define fd_clr(fd, fdsetp) __fd_clr (fd, fdsetp) //將指定的fd清0

3 #define fd_isset(fd, fdsetp) __fd_isset (fd, fdsetp) //測試fd狀態,如被置1,返回非0,否則返回0

4 #define fd_zero(fdsetp) __fd_zero (fdsetp) //將所有的fd清0

(3)__timeout

timeout的資料型別是timeval結構體。通過填充該結構體,設定超時時間,精確到微妙級,如果該引數設定為null,則一直等待,直到有fd可讀寫。如果tv_sec和tv_usec都設定為0,則輪詢完指定fd後,立即返回。

1 struct timeval

2 ;

(4)select有三種返回值

-1  :出錯

0   :如果設定了超時,在指定時間內沒有fd可讀寫,則返回0,可在此指定相應的超時處理操作。

>0 :返回可讀寫的fd數

可遮蔽訊號的select — pselect

從原型上看,pselect函式與select函式的區別在於設定超時的結構體不同,以及多了個用於遮蔽訊號的引數。如果__sigmask設定為null,則與select一樣。

1 int pselect (int __nfds, fd_set *__restrict __readfds,

2 fd_set *__restrict __writefds,

3 fd_set *__restrict __exceptfds,

4 const struct timespec *__restrict __timeout,

5 const __sigset_t *__restrict __sigmask);

(1)timespec結構體的定義如下,它精確到納秒級。

1 struct timespec

2 ;

(2)__sigmask實際上是訊號的位向量。資料型別是sigset_t,定義如下

1

/*a `sigset_t' has a bit for each signal. */2

3 # define _sigset_nwords (1024 / (8 * sizeof (unsigned long

int)))

4 typedef struct

5 __sigset_t;

測試**:

//

client

#include #include

#pragma comment (lib,"ws2_32.lib")

#define max_line 80

#define port 8000typedef

intsocklen_t;

int main(int argc, char *argv)

addr_len = sizeof

(cin);

while (1

)

else

return0;}}

break

; }

}return0;

}

//server

#pragma comment (lib,"ws2_32.lib")#include

#include

#define max_line 80

#define port 8000

int main(int argc, char *argv)

n = bind(sockfd, (struct sockaddr*)&sin, sizeof

(sin));

if (n < 0

)

while (1

) }

測試:鏈結失敗。。。

基於select模型的server

前面一篇介紹了io模型。其中重點介紹了io多路轉接中的三種模型,包括了select,poll,epoll三種。下面就是基於select模型編寫的伺服器與客戶機,兩者可以進行互動。伺服器端 k include include include include include include includ...

基於Select模型的UDP TCP混合程式設計

selecttestserver.cpp 定義控制台應用程式的入口點。tcp udp復用server select非阻塞模式 ip 127.0.0.1 tcp port 5001 udp port 5000 include stdafx.h include pragma comment lib,ws...

UDP併發伺服器模型 二 select機制

上篇文章說了下 udp 併發模型。然後筆者也自己編寫了一套 基本上能顯示 udp 併發機制。大致原理參考 select機制能很好地提供多路io功能。對於本套 已基本上能提供類似 select 的功能主要函式介面 void listen head init struct list head head ...