diff options
Diffstat (limited to 'externals/gridflow/extra/server_2.rb')
-rw-r--r-- | externals/gridflow/extra/server_2.rb | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/externals/gridflow/extra/server_2.rb b/externals/gridflow/extra/server_2.rb new file mode 100644 index 00000000..4807d502 --- /dev/null +++ b/externals/gridflow/extra/server_2.rb @@ -0,0 +1,65 @@ +# a server program to connect 2 or more clients together. +# by Mathieu Bouchard + +require "fcntl" +require "socket" + +class IO + def nonblock=flag + bit = Fcntl::O_NONBLOCK + fcntl(Fcntl::F_SETFL, (fcntl(Fcntl::F_GETFL) & ~bit) | + if flag then bit else 0 end) + end + # does not work with any ruby version, due to a bug. see below. + def read_at_most n + s="" + k=1<<(Math.log(n)/Math.log(2)).to_i + while k>0 + unless k+s.length>n + puts "trying #{k}" + (s << read(k)) rescue Errno::EWOULDBLOCK + end + k>>=1 + end + s + end + # this one works but is slow. + def bugfree_read_at_most n + s="" + (s << (read 1) while s.length<n) rescue Errno::EWOULDBLOCK + s + end +end + +serv = TCPServer.new 4242 +socks = [serv] + +loop { + puts "waiting for connection (port 4242)" + begin + loop { + puts "waiting" + ready,blah,crap = IO.select socks, [], socks, 1 + (ready||[]).each {|s| + if s==serv then + sock = serv.accept + sock.nonblock=true + socks << sock + puts "incoming connection (total: #{socks.length-1})" + else + other = socks.find_all{|x|not TCPServer===x} - [s] + stuff = s.bugfree_read_at_most 1024 + p stuff + (s.close; socks.delete s) if not stuff or stuff.length==0 + other.each {|x| + p x + x.write stuff + } + end + } + } + rescue Errno::EPIPE # Broken Pipe + puts "connection closed (by client)" + # it's ok, go back to waiting. + end +} |