echoサーバ

簡単なechoサーバを作ったら、Ctrl-Cでサーバが落ちない。

require 'socket'

alive = true
trap(:INT) { alive = false }

TCPServer.open('echo') {|server|
  while alive
    Thread.fork(server.accept) {|sock|
      begin
        while s = sock.gets
          puts ":#{s}"
          sock.write(s)
        end
      ensure
        sock.close unless sock.closed?
      end
    }
  end
}

server.acceptでメインスレッドが止まってる…ような。
どうしたらいいんだろうと思って、webrickのソースを読んでみる。
それで、次のように修正。

require 'socket'

alive = true
trap(:INT) { alive = false }

TCPServer.open('echo') {|server|
  reads = [server]
  while alive
    if selected = select(reads, nil, nil, 2.0)
      selected[0].each {|svr|
        if sock = svr.accept
          begin
            while msg = sock.gets
              sock.write(msg)
            end
          ensure
            sock.close unless sock.closed?
          end
        end
      }
    end
  end
}

タイムラグはあるけど、止まることは止まる。
ホント、知識ないよなぁ…orz