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.”
···
---------------------
# server thread
def bar
sock = UDPSocket.new()
sock.bind( "", PORT )
begin
msg, adr = sock.recvfrom(256)
rescue Interrupt
puts "interrupt"
else
print adr.inspect, " -> ", msg.inspect, "\n"
end
sock.close
end
# main (ui) thread
t = Thread.new( &method(:bar) )
puts "press ctrl-c to quit"
begin
select( nil, nil, [STDIN], 1.0 ) while t.alive?
rescue Interrupt
t.raise( Interrupt )
end
puts "wait for thread"
t.join()
puts "thread reaped"
---------------------
This approach works great for handling CTRL-C: the application exits
without hesitation.
However there are 2 problems:
1. When I send a message to the server, I get the following error on the
select() call:
C:/bin/ruby/z.rb:54:in `select': An operation was attempted on something
that is not a socket. (Errno::ENOTSOCK)
2. 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.
Thanks,
Mark Zvilius
--
Posted via http://www.ruby-forum.com/.