class TCPServer + TCPSocket + IPSocket + BasicSocket
クラスの継承リスト: TCPServer < TCPSocket < IPSocket < BasicSocket < IO < Enumerable < File::Constants < Object < Kernel
要約
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
-
この値が真ならアドレスからホスト名への逆引きを行わなくなります。
この設定は大域的に作用します。
デフォルトは false です。
以下のメソッドの動作に影響します。
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
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) -> String
-
ソケットのオプションを取得します。getsockopt(2) を参照してください。 取得したオプションのデータをパックした文字列を 返します。
- [PARAM] level:
- getsockopt(2) の 第二引数のlevel
- [PARAM] optname:
- getsockopt(2) の 第三引数のoption_name
[SEE_ALSO] BasicSocket#setsockopt
例:
serv = TCPServer.open("", 0) c = TCPSocket.open(*Socket.unpack_sockaddr_in(serv.getsockname).reverse) s = serv.accept opt = c.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY) p opt #=> "\000\000\000\000" p opt.unpack("i")[0] #=> 0 (Nagle アルゴリズム有効)
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 を返します。
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"]
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)
setsockopt(level, optname, optval) -> 0
-
ソケットのオプションを設定します。setsockopt(2) を参照してください。
level, optname には Socket::SOL_SOCKET や Socket::SO_REUSEADDR といった整数値を用います。
optval には文字列、整数、真偽値(true or false)を渡すことができます。 文字列の場合には setsockopt(2) にはその文字列と 長さが渡されます。整数の場合はintへのポインタが渡されます。 true/falseの場合は0/1という整数と解釈され、そのメモリ領域の intポインタを渡します。
- [PARAM] level:
- setsockopt(2) の level を参照してください。
- [PARAM] optname:
- setsockopt(2) の option_name を参照してください。
- [PARAM] optval:
- 設定値
- [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 }