select 〜TCP/IP通信 データが届いているかチェックする〜


目次に戻る


UNIX上ではselectといったらストリームから送受信がノンブロックで実行できるかチェック する関数。と位置づけられていますが、WindowsではWinsockの中に含まれているのでソ ケット通信の中で紹介することにします。
 
先日 send,recv を紹介したときに「これらの関数は処理が終了するまでブロックして しまう」と説明しました。もう少し具体的に書くと、 send関数は「送信できる状態まで待ち、データを送信する。」recv関数は「データが届くま で待ち、届いたデータを受信する。」機能を提供します。つまり、sendはデータが送信でき る状態ならばブロックしませんし、recvはデータが届いている状態ならばブロックしない。 という事になります。
 
そこで、select関数の登場です。
select関数を使えば、指定したソケットハンドルに対して、「現在データをノンブロック で送信できる状態なのか」「現在指定したソケットにデータが届いているのか
」をノンブロックでチェックすることができます。
 
/* ノンブロックでrecvを行えるかチェックする */
int CheckReceivable( int fd )
{
   fd_set fdset;
   int re;
   struct timeval timeout;

   FD_ZERO( &fdset );
   FD_SET( fd , &fdset );

   /* timeoutは0秒。つまりselectはすぐ戻ってく る */
   timeout.tv_sec = 0;
   timeout.tv_usec = 0;

   /* readできるかチェック */
   re = select( fd+1 , &fdset , NULL , NULL , &timeout );

   return (re == 1) ? TRUE : FALSE;

}

/* ノンブロックでsendを行えるかチェックする */
int CheckSendable( int fd )
{
   fd_set fdset;
   int re;
   struct timeval timeout;

   FD_ZERO( &fdset );
   FD_SET( fd , &fdset );

   /* timeoutは0秒。つまりselectはすぐ戻ってく る */
   timeout.tv_sec = 0;
   timeout.tv_usec = 0;

   /* writeできるかチェック */
   re = select( fd+1 , NULL , &fdset , NULL , &timeout );

   return (re == 1) ? TRUE : FALSE;
}



目次に戻る