[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Blocking UDP recv() interaction with select

Mark Zvilius

9/3/2007 12:30:00 AM

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-....

1 Answer

Bill Kelly

9/3/2007 7:07:00 AM

0


From: "Mark Zvilius" <zvilius@earthlink.net>
>
> 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.

Your code calling select with STDIN on Windows isn't going to
work properly. Here's what I get in IRB:

>> select( nil, nil, [STDIN], 1.0 )
Errno::ENOTSOCK: An operation was attempted on something that is not a socket.
from (irb):174:in `select'
from (irb):174

It seems this has changed from the old behavior, which, if I recall
correctly, didn't used to raise an exception. I think it used to just
always immediately return from select indicating the file handle
was readable (regardless of whether any data was present or
not.)

But anyway...

I don't have a particular suggestion, other than to only use sockets
with select on Windows.

If you need to check whether any input has arrived at the console,
I've used 'kbhit' in the past.

( http://groups.google.com/group/comp.lang.ruby/msg/27eaef... )


Hope this helps,

Bill