Problems using gets() on a socket

Hi,

I have built a telnet "chat server" using TCPserver and a select
statement.

If a client exits "cleanly" (such as by closing the shell in which
telnet is running), I can recognize the socket as being terminated using
sock.eof? and everything's fine.

But if a client does wacky stuff like suspend their telnet process with
ctrl+z, then my server hangs at this line:

s = sock.gets()

(where s is a string and sock is the socket of the client)

I tried using s = sock.read and the server could not get past that line,
even for successfully connected clients. I tried using s =
sock.recvfrom(500)[0] but when the client hits that line I get the error
"in `recvfrom': recv for buffered IO (IOError)".

Any help you can provide would be gratefully received!

Very best,

- Andrew

···

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

I have built a telnet "chat server" using TCPserver and a select
statement.

If a client exits "cleanly" (such as by closing the shell in which
telnet is running), I can recognize the socket as being terminated using
sock.eof? and everything's fine.

But if a client does wacky stuff like suspend their telnet process with
ctrl+z, then my server hangs at this line:

s = sock.gets()

(where s is a string and sock is the socket of the client)

Well, that's perfectly OK since from the socket connection's point of view nothing changed. The process is still there and both ends can still exchange data (after the client has been woken up which can happen at any point in time).

I tried using s = sock.read and the server could not get past that line,
even for successfully connected clients. I tried using s =
sock.recvfrom(500)[0] but when the client hits that line I get the error
"in `recvfrom': recv for buffered IO (IOError)".

Any help you can provide would be gratefully received!

If you want to deal with those situations you probably need to extend your protocol to be able to intermediately park a chat session and resume it later. You could even release the socket in between to not waste too many resources. This also requires that your client process catches the signal, notifies the server from the session park and release the socket. (Note, I am not 100% sure that you can do this and still put the process to sleep.)

You can as well simply do nothing because only these things can happen:

1. somebody wakes up the client process and communication resumes normally.

2. somebody kills the client in which case the socket is released and the server will eventually throw an exception or return nil from #gets.

3. network is disconnected or some other error in which case the server likely gets an exception.

Kind regards

  robert

···

On 28.08.2010 23:24, Geometric Patterns wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

But if a client does wacky stuff like suspend their telnet process with
ctrl+z, then my server hangs at this line:

s = sock.gets()

This socket tutorial might help you:
http://en.wikibooks.org/wiki/Ruby_Programming/Reference/Objects/Socket

···

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