TCP IP程式設計基礎 超時 多路復用 非阻塞

2021-04-29 03:48:26 字數 1664 閱讀 4175

在tcp連線中,recv等函式預設為阻塞模式(block),即直到有資料到來之前函式不會返回,而我們有時則需要一種超時機制使其在一定時間後返回而不管是否有資料到來,這裡我們就會用到setsockopt()函式:

int  setsockopt(int  s, int level, int optname, void* optval, socklen_t* optlen);

這裡我們要涉及到乙個結構:

struct timeval

;這裡第乙個域的單位為秒,第二個域的單位為微秒。

struct timeval tv_out;

tv_out.tv_sec = 1;

tv_out.tv_usec = 0;

填充這個結構後,我們就可以以如下的方式呼叫這個函式:

setsockopt(fd, sol_socket, so_rcvtimeo, &tv_out, sizeof(tv_out));(具體引數可以man一下,或檢視msdn)

這樣我們就設定了recv()函式的超時機制,當超過tv_out設定的時間而沒有資料到來時recv()就會返回0值。

第二個我們要介紹的是多路復用機制,也就是同時監聽多個套接字連線。

int select(int n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);

這裡涉及到了fd_set結構:

typedef struct fd_set

fd_count為fd_set結構中包含的套接字個數,fd_array唯一個int 陣列,包含了我們要監聽的套接字。

首先我們需要使用fd_set將我們要監聽的套接字新增到fd_set結構中:

fd_set readfd;

fd_set(fd, &readfd);

然後我們這樣呼叫select函式:

select(max_fd + 1, &readfd, null, null, null);(具體引數可以man一下,或檢視msdn)

fd_isset(fd, &readfd);

其中max_fd為我們要監聽的套接字中值最大的乙個,同時在呼叫select是要將其加1,readfd即為我們監聽的要進行讀操作的套接字連線,第三個引數是我們監聽的要進行寫操作的套接字連線,第四個引數用於異常,而最後乙個引數可以用來設定超時,這裡同樣使用了struct timeval結構,可以實現與前面介紹的同樣的效果。這裡如果連線進來的話select即返回乙個大於零的值,然後我們呼叫fd_isset巨集來檢測具體是那乙個套接字有資料進來(fd_isset返回非零值)。

最後介紹的是另一種實現非阻塞的方法,這種方法在有些應用中會起到一定作用,尤其是在select()函式監聽的套接字個數超過1024個時(因為fd_set結構在大部分unix系統中都對其可以監聽的套接字個數作了1024的限制,如果要突破這個限制,必須修改標頭檔案並重新編譯核心),我們就不能使用select多路復用機制。

拿recv()函式來說,我們可以這樣進行呼叫:

recv(fd, buf, sizeof(buf), msg_dontwait);

注意到我們這裡採用了msg_dontwait標誌,它的作用是告訴recv()函式如果有資料到來的話就接受全部資料並立刻返回,沒有資料的話也是立刻返回,而不進行任何的等待。採用這個機制就可以在多於1024個套接字連線時使用for()迴圈對全部的連線進行監聽。

TCP IP程式設計基礎 超時 多路復用 非阻塞

在tcp連線中,recv等函式預設為阻塞模式 block 即直到有資料到來之前函式不會返回,而我們有時則需要一種超時機制使其在一定時間後返回而不管是否有資料到來,這裡我們就會用到setsockopt 函式 int setsockopt int s,int level,int optname,void...

《網路程式設計》I O 多路復用

在前面的文章中介紹了五種 i o 模型 i o 模型 這裡介紹 i o 模型中 i o 多路復用在 tcp 套接字程式設計中的使用。在 i o 多路復用中主要是 select 和 poll 函式的使用。該函式允許程序指示核心等待多個事件中的任何乙個發生,並只在乙個或多個事件發生或超過指定時間後才被喚...

Linux IO多路復用

一.select 函式 include include include int select int n,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout fd clr int fd,fd set set f...