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

class TCPServer + TCPSocket + IPSocket + BasicSocket

クラスの継承リスト: TCPServer < TCPSocket < IPSocket < BasicSocket < IO < Enumerable < File::Constants < Object < Kernel < BasicObject

要約

TCP/IP ストリーム型接続のサーバ側のソケットのクラスです。

このクラスによって簡単にソケットを利用したサーバのプログラミングができます。

例えば echo サーバは以下のようになります。

require "socket"

gs = TCPServer.open(0)
socks = [gs]
addr = gs.addr
addr.shift
printf("server is on %s\n", addr.join(":"))

while true
  nsock = select(socks)
  next if nsock == nil
  for s in nsock[0]
    if s == gs
      socks.push(s.accept)
      print(s, " is accepted\n")
    else
      if s.eof?
        print(s, " is gone\n")
        s.close
        socks.delete(s)
      else
        str = s.gets
        s.write(str)
      end
    end
  end
end

Thread を使えばもっと短くなります。

require "socket"

gs = TCPServer.open(0)
addr = gs.addr
addr.shift
printf("server is on %s\n", addr.join(":"))

while true
  Thread.start(gs.accept) do |s|       # save to dynamic variable
    print(s, " is accepted\n")
    while s.gets
      s.write($_)
    end
    print(s, " is gone\n")
    s.close
  end
end

特異メソッド

do_not_reverse_lookup -> bool

Socket#do_not_reverse_lookup の Socket オブジェクト生成時の デフォルト値を返します。

この設定は大域的に作用します。

デフォルトは true です。

do_not_reverse_lookup=(bool)

BasicSocket#do_not_reverse_lookup の値を変更します。

[PARAM] bool:
この値が真ならアドレスからホスト名への逆引きを行わなくなります。

例:

require 'socket'

p TCPSocket.new('localhost', 'telnet').addr
TCPSocket.do_not_reverse_lookup = true
p TCPSocket.new('localhost', 'telnet').addr

=> ["AF_INET", 2253, "localhost", "127.0.0.1"]
   ["AF_INET", 2254, "127.0.0.1", "127.0.0.1"]
for_fd(fd) -> BasicSocket

ファイルディスクリプタ fd に対する新しいソケットを生成します。

返り値のクラスはどのクラスの for_fd を呼びだしたかによって決まります。

BasicSocket.for_fd(fd) # BasicSocket のインスタンスを返す
TCPSocket.for_fd(fd) # TCPSocket のインスタンスを返す
[PARAM] fd:
ファイルディスクリプタ を指定します。
[RETURN]
任意のソケットである fd から対応するソケットクラスのインスタンスを作り、それを返します。
getaddress(host) -> String [redefined by resolv-replace]

IPSocket.getaddress を置きかえ、 resolv ライブラリを使い名前解決します。

[PARAM] host:
ホスト名を指定します。
[EXCEPTION] SocketError:
名前解決に失敗した場合に発生します。
getaddress(host) -> String

ホスト名からホストのアドレスを返します。ホストのアドレスは文 字列は octet decimal の文字列 (例: 127.0.0.1) です。

[PARAM] host:
ホスト名を文字列で指定します。

例:

p IPSocket.getaddress("www.ruby-lang.org")        #=> "210.163.138.100"
gethostbyname(host) -> Array

ホスト名または IP アドレス (整数または"127.0.0.1" のような文字列)からホストの情報を返します。ホスト情報は、ホ スト名、ホストの別名の配列、ホストのアドレスタイプ、ホストの アドレスを各要素とする配列です。ホストのアドレスは octet decimal の文字列 ("127.0.0.1"のような文字列) です。

[PARAM] host:
ホスト名または IP アドレス (整数または"127.0.0.1" のような文字列)を指定します。
[RETURN]
ホスト名、ホストの別名の配列、ホストのアドレスタイプ、ホストのアドレスを各要素とする配列を返します。

例:

p TCPSocket.gethostbyname("www.ruby-lang.org")
#=> ["beryllium.ruby-lang.org", [], 2, "210.163.138.100"]
new(host=nil, service) -> TCPServer
open(host=nil, service) -> TCPServer

新しいサーバー接続をオープンします。service は /etc/services (または NIS) に登録されているサービ ス名かポート番号で指定します。host を指定した時は 指定したホストに対しての接続だけを受け付けます。省略時は全てのホ スト(インタフェース)への接続要求を受け付けることになります。

host に指定できる形式はsocket/ホスト指定形式 を見てください。

[PARAM] host:
接続したいホストを指定します。 host に指定できる形式はsocket/ホスト指定形式 を見てください。
[PARAM] service:
/etc/services (または NIS) に登録されているサービ ス名かポート番号で指定します。
open(host, serv, local_host=nil, local_service=nil) -> TCPSocket [redefined by resolv-replace]
new(host, serv, local_host=nil, local_service=nil) -> TCPSocket [redefined by resolv-replace]

TCPSocket.new のパラメータ host と local_host の名前解決に resolv ライブラリを使います。

[PARAM] host:
ホスト名、または octet decimal によるインターネットアドレスを示す文字列を指定します。
[PARAM] service:
/etc/services (または NIS) に登録されているサービス名かポート番号を指定します。
[PARAM] local_host:
ホスト名、または octet decimal によるインターネットアドレスを示す文字列を指定します。
[PARAM] local_service:
/etc/services (または NIS) に登録されているサービス名かポート番号を指定します。
[EXCEPTION] SocketError:
名前解決に失敗した場合に発生します。
open(host, service, local_host=nil, local_service=nil) -> TCPSocket
new(host, service, local_host=nil, local_service=nil) -> TCPSocket

host で指定したホストの service で指定したポートと接続したソケッ トを返します。host はホスト名、または octet decimal によるインターネットアドレスを示す文字列、service は /etc/services (または NIS) に登録されているサー ビス名かポート番号です。

引数 local_host, local_service を指定した場合、そのアドレス に対して bind(2) します。

[PARAM] host:
ホスト名、または octet decimal によるインターネットアドレスを示す文字列を指定します。
[PARAM] service:
/etc/services (または NIS) に登録されているサービス名かポート番号を指定します。
[PARAM] local_host:
ホスト名、または octet decimal によるインターネットアドレスを示す文字列を指定します。
[PARAM] local_service:
/etc/services (または NIS) に登録されているサービス名かポート番号を指定します。

インスタンスメソッド

accept -> TCPSocket

クライアントからの接続要求を受け付け、接続した TCPSocket のインスタンスを返します。

例:

TCPServer.open("", 0) {|serv|
  c = TCPSocket.new(*serv.addr.values_at(3,1))
  s = serv.accept
  c.write "foo"
  p s.recv(10)  #=> "foo"
}
accept_nonblock -> TCPSocket

ソケットをノンブロッキングモードに設定した後、 accept(2) を呼び出します。

返り値は TCPServer#accept と同じです。

accept(2) がエラーになった場合、 EAGAIN, EINTR を含め例外 Errno::EXXX が発生します。

[EXCEPTION] Errno::EXXX:
accept(2) がエラーになった場合に発生します。
addr -> Array

ソケットの接続情報を表す配列を返します。配列の各要素は第1要 素が文字列 "AF_INET", "AF_INET6" など、第2要素が port 番号、第3要素がホストを表 す文字列、第4要素がホストの IP アドレスを表す文字列 (octet decimal や hexadecimal) です。

[EXCEPTION] Errno::EXXX:
getsockname(2) が 0 未満の値を返した場合に発生します。

例:

serv = TCPServer.new("localhost", 0)
p serv.addr         #=> ["AF_INET", 46102, "localhost.localdomain", "127.0.0.1"]
c = TCPSocket.new(*serv.addr.values_at(3,1))
s = serv.accept
connect_address -> Addrinfo

ローカルマシン内で接続するのに適当なアドレスを Addrinfo オブジェクトで返します。

BasicSocket#local_address の返り値 以下の点を除いては同じものを返します。

  • IPv4 の不定アドレス(0.0.0.0) は IPv4 のループバックアドレス(127.0.0.1) に置換される
  • IPv6 の不定アドレス(::) は IPv6 のループバックアドレス(::1) に置換される

BasicSocket#local_address が接続先として不適なアドレスを返す場合は 例外 SocketError が発生します。

Addrinfo.tcp("0.0.0.0", 0).listen {|serv|
  p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP>
  serv.connect_address.connect {|c|
    s, _ = serv.accept
    p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>]
  }
}
[EXCEPTION] SocketError:
アドレスが接続に不適な場合に返します

[SEE_ALSO] BasicSocket#local_address

do_not_reverse_lookup -> bool

ソケットごとのアドレスからホスト名への逆引きの設定を返します。

真ならアドレスからホスト名への逆引きを行いません。

初期値はソケットを生成したときの BasicSocket.do_not_reverse_lookup の値になります。

[SEE_ALSO] BasicSocket#do_not_reverse_lookup=

do_not_reverse_lookup=(bool)

アドレスからホスト名への逆引きの設定をソケットごとに設定します。

[PARAM] bool:
この値が真ならアドレスからホスト名への逆引きを行わなくなります。

[SEE_ALSO] BasicSocket#do_not_reverse_lookup

getpeereid -> [Integer, Integer]

Unix ドメインソケットにおいて接続相手の euid と egid を 返します。

配列の最初の要素が euid, 2番目の要素が egid です。

ソケットが Unix ドメインソケットでない場合の返り値は 不定です。

Socket.unix_server_loop("/tmp/sock") {|s|
  begin
    euid, egid = s.getpeereid

    # Check the connected client is myself or not.
    next if euid != Process.uid

    # do something about my resource.
  ensure
    s.close
  end
}
getpeername -> String

接続の相手先のソケットの情報を取得します。sockaddr 構造体をパッ クした文字列を返します。getpeername(2) を参照してください。

例:

serv = TCPServer.open("", 0)
c = TCPSocket.open(*Socket.unpack_sockaddr_in(serv.getsockname).reverse)
s = serv.accept
addr = c.getpeername
p addr      #=> "\002\000\267\214\177\000\000\001\000\000\000\000\000\000\000\000"
p Socket.unpack_sockaddr_in(addr)   #=> [46988, "127.0.0.1"]
p addr == s.getsockname     #=> true
getsockname -> String

ソケットの情報を取得します。sockaddr 構造体をパックした 文字列を返します。getsockname(2) を参照してください。

例:

serv = TCPServer.open("", 0)
p serv.getsockname        #=> "\002\000\236C\000\000\000\000\000\000\000\000\000\000\000\000"
p Socket.unpack_sockaddr_in(serv.getsockname)     #=> [40515, "0.0.0.0"]
c = TCPSocket.open(*Socket.unpack_sockaddr_in(serv.getsockname).reverse)
s = serv.accept
getsockopt(level, optname) -> Socket::Option

ソケットのオプションを取得します。getsockopt(2) を参照してください。 取得したオプションのデータを Socket::Option で返します。

level, optname には Socket::SOL_SOCKET や Socket::SO_REUSEADDR といった整数値の他、文字列("SOL_SOCKET", prefixなしの "SOCKET")や シンボル(:SO_REUSEADDR, :REUSEADDR)を用いることができます。

[PARAM] level:
getsockopt(2) の 第二引数のlevel
[PARAM] optname:
getsockopt(2) の 第三引数のoption_name

[SEE_ALSO] BasicSocket#setsockopt

例:

serv = Socket.tcp_server_sockets("", 0)[0]
c = serv.local_address.connect
s = serv.accept
opt = c.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY)
# c.getsockopt("TCP", "NODELAY"),  なども可能
p opt #=> #<Socket::Option: INET TCP NODELAY 0>
p opt.bool #=> false (Nagle アルゴリズム有効)
p opt.unpack("i")[0] #=> 0 (Socket::Option#unpack が互換性のために存在する)
# 整数値の場合は Socket::Option#int を用いる
p c.getsockopt(:IP, :TTL).int #=> 64
listen(backlog) -> 0

listen(2) を実行します。 (Socket#listenと同じ)

backlog は、クライアントからの接続要求を保留できる数です。 TCPServer のインスタンスは最初は backlog の値は 5 で生成されます。

listen(2) が成功すれば 0 を返します。 失敗すれば 例外 Errno::EXXX が発生します。

[PARAM] backlog:
backlog は、クライアントからの接続要求を保留できる数です。 TCPServer のインスタンスは最初は backlog の値は 5 で生成されます。
[EXCEPTION] Errno::EXXX:
listen(2) が失敗すれば 例外 Errno::EXXX が発生します。
[RETURN]
listen(2) が成功すれば 0 を返します。
local_address -> Addrinfo

getsockname(2) で得られたローカルアドレス情報を Addrinfo オブジェクトとして返します。

返されたオブジェクトの Addrinfo#protocol は 0 を 返すことに注意してください。

TCPSocket.open("www.ruby-lang.org", 80) {|s|
  p s.local_address #=> #<Addrinfo: 192.168.0.129:36873 TCP>
}

TCPServer.open("127.0.0.1", 1512) {|serv|
  p serv.local_address #=> #<Addrinfo: 127.0.0.1:1512 TCP>
}

[SEE_ALSO] BasicSocket#getsockname

peeraddr -> Array

接続相手先ソケットの情報を表す配列を返します。配列の各要素は IPSocket#addr メソッドが返す配列 と同じです。

[EXCEPTION] Errno::EXXX:
getpeername(2) が 0 未満の値を返した場合に発生します。

例:

TCPSocket.open("localhost", "http") {|s|
  p s.peeraddr    #=> ["AF_INET", 80, "localhost.localdomain", "127.0.0.1"]
  p s.addr        #=> ["AF_INET", 52615, "localhost.localdomain", "127.0.0.1"]
}
recv(maxlen, flags = 0) -> String

ソケットからデータを受け取り、文字列として返します。 maxlen は受け取る最大の長さを指定します。 flags については recv(2) を参照してください。flags の デフォルト値は 0 です。flags の指定に必要な定数は Socket クラスで定義されています。(例: Socket::MSG_PEEK)

内部で呼び出す recv(2) が 0 を返した場合、このメソッドは "" を返します。 この意味はソケットによって異なります。 たとえば TCP では EOF を意味しますし、 UDP では空のパケットを読み込んだことを意味します。

[PARAM] maxlen:
受け取る文字列の最大の長さを指定します。
[PARAM] flags:
recv(2) を参照してください。
[EXCEPTION] IOError:
[EXCEPTION] Errno::EXXX:
recvfrom(2) がエラーになった場合などに発生します。

例:

s1, s2 = UNIXSocket.pair
s1.write "a"
s1.close
p s2.recv(10, Socket::MSG_PEEK)   #=> "a"
p s2.recv(10)                     #=> "a"
p s2.recv(10)                     #=> ""
recv_nonblock(maxlen, flags = 0) -> String

ソケットをノンブロッキングモードに設定した後、 recvfrom(2) でソケットからデータを受け取ります。

引数、返り値は BasicSocket#recv と同じです。

recvfrom(2) がエラーになった場合、 EAGAIN, EINTR を含め例外 Errno::EXXX が発生します。

[PARAM] maxlen:
受け取る文字列の最大の長さを指定します。
[PARAM] flags:
recv(2) を参照してください。
[EXCEPTION] IOError:
[EXCEPTION] Errno::EXXX:
recvfrom(2) がエラーになった場合などに発生します。
recvfrom(maxlen, flags = 0) -> Array

recv と同様にソケットからデータを受け取りますが、 戻り値は文字列と相手ソケットのアドレス (形式は IPSocket#addr 参照) のペアです。引数につ いては BasicSocket#recv と同様です。

[PARAM] maxlen:
受け取る文字列の最大の長さを指定します。
[PARAM] flags:
recv(2) を参照してください。
[EXCEPTION] IOError:
[EXCEPTION] Errno::EXXX:
recvfrom(2) がエラーになった場合などに発生します。

例:

s1 = UDPSocket.new
s1.bind("0.0.0.0", 0) # 適当に空いている port を割り当てる
s2 = UDPSocket.new
s2.send("foo", 0, s1.getsockname)
mesg, inet_addr = s1.recvfrom(100)
p mesg            #=> "foo"
p inet_addr       #=> ["AF_INET", 32876, "localhost.localdomain", "127.0.0.1"]
recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) -> [String, Addrinfo, Integer, *Socket::AncillaryData]

recvmsg(2) を用いてメッセージを受け取ります。

このメソッドはブロックします。ノンブロッキング方式で通信したい 場合は BasicSocket#recvmsg_nonblock を用います。

maxmesglen, maxcontrollen で受け取るメッセージおよび補助データ (Socket::AncillaryData)の最大長をバイト単位で指定します。 省略した場合は必要なだけ内部バッファを拡大して データが切れないようにします。

flags では Socket::MSG_* という名前の定数の biwsise OR を取った ものを渡します。

opts にはその他のオプションを渡します。今のところ :scm_right => bool というオプションのみ利用できます。このオプションに 真を渡すと、 SCM_RIGHTS 制御メッセージを受け取ったときに、メッセージに含まれる IO オブジェクトを生成します。詳しくは Socket::AncillaryData#unix_rights を参照してください。

返り値は配列で得られます。

返り値の配列の最初の要素は受け取ったメッセージを表す文字列です。

2番目の要素は connection-less socket の場合には送り元の アドレスが Addrinfo オブジェクトとして含まれています。 TCP のような connection-oriented socket の場合は 何が含まれているかはプラットフォーム依存です。

3番目の要素は受け取ったメッセージに付加されているフラグで、 Socket::MSG_* 定数の bitwise OR で表現されています。

残りの要素は補助データ(Socket::AncillaryData オブジェクト)です。

# UnixSocket#recv_io を recvmsg で実装する例
mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true)
controls.each {|ancdata|
  if ancdata.cmsg_is?(:SOCKET, :RIGHTS)
    return ancdata.unix_rights[0]
  end
}
[PARAM] maxmesglen:
受け取るメッセージの最大長
[PARAM] flags:
フラグ
[PARAM] maxcontrollen:
受け取る補助データの最大長
[PARAM] opts:
ハッシュオプション
recvmsg_nonblock(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) -> [String, Addrinfo, Integer, *Socket::AncillaryData]

recvmsg(2) を用いてノンブロッキング方式でメッセージを受け取ります。

ブロッキングの有無以外は BasicSocket#recvmsg と同じです。 詳しくはそちらを参照してください。

[PARAM] maxmesglen:
受け取るメッセージの最大長
[PARAM] flags:
フラグ
[PARAM] maxcontrollen:
受け取る補助データの最大長
[PARAM] opts:
ハッシュオプション
remote_address -> Addrinfo

getpeername(2) で得られたリモートアドレス情報を Addrinfo オブジェクトとして返します。

返されたオブジェクトの Addrinfo#protocol は 0 を 返すことに注意してください。

TCPSocket.open("www.ruby-lang.org", 80) {|s|
  p s.remote_address #=> #<Addrinfo: 221.186.184.68:80 TCP>
}

TCPServer.open("127.0.0.1", 1728) {|serv|
  c = TCPSocket.new("127.0.0.1", 1728)
  s = serv.accept
  p s.remote_address #=> #<Addrinfo: 127.0.0.1:36504 TCP>
}

[SEE_ALSO] BasicSocket#getpeername

send(mesg, flags, dest_sockaddr = nil) -> Fixnum

ソケットを介してデータを送ります。flags に関しては send(2) を参照してください。connect していないソケット に対しては送り先である dest_sockaddr を指定する必要があります。実際に送っ たデータの長さを返します。

dest_sockaddr には「ソケットアドレス構造体を pack した文字列」 を指定します。

データの送信に失敗した場合は例外 Errno::EXXX が発生します。

[PARAM] mesg:
送信するデータを文字列で指定します。
[PARAM] flags:
send(2) の flags を参照してください。
[PARAM] dest_sockaddr:
「ソケットアドレス構造体を pack した文字列」を指定します。
[EXCEPTION] Errno::EXXX:
データの送信に失敗した場合に発生します。

例:

s = UDPSocket.new
sockaddr = Socket.sockaddr_in("discard", "localhost")
s.send("The king has donkey ears!", 0, sockaddr)
sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) -> Integer

sendmsg(2) を用いてメッセージを送ります。

このメソッドはブロックします。ノンブロッキング方式で通信したい 場合は BasicSocket#sendmsg_nonblock を用います。

ソケットが connection-less の場合は dest_sockaddr で 通信先のアドレスを指定しなければなりません。Socket.sockaddr_in の返り値や Addrinfo オブジェクトを引数として渡すことができます。

controls には 補助データ(ancillary data)を渡します。 Socket::AncillaryData のインスタンスや 3要素(cmsg_level, cmsg_type, cmsg_data) の配列を用いることができます。

送ったバイト数を返します。

# UnixSocket#send_io の実装例
# use Socket::AncillaryData.
ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno)
sock.sendmsg("a", 0, nil, ancdata)

# use 3-element array.
ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")]
sock.sendmsg("\0", 0, nil, ancdata)
[PARAM] mesg:
メッセージ文字列
[PARAM] flags:
フラグ(Socket::MSG_* という定数の bitwise OR を取ったもの)
[PARAM] dest_sockaddr:
通信先のアドレス
[PARAM] controls:
補助データの配列

[SEE_ALSO] BasicSocket#sendmsg_nonblock

sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls) -> Integer

sendmsg(2) を用いてノンブロッキング方式でメッセージを送ります。

詳しくは BasicSocket#sendmsg を見てください。

[RETURN]
送ったバイト数
[PARAM] mesg:
メッセージ文字列
[PARAM] flags:
フラグ(Socket::MSG_* という定数の bitwise OR を取ったもの)
[PARAM] dest_sockaddr:
通信先のアドレス
[PARAM] controls:
補助データの配列

[SEE_ALSO] BasicSocket#sendmsg

setsockopt(level, optname, optval) -> 0
setsockopt(socketoption) -> 0

ソケットのオプションを設定します。setsockopt(2) を参照してください。

level, optname には Socket::SOL_SOCKET や Socket::SO_REUSEADDR といった整数値の他、文字列("SOL_SOCKET", prefixなしの "SOCKET")や シンボル(:SO_REUSEADDR, :REUSEADDR)を用いることができます。

optval には文字列、整数、真偽値(true or false)を渡すことができます。 文字列の場合には setsockopt(2) にはその文字列と 長さが渡されます。整数の場合はintへのポインタが渡されます。 true/falseの場合は0/1という整数と解釈され、そのメモリ領域の intポインタを渡します。

引数が1つの場合は Socket::Option で設定値を表現します。

# 真偽値の場合
#setsockopt could be called like this:
sock.setsockopt(:SOCKET, :REUSEADDR, true)
sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
sock.setsockopt(Socket::Option.bool(:INET, :SOCKET, :REUSEADDR, true))

# 整数値の場合
#setsockopt could be called like this:
sock.setsockopt(:IP, :TTL, 255)
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, 255)
sock.setsockopt(Socket::Option.int(:INET, :IP, :TTL, 255))

# より複雑な場合
optval = IPAddr.new("224.0.0.251").hton +
         IPAddr.new(Socket::INADDR_ANY, Socket::AF_INET).hton
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, optval)
[PARAM] level:
setsockopt(2) の level を参照してください。
[PARAM] optname:
setsockopt(2) の option_name を参照してください。
[PARAM] optval:
設定値
[PARAM] socketoption:
設定値を表す Socket::Option オブジェクト
[EXCEPTION] Errno::EXXX:
オプションの設定に失敗した場合発生します。

[SEE_ALSO] BasicSocket#getsockopt

shutdown(how = Socket::SHUT_RDWR) -> 0

ソケットの以降の接続を終了させます。

how の値によって以下のように接続が終了します。

  • Socket::SHUT_RD: それ以降の受信が拒否されます
  • Socket::SHUT_WR: それ以降の送信が拒否されます
  • Socket::SHUT_RDWR: それ以降の送信、受信ともに拒否されます

how を省略すると Socket::SHUT_RDWR を指定したことになります。 shutdown(2) を参照してください。

[PARAM] how:
接続の終了の仕方を Socket::SHUT_RD, Socket::SHUT_WR, Socket::SHUT_RDWR などで指定します。
[EXCEPTION] Errno::EXXX:
ソケットの以降の接続を終了操作が失敗した場合に発生します。
[EXCEPTION] ArgumentError:
how に範囲外の整数を入力した場合に発生します。
[EXCEPTION] SecurityError:
セーフレベルが 4 以上で、ソケットに汚染マークがついていない場合発生します。
sysaccept -> Fixnum

接続したクライアントのソケットをファイル記述子で返すことを除けば TCPServer#accept と同じです。

例:

TCPServer.open("", 0) {|serv|
  c = TCPSocket.new(*serv.addr.values_at(3,1))
  p serv.sysaccept        #=> 6
}
class TCPServer