From: 7stud -- Date: 2011-09-07T16:24:45+09:00 Subject: Re: TCPSocket recv's nil with gets() if the server crashes? 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/.