Ruby で TCP のクライアントとしてサーバーに接続するには TCPSocket.open
(TCPSocket.new
)を使うもんだと思ってたんだけど、最近 Socket.tcp
というのもあることを知った。
どうやら 1.9.2 で追加されたらしい。10年以上も気づかなかった…。サーバー側の Socket.tcp_server_loop
も同じ時に追加されていてこっちは気づいてたんだけどなぁ。
TCPSocket.open
も Socket.tcp
もクライアントとしてサーバーに接続するのでだいたい同じなんだけど、Socket.tcp
の方は connect_timeout
というキーワード引数で接続タイムアウト時間を指定できる(2.0.0 から)。
なお、2.7 から resolv_timeout
というキーワード引数でホスト名解決のタイムアウト時間を指定できるようにもなっている…と思いきや、3.0 では無効になってた。短い命だった。
返すオブジェクトが TCPSocket
か Socket
かの違いはある。けど、TCPSocket
の方に addr
, peeraddr
というメソッドがある程度の違い。
TCPSocket.instance_methods - Socket.instance_methods #=> [:addr, :peeraddr]
それに addr
, peeraddr
と同じ役割のメソッドは Socket
の方にも local_address
, remote_address
として用意されている。
s = TCPSocket.open("google.com", 80) s.addr #=> ["AF_INET6", 51432, "2405:6582:6260:1b00:f7c9:81c:93f6:b1bd", "2405:6582:6260:1b00:f7c9:81c:93f6:b1bd"] s.peeraddr #=> ["AF_INET6", 80, "2404:6800:4004:818::200e", "2404:6800:4004:818::200e"] s = Socket.tcp("google.com", 80) s.local_address #=> #<Addrinfo: [2405:6582:6260:1b00:f7c9:81c:93f6:b1bd]:51444 TCP> s.remote_address #=> #<Addrinfo: [2404:6800:4004:81d::200e]:80 TCP>
local_address
, remote_address
の方は配列じゃなくてちゃんとオブジェクトを返すので良さそう。
と、ここまで書いて TCPSocket
のソースを読んでみたら、TCPSocket.open
の方にも connect_timeout
というキーワード引数が増えていた。3.0 で追加されたらしい。
というわけで、まあどっちでも好きな方を使えばいいんだけど、個人的には Socket.tcp
の方が良さそうな気がしてるので、今後は Socket.tcp
を使おうと思う。