singleton method Socket.tcp_server_loop

tcp_server_loop(port) {|sock,addr| ...} -> ()[permalink][rdoc][edit]
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 サーバ
# 一度に一つのクライアントした取り扱えない
require 'socket'

Socket.tcp_server_loop(16807) {|sock, client_addrinfo|
  begin
    IO.copy_stream(sock, sock)
  ensure
    sock.close
  end
}

# スレッドを使った echo サーバ
# 同時に複数のクライアントを取り扱える
# 以下の例だと接続制限がない(つまり接続過剰になりえる)ことに注意
require 'socket'

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