require 'socket' require 'logger' require 'timeout' require 'thread' TCP_PORT = 12345 $working = true $server_thread = nil $logdata = Hash.new{0} class StopServer < RuntimeError end def show_result result puts "\033[H\033[J" puts '===================================================' result.sort_by{|k, v| k.to_i || k}.each{|k, v| puts "#{k} #{'*' * v}" } puts '===================================================' end def collect() conn = {} result = Hash.new{0} queue = Queue.new viewer = Thread.new{ while r = queue.deq result[r[0]] += 1 unless r[2] == nil result[r[2]] -= 1 end show_result(result) end } $server_thead = Thread.new{ begin gs = TCPServer.new(TCP_PORT) while $working Thread.new(gs.accept) {|s| begin timeout(2){ addr = s.peeraddr[3] data = s.gets sel, name = data.split(/\s+/) i = sel.to_i sel = i.to_s if i < 1 || i > 9 s.puts 'error: illegal selection' elsif name == nil s.puts 'error: no name' elsif conn[addr] != nil if name != conn[addr] s.puts 'error: different names for one addr' else s.puts 'updated' queue.enq [sel, name, $logdata[name]] $logdata[name] = sel end else conn[addr] = name s.puts 'ok' queue.enq [sel, name, nil] $logdata[name] = sel end s.close } rescue Exception => e STDERR.puts e.to_s end } end rescue StopServer rescue Exception => e STDERR.puts e.to_s end } end def stop_collect if $server_thread $server_thread.kill $server_thread = nil end end if $0 == __FILE__ logfile = (ARGV.shift || (print('filename? '); gets.chomp)) logfile = './' + Time.now.strftime('%Y%m%d%H%M%S') + logfile + '.csv' if File.exist?(logfile + '.csv') puts 'file exists: ' + logfile else puts 'logfile: ' + logfile collect() puts 'exit if pressed Enter key' gets io = open(logfile, 'w') $logdata.each {|name, sel| io.write( name + ',' + sel + "\n") } end end