From: Aaron Turner Date: 2010-01-13T08:21:25+09:00 Subject: Re: TCPSocket doesn't detect remote disconnection inmediatelly On Tue, Jan 12, 2010 at 2:37 PM, Iñaki Baz Castillo wrote: > El Martes, 12 de Enero de 2010, Aaron Turner escribió: >> Long story short, what you're seeing with Ruby is not a bug, but >> rather how TCP sockets work.  TCP sockets are bi-directional and when >> one side "closes" the connection, they are not actually causing the >> TCP session to tear down as telnet implies, but rather is informing >> the other end of the connection that they have no more data to send. >> The receive direction is still technically open via TCP, although the >> HTTP protocol specifies no more communication is possible. > > Understood, thanks a lot. > > Then I wonder if there is some way to detect that the remote has closed its > side. When it occurs the remote sends a TCP segment with ACK+FIN flags > enabled. > > Is there a way to detect it in Ruby using TCPSocket? if there some attribute > of the socket object that changes whe such ACK+FIN arrives? (however I've > tried most of the TCPSocket methods and found nothing). There are two ways of doing this: 1) The application running over TCP. In this case the HTTP 400 error is telling you that the web server is done talking to you and no future requests will be processed. 2) The other way is when you read, did you get an EOF error? EOF == server has called shutdown() on the socket. Ruby sockets behave just like C sockets. It's just the Ruby language wrapping them. There's nothing "special" about ruby sockets. What this means is that the best resource isn't the ruby docs- they just document the ruby API. To understand how sockets work, read Richard Stevens or start doing google searches on things like "tcp detecting close". > The underlaying system of courses knows it as in case a new TCP segment is > sent (by the Ruby client) it's sent with big PUSH enabled, knowing that the > remote will reply with RESET flag enabled. Is the Ruby TCPSocket aware that > its message is sent with PUSH flag enabled? if so it could raise something > (optionally) so I know that I'll get no response and could reconnect and > retry. Is it possible? The PSH (Push) flag has nothing to do with it. PSH just tells the receiving host that the TCP packet has interesting data for the application and it should quickly "push it up" to the application for processing. > Humm, I think that all this stuff is done at kernel TCP layer so the socket > user has nothing to deal with... am I right? Depends on what you mean by "all this stuff". If you mean making TCP a reliable, bi-directional stream & session based programming construct then yes, the kernel does that for you. If you mean dealing with knowing when you can read/write to the socket, then no, that's your job. You the programmer have a lot of control over tcp sockets and are expected to know how to use them properly. As I said last time, while TCP sockets utilize a very similar API as File IO, but they are more complicated and you need to know how to use them. Good luck. -- Aaron Turner http://synfin.net/ http://tcpreplay.synfin.net/ - Pcap editing and replay tools for Unix & Windows Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety. -- Benjamin Franklin "carpe diem quam minimum credula postero"