winsock中select模型實戰

2021-08-14 02:41:24 字數 2671 閱讀 5213

選擇(select)模型是winsock中最常見的 i/o模型。核心便是利用 select 函式,實現對 i/o的管理!利用 select 函式來判斷某socket上是否有資料可讀,或者能否向乙個套接字寫入資料,防止程式在socket處於阻塞模式中時,在一次 i/o 呼叫(如send或recv、accept等)過程中,被迫進入「鎖定」狀態;同時防止在套接字處於非阻塞模式中時,產生wsaewouldblock錯誤。

select 函式原型:

int  select(

int nfds, //傳入引數,忽略

fd_set far * readfds, //檢查可讀性

fd_set far * writefds, //檢查可寫性

fd_set far * exceptfds, //例外資料

const struct timeval far * timeout //本次select呼叫最長的等待時間

);

函式返回值,select()函式呼叫後,返回處於就緒狀態並且已經包含在fd_set結構中的套介面描述符,也就是說,它要修改集合,刪除那些不能進行指定操作的套介面。但如果超時則返回0;如果發生錯誤,則返回socket_error,應用程式可通過wsagetlasterror()獲取錯誤**。

其中fd_set是乙個結構型別說明符,代表著一系列特定套介面的集合,它的定義如下:

typedef  struct  fd_set   fd_set;

timeval是乙個結構型別,它的定義如下:

struct  timeval ;
若將超時值設定為(0 , 0),表明 select 會立即返回,出於對效能方面的考慮,應避免這樣的設定。

以下為測試select()函式的程式,乙個伺服器端兩個客戶端

下面是伺服器端程式:

#define  fd_setsize 500

#include < winsock2.h>

#pragma comment ( lib, "ws2_32" )

#include < stdio.h>

int main()

else

printf( "①載入成功\n" );

//-------②建立流式套接字------------

socket s= socket( af_inet, sock_stream, 0 );

if ( s== invalid_socket)

else

printf( "②已建立監聽套介面:【%d】\n" , s);

//將套介面s置於」非阻塞模式「

u_long u1= 1 ;

ioctlsocket( s, fionbio,( u_long*)& u1);

//-----------③繫結本地位址---------------------

struct sockaddr_in sadd;

sadd.sin_family= af_inet;

sadd.sin_port= htons( 5555 );

sadd.sin_addr.s_un.s_addr= inet_addr( "192.168.31.1" );

if ( bind( s,( sockaddr*)& sadd, sizeof ( sadd))== socket_error)

else

//--------------④進入監聽狀態-----------------

if ( listen( s, 3 )== socket_error)

else

printf( "④進入監聽狀態\n" );

//--------------⑤select-------------------

//準備工作

int x= 1 ;

timeval tv;

tv.tv_sec= 20 ;

tv.tv_usec= 0 ;

fd_set socket_jh01;

fd_zero(& socket_jh01);

fd_set( s,& socket_jh01);

fd_set socket_jh02;

fd_zero(& socket_jh02);

while ( true )

else

}else

else if ( crecv> 0 )

else if ( isend<= 0 )

else

printf( "給客戶【%d】資訊已傳送,首席資訊官度%d位元組\n\n" , socket_jh02.fd_array[ i], isend);

}else

}} //end for

} //end sock_sum

//------------情況二 超時

else if ( sock_sum== 0 )

else

}//--------------情況三 失敗

else

} //while end

closesocket( s);

printf( "退出" );

wsacleanup();

return 0 ;

}

客戶端程式省去。

winsock之select選擇模型

由於使用傳統的socket模型在處理大量的客戶端時需要不斷的開闢多餘的執行緒,這樣無非會很大程度上浪費系統資源,因此,我們需要一種能夠管理套接字的模型。最簡單的select選擇模型可以採用一種有序的方式,輪詢fd set集合,從而同時進行對多個套接字的管理。所用結構體 typedef struct ...

WinSock學習 1 Select模型

新學的,有錯誤請指出 bool initialsocket socket sock,u short port int findposofset socket s,fd set set int tmain int argc,tchar argv fd set fdset fd zero fdset f...

Ruby on Rails中select使用方法

在ruby on rails中真的有一堆select helper可以用,我們經常容易混淆。常見的有三個.select,select tag,collection select 其餘的什麼select date那些不談 我們先來看看乙個基本的下拉式選項骨架 p select name ror opt...