From: Tanaka Akira Date: 2004-03-27T21:17:59+09:00 Subject: Re: non blocking read and thread In article <000001c413d5$e0ec97a0$0300a8c0@boulba>, "yannick" writes: > Thank you for the tip, using sysread does fix this problem. But after > further tests, I found another problem. Apparently, as Ara.T.Howard > pointed out before, Kernel#select and IO#sysread seems to be a bad mix. > Every sockets Kernel#select returns seems to be buffered, as this code > shows : The problem is not Kernel#select but IO#eof?. IO#eof? is a kind of buffered IO methods. EOF should be detected using EOFError caused by sysread. require 'socket' require 'fcntl' Thread.new do sleep 2 client = TCPSocket.new('localhost', '1999') loop do sleep 1 client.syswrite "message" end end server = TCPServer.new("0.0.0.0","1999") thr = Thread.new do socks = [] loop do rs,wd,ed = select(socks+[server],nil,nil) rs.each do |sock| if sock == server n_sock = server.accept n_sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) socks.push n_sock #This call will not raise an IOError #because this socket in not buffered yet. puts n_sock.sysread(100) elsif sock.closed? socks.delete sock else #This call however will raise an IOError. begin puts sock.sysread(100) rescue EOFError sock.close socks.delete sock end end end end end thr.join -- Tanaka Akira