s-kitaの日記 このページをアンテナに追加 RSSフィード

2008-05-22

基本TCPソケット2

listen関数

listen関数は、TCPサーバーのみが呼び出す関数

1.socket関数で作成されたソケットはアクティブソケット、すなわちconnectの対象となるクライアントソケットであると見なされる。listen関数は、接続していないソケットをパッシブソケット、すなわちソケットへのコネクション要求をカーネルが受ける状態へ変換する。

2. 第2引数で指定された、このソケットに対するカーネル内のコネクションキューの最大長を設定する。

Kpre>

#include <sys/socket.h>

int listen(int sockfd, int backlog);

戻り値:成功なら0、エラーなら-1

  • socket
  • bind
  • listen
  • accept

    各リスニングソケットに対してカーネル内に次の2種類のキューがある。

  • 1.確立待ちコネクションキュー(incomplete connection queue) 各クライアントから到着したSYNに対応し、TCPの3WHSの完了待ちエントリが含まれるキュー。これらのソケットは、SYN_RCVD状態にある。
  • 2.確立済みコネクションキュー(completed connection queue) TCPの3WHSが完了した各クライアントに対応するエントリが含まれるキュー。これらのソケットは、ESTABLISHED状態にある。

    参考文献

  • UNIXネットワークプログラミング スティーブンズ
  • 基本TCPソケット

    ネットワークI/Oを行うためには、socket関数を呼び出す

    #include <sys/socket.h>
    int socket(int family, int type, int protocol);
    


    socket関数に使用するプロトコルファミリ

    type説明
    AF_INETIPv4プロトコル
    AF_INET6IPv6プロトコル
    AF_LOCALUnixドメインソケット
    AF_ROUTE経路制御ソケット
    AF_KEYキーソケット


    socket関数に使用するソケットの型

    type説明
    SOCK_STREAMストリームソケット
    SOCK_DGRAMデータグラムソケット
    SOCK_RAWrawソケット


    connect関数

    connect関数は、TCPクライアントがTCPサーバーとのコネクションを確立するために用いられる。

    #include <sys/socket.h>
    int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
    
    戻り値:成功なら0、エラーなら-1
    

    sockfdは、socket関数が返したソケットディスクリプタ

    クライアントは、connect関数より先に、bind関数を呼び出さなくてよい。カーネルが必要に応じて短命ポートと始点IPアドレスの両方を選択する。

    connect関数の呼び出しは、TCPの 3 Way Hand Shake を起動する。

    connect関数がエラーになる場合

  • クライアントTCPがSYNセグメントに対する応答を受信しなかった場合

    ETIMEOUTが返される。

  • クライアントからのSYNに対応するサーバーからの応答がRSTであった場合、サーバーホスト上の指定したポートでコネクションを待っているプロセスが存在しないことを表す。ハードエラー。ECONNREFUSEDが返される。

  • クライアントからのSYNがいずれかの中間ルーターでICMP終点到達不可エラーを誘発した場合。ソフトエラー。クライアントTCPは、このメッセージを保存するが、SYNを送信し続ける。ある一定時間応答が受信されない場合、EHOSTUNREACH or ENETUNREACHとして返される。




    bind関数

    bind関数は、ソケットにローカルなプロトコルアドレスをバインドする。

    #include <sys/socket.h>
    int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);
    
    戻り値:成功なら0, エラーなら-1
    

    TCPではbind呼び出し時に、ポート番号とIPアドレスの両方を指定することができるし、全く指定しないこともできる。


    myaddrのポート番号に0が指定されていた場合、bindの呼び出し時にカーネルが短命ポートを選択する。

    ワイルドカードIPアドレスが指定された場合、カーネルはソケットが接続されるまで(TCP)、あるいはソケットを通してデータグラムが送信されるまで(UDP)ローカルIPアドレスを選択しない。

    IPv4では、ワイルドカードアドレスは、通常ゼロの値を持つ INADDR_ANY定数で指定し、この値を用いてカーネルにIPアドレスを選択するように指示する。

    struct sockaddr_in servaddr;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    

    bindが返す典型的なエラーにEADDRINUSE(Address already in use - アドレスは既に使用されている)がある。







    参考文献

  • UNIXネットワークプログラミング スティーブンズ