Bill Kelly
7/16/2005 10:02:00 PM
From: "James Edward Gray II" <james@grayproductions.net>
>
> Is this the "standard" way to make a nonblocking Socket in Ruby?
>
> require "socket"
> require "fcntl"
>
> server = TCPServer.new(...)
> server.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
>
> __END__
>
> Will that work on Unix and Windows?
As far as I know it's the "standard" way (but that
just means it's the only way I know of. :)
It doesn't work on Windows. :(
I've ended up tacking on: ... if defined? Fcntl::O_NONBLOCK
onto the fcntl() line so that my scripts still run on
windows, even though they may block inappropriately.
Blocking I/O issues have been a thorny issue for me in
trying to write cross-platform network applications in
Ruby.
> If I accept() a connection from that, will the connecting socket be
> nonblocking as well?
I seem to recall discussion of a patch to fix something
related to nonblocking I/O and accept() within the last
year or so... but I could be wrong... (I couldn't find
it with Google.)
I tend to re-issue the nonblock fcntl() call before
every socket operation I perform.
Even so, I *still* hit this timeout occasionally:
if select([sock], nil, nil, UDP_RECV_TIMEOUT)
begin
timeout(UDP_RECV_TIMEOUT) {
sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) if defined? Fcntl::O_NONBLOCK
resp = sock.recvfrom(65536)
}
rescue Timeout::Error
$stderr.puts "Timeout::Error in sock.recvfrom !"
end
end
...Since select() said data was ready, AND since I'm
requesting a nonblocking operation... I have no idea
why #recvfrom sometimes hangs. It used to totally hang
my program (on linux), indefinitely, about once a day,
until I added the timeout().
Regards,
Bill