aboutsummaryrefslogtreecommitdiff
path: root/externals/gridflow/extra/server_2.rb
diff options
context:
space:
mode:
Diffstat (limited to 'externals/gridflow/extra/server_2.rb')
-rw-r--r--externals/gridflow/extra/server_2.rb65
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
+}