Bill W. wrote in post #1020562:
> I don't claim to be much of a programmer, and I am also new to RUBY, so
> hopefully this is a good question.
>
> I am making a client that can connect to a port and read an unknown
> number of lines, like a server banner.
> Since the server doesn't close the connection, the program will not move
> on.  To overcome this, I used select() with a timeout, so it will read
> whatever is in the pipe and move on if it gets nothing more within n
> seconds.
>
> Everything worked fine, until I tried crashing the server.  I started to
> get a string of nil coming into the client.
>
> Here is the code for the server:
>
> #!/usr/bin/ruby
>
> require 'socket'               # Get sockets from stdlib
>
> server = TCPServer.open(2000)  # Socket to listen on port 2000
> loop {                         # Servers run forever
>   client = server.accept       # Wait for a client to connect
>   client.puts(Time.now.ctime)  # Send the time to the client
>   #Don't close the connection, to simulate an unknown size.
> }
>
> And my client:
>
> #!/usr/bin/ruby
>
> require 'socket'
>
> host = 'localhost'
> port = 2000
> sockets = Array.new #select() requires an array
> #fill the first index with a socket
> sockets[0] = TCPSocket.open(host, port)
> while 1                              #loop till it breaks
> #listen for a read, timeout 10 seconds
> res = select(sockets, nil, nil, 10)
>   if res != nil  #a nil is a timeout and will break

Situation: the server closes the socket.
select() returns nil if it times out--otherwise it returns a non-nil. 
Presumably, there is no timeout, so execution continues inside your 
if-block.

>         #THIS PRINTS NIL FOREVER on a server crash
>     puts sockets[0].gets()
>

If you check the docs for IO.gets(), it returns nil at end of file. 
When a socket is closed, it sends eof to the other side.  Therefore 
gets() returns nil.  Then the loop begins again.  Nothing has changed, 
so you get the same output, etc., etc.


>   else
>     sockets[0].close
>     break
>   end
> end
>
> If the server stays up, the client gets the time, waits 10 seconds for
> more, and just quits and closes.
> If you kill the server before select() times out, you will get an
> infinite loop of 'nil' in the client.
> I used socket[0] instead of a loop to parse read events in res since
> there is only one socket, and it must be the one triggering select.  (I
> checked to be sure, res[0] and socket[0] are the same socket)
>
> I could use this 'nil' to show that the server has crashed, but I can't
> help but think it is a symptom of something I've done terribly wrong
> that works for now but will bite me in the future.
>
> Any thoughts on where this 'nil' is from?

-- 
Posted via http://www.ruby-forum.com/.