I want to use Ruby for a UDP server application under Windows XP. I
intend to use two threads: one for a simple UI, and a separate thread
for the UDP server (with blocking calls).
As a proof of concept I wrote the following test code, whose intent is
to wait for an incoming message, with the user able to press CTRL-C to
terminate the â€œserver.â€
sock = UDPSocket.new()
sock.bind( “”, PORT )
msg, adr = sock.recvfrom(256)
print adr.inspect, " -> ", msg.inspect, “\n”
main (ui) thread
t = Thread.new( &method(:bar) )
puts “press ctrl-c to quit”
select( nil, nil, [STDIN], 1.0 ) while t.alive?
t.raise( Interrupt )
puts “wait for thread”
puts “thread reaped”
This approach works great for handling CTRL-C: the application exits
However there are 2 problems:
When I send a message to the server, I get the following error on the
C:/bin/ruby/z.rb:54:in `select’: An operation was attempted on something
that is not a socket. (Errno::ENOTSOCK)
While waiting with one thread at the recvfrom() and the other in the
one-second select() loop, this code uses 100% of the available CPU time.
Are these considered bugs, features, or perhaps bugs that are not
fixable? [I am fully aware that Winsock select() only works for sockets, so the underlying implementation must be nastier for Windows than for Unix.]
Is there a more appropriate way to provide a â€œUI threadâ€ alongside a
blocking UDP server thread?
I am using Ruby 1.8.5 on Windows XP.