From: Bill Kelly Date: 2005-07-17T07:01:54+09:00 Subject: Re: Nonblocking Sockets From: "James Edward Gray II" > > 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