From: Mark Zvilius Date: 2007-09-03T09:29:44+09:00 Subject: Blocking UDP recv() interaction with select() 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/.