Ruby 1.9.3 リファレンスマニュアル > ライブラリ一覧 > socketライブラリ > Socketクラス > tcp_server_loop

singleton method Socket.tcp_server_loop

tcp_server_loop(port) {|sock,addr| ...} -> ()
tcp_server_loop(host, port) {|sock,addr| ...} -> ()

TCP/IP で host:port で待ち受けるサーバ側のソケットを作成し、 新しい接続を受け入れるごとにブロックを呼び出します。

ブロックには新しい接続を表すソケットオブジェクトと、 クライアントアドレスを表す Addrinfo オブジェクトが渡されます。

ブロックの実行が終わってもソケットは close されません。 アプリケーション側が明示的に close する必要があります。

このメソッドはブロックを逐次的に呼び出します。 つまりブロックからリターンするまで次のコネクションを受け入れません。 そのため、同時に複数のクライアントと通信したい場合は スレッドのような並列機構を使う必要があります。

サーバのソケットアドレスを決めるために Addrinfo.getaddrinfo が用いられることに注意してください。 Addrinfo.getaddrinfo は複数のアドレスを返す(IPv4 と IPv6 など) 場合があり、その場合その全てが用いられます。つまり IPv4 と IPv6 の 両方を待ち受けます。getaddrinfo が 0 個のアドレスを返す場合はエラー になります。1つ以上を返した場合にそれが用いられます。

# 逐次的な echo サーバ
# 一度に一つのクライアントした取り扱えない
Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  begin
    IO.copy_stream(sock, sock)
  ensure
    sock.close
  end
}

# スレッドを使った echo サーバ
# 同時に複数のクライアントを取り扱える
# 以下の例だと接続制限がない(つまり接続過剰になりえる)ことに注意
Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  Thread.new {
    begin
      IO.copy_stream(sock, sock)
    ensure
      sock.close
    end
  }
}

内部的には Socket.tcp_server_sockets で 生成したソケットを Socket.accept_loop で処理しています。

[PARAM] host:
割り当てるホスト名
[PARAM] port:
割り当てるポート番号

[SEE_ALSO] Socket.tcp_server_sockets, Socket.accept_loop

class Socket