require 'socket' class ClientQuitError < RuntimeError; end port = ARGV.shift || 0 # default is to use the next available port host = ARGV.shift # default is to bind everything server = host ? TCPServer.open(host, port) : TCPServer.open(port) port = server.addr[1] addrs = server.addr[2..-1].uniq puts "*** listening on #{addrs.collect{|a|"#{a}:#{port}"}.join(' ')}" loop do socket = server.accept Thread.start do # one thread per client s = socket port = s.peeraddr[1] name = s.peeraddr[2] addr = s.peeraddr[3] puts "*** recieving from #{name}:#{port}" begin while line = s.gets # read a line at a time raise ClientQuitError if line =~ /^die\r?$/ puts "#{addr} [#{Time.now}]: #{line}" end rescue ClientQuitError puts "*** #{name}:#{port} disconnected" ensure s.close # close socket on error end puts "*** done with #{name}:#{port}" end end