LINUX忘却録-リナックス(主にdebian)の覚書や、解説を書いています。
[17]  [16]  [15]  [14]  [13]  [12]  [11]  [10]  [9]  [8]  [7
ノンブロッキングとは、ソケット(socket)の命令を、非同期で渡してプログラムに直ぐに返す方法です。
この方法では、通常接続が完了していれば、送受信可能ですが、接続が完了していなければ、送受信は出来ないといった状態を知る事が出来ず、様々な問題があります。
そこで、ノンブロッキングの接続を行う場合は、大抵 Select (ソケットの状態を知る命令)と同時に使用します。

(通常 Select は、ブロッキング送受信で使用する)

ノンブロッキングを利用したタイムアウト付接続のサンプルソース
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#define SOCKADDR_IN             struct sockaddr_in
#define SOCKET                  int
#define BUFSIZE                 8192
#define MAX_PATH                256 

int main( int argc, char *argv[] ){
    SOCKET          sock;
    SOCKADDR_IN     addr;
    char            rbuff[BUFSIZE];
    fd_set          readfds;
    fd_set          writefds;
    struct timeval  timeout;

    int             port = 23;
    int             ret;
    int             addrlen;
    int             val;
    //入力パラメータをチェック
    if( argc <=1 ) return -1;
    if( argc >2 )
            port = atoi( argv[2] );
       //ソケットを作成
        sock = socket( AF_INET, SOCK_STREAM, 0 );
        if( sock == -1 ){
                printf( "err: socket\n" );
                return -1;
        }
    //接続相手先を設定
    memset( &addr, 0, sizeof( addr ) );
    addr.sin_family = AF_INET;
    addr.sin_port = htons( port );
    addr.sin_addr.s_addr = inet_addr( argv[1] );
    //ソケットをノンブロッキングに設定
    val = 1;
    ioctl(sock, FIONBIO, &val);
    FD_ZERO(&readfds);
    FD_SET(sock, &readfds);
    //接続のタイムアウトを5秒に設定
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    //指定したサーバに接続要求命令
    ret = connect( sock, (struct sockaddr *)&addr, sizeof( addr ) );

    if( ret != 0 ){
        //ノンブロッキングなので接続が完了していないので、必ずエラーになります。
        printf( "エラー(%d):%s\n", errno, strerror( errno ) );
    }
    //そこで、ソケットが受信可能な状態になれば、接続が完了または、拒否されているのでセレクトを実行
    ret = select(sock+1, &readfds, NULL, NULL, &timeout);
    if( ret == 0 ){
        //セレクトの戻り値が0の時、タイムアウト
        printf( "接続タイムアウト\n" );
    }else{
        //セレクトの対象が自分のソケットなら
        if (FD_ISSET(sock, &readfds)) {
            //受信を試してみます。(ここでは、試すだけなので0バイト受信しようとしてます)
            ret = recv( sock, rbuff, 0, 0 );
            if( ret == -1 ){
                //受信がエラーなら、接続拒否
                printf( "接続拒否(相手サーバは存在するが、指定したポートで待機していない、又は、接続が許可されていない。\n", ret );
                        }else{
                //受信成功なら、接続に成功しています。
                printf( "接続成功\n" );
            }
        }
    }
    //後処理
    close( sock );
    return 0;
}

この記事にコメントする
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
この記事へのトラックバック
この記事にトラックバックする:
delhi escorts
wluc wluc siamese kitten with breeding rights siamese kitten with breeding rights
URL 2009/10/01(Thu)05:23:06
repossessed homes
cabazon outlets cabazon outlets jumeirah motel jumeirah motel
URL 2009/10/20(Tue)22:00:51
love's unending legacy
underarm hair removal underarm hair removal sandy koufax sandy koufax
URL 2009/10/20(Tue)22:32:42
mashed potato casserole
104.9 clear fm 104.9 clear fm subaru brat subaru brat
URL 2009/10/20(Tue)23:38:30
icfai business school
rss feeds filetype rss rss feeds filetype rss cardmember services cardmember services
URL 2009/10/21(Wed)00:34:45
kidsline decals
comprar esencias naturales comprar esencias naturales kost 103.5 kost 103.5
URL 2009/10/21(Wed)02:26:05
maricopa county library
tim hasselback tim hasselback fuzzi bunz fuzzi bunz
URL 2009/10/21(Wed)03:33:53
cuppy cake song
haulmark trailer mi haulmark trailer mi micro paiement audiotel micro paiement audiotel
URL 2009/10/21(Wed)04:09:12
chadam
mace pepper spray mace pepper spray porntal porntal
URL 2009/10/21(Wed)05:03:08
chopard lunar one
pensacolanewsjournal pensacolanewsjournal hobo spider bites hobo spider bites
URL 2009/10/21(Wed)05:54:32
sfgiants
briana frost briana frost
URL 2009/10/21(Wed)07:06:23
skbjvlto
skbjvlto
URL 2009/12/18(Fri)05:05:01
フリーエリア
Copyright © LINUX忘却録 All Rights Reserved.