RubyでマルチスレッドなTCP Serverのサンプルコード

RubyTCP/IPのソケットを試してみました。サーバ側はマルチスレッドです。

サーバ側サンプルコード

server.rb

require 'socket'

maxlen = 10

server = TCPServer.open(3000)
loop do
  Thread.start(server.accept) do |socket|
    begin
      loop do
        buf = socket.readpartial(maxlen) # クライアントから受信
        socket.write(buf) # そのままクライアントに返答
        $stdout.write(buf) # 動作確認のためサーバ側標準出力
      end
    rescue EOFError => e
      $stdout.write("eof\n") # 切断
    rescue => e
      print e.backtrace.join("\n")
    ensure
      socket.close
    end
  end
end

クライアント側サンプルコード

client.rb

require 'socket'

maxlen = 10

TCPSocket.open("localhost", 3000) do |socket|
  t1 = Thread.start do
    socket.write("Hello\n") # サーバに送信
    sleep(1)
    socket.shutdown() # 1秒たったらクライアントから切断
  end
  t2 = Thread.start do
    begin
      loop do
        buf = socket.readpartial(maxlen) # サーバから受信
        $stdout.write(buf) # 動作確認のためクライアント側標準出力
      end
    rescue EOFError => e
      $stdout.write("eof\n") # 切断
    end
  end
  t1.join # スレッドが終了するまで待つ
  t2.join # スレッドが終了するまで待つ
end

実行例

サーバ側。起動しただけだと黙って待ち受けてます。

$ ruby server.rb

クライアント側。Helloと送信し、同じテキストを受信し、1秒後に切断します。

$ ruby client.rb
Hello
eof

クライアントを複数の端末を使うなどして同時に起動してもサーバ側は並行して処理できています。

$ ruby server.rb
Hello
eof
Hello
eof
Hello
Hello
eof
eof

Javaならレファレンスを見ながら書けば動くだろうという安心感(自信)があります。が、他の言語だとこういうのは、実際に書いて試行錯誤しないと私は書けないです)