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
#THIS PRINTS NIL FOREVER on a server crash
puts sockets[0].gets()
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?