blob: 4807d50272ff25d77cee74e7920fabfa62c44663 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
}
|