🙆

ServerSocketを作るRubyラッパー

2024/10/26に公開

サーバーSocketを扱うRubyラッパー。

本記事はなるほどTCPソケット ― Rubyで学ぶソケットプログラミングの基礎を参考にしています。

サーバーの構築

TCPServerクラスを使用すると、シンプルにTCPサーバーを作成できます。

require "socket"
# プロセス中の「サーバー本体」を抽象化
server = TCPServer.new("0.0.0.0", 4481)

上記のコードは、より低レベルなSocketクラスを使用した下記のコードと同じ動作をします。

require 'socket'

server = Socket.new(:INET, :STREAM)
addr = Socket.pack_sockaddr_in(4481, '0.0.0.0')
server.bind(addr)
server.listen(5)

接続処理

サーバーの接続処理はaccept_loopで実装します。

require "socket"
# プロセス中の「サーバー本体」を抽象化
server = TCPServer.new("0.0.0.0", 4481)
# 接続処理を抽象化
Socket.accept_loop(server) do |connection|
  # ブロック引数 `connection` は、クライアントとの接続を表すSocketオブジェクト。acceptを呼び出したときの戻り値と同じ
  connection.close
end

loopを利用する下記のコードと同じ。

require 'socket'

socket = Socket.new(:INET, :STREAM)
addr = Socket.pack_sockaddr_in(4481, '0.0.0.0')
socket.bind(addr)
socket.listen(5)

loop do
  connection, _ = socket.accept
  connection.close
end

accept_loopの引数にはサーバーの集合を渡すことができる。

require "socket"
# プロセス中の「サーバー本体」を抽象化
servers = Socket.tcp_server_sockets("0.0.0.0", 4481)
# 接続処理を抽象化
Socket.accept_loop(servers) do |connection|
  connection.close
end

極めつけ

Socket.tcp_server_loopを使用すると、サーバーの作成から接続処理までをシンプルに実装できる。

require "socket"

Socket.tcp_server_loop("0.0.0.0", 4481) do |connection|
  data = connection.gets
  puts "Received: #{data}"

  connection.puts "Server received: #{data}"
  connection.close
end

実際に接続テストしてみます。

echo ohai | nc localhost 4481

Discussion