Re: a question about TIdIOHandlerStack.Connected

Giganews Newsgroups
Subject: Re: a question about TIdIOHandlerStack.Connected
Posted by:  Remy Lebeau \(Indy Team\) (re…
Date: Sat, 15 Jan 2011

"jvlad" <dm…> wrote in message

> Now we're about to check conection status, so we call IO's
> Connected() and it calls ReadFromSource this method runs select
> recognizes that the socket is not readable anymore so it returns -1.

When a socket has been cleanly disconnected by the remote peer, select()
reports the socket is readable, not unreadable like you claim.  It is then
the following read operation that reports the disconnect, by returning 0
bytes received.  This is documented behavior in the socket APIs that Indy
uses.  Under this situation, ReadFromSource() will return 0 when
ReadDataFromSource() returns 0.  -1 means the socket did not become readable
before the specified timeout elapsed, which is not the case in this

> As you can see this fact is ignored here.

It is supposed to be ignored there.  ReadFromSource() will set the
ClosedGracefully property to True, and then the inherited Connected() will
look at ClosedGracefully (amongst other things).

> Wouldn't it be better either not to call ReadFromSource
> or use the returning value?

No to both.  If ReadFromSource() is removed, Connected() would stop
functioning.  Indy uses blocking sockets, and the only way to detect a
disconnect on a blocking socket is to perform a read/write operation on the
socket.  Obviously, Connected() cannot send any outbound data, so it has to
check for inbound data instead.  The combination of select()=readable and
recv()=0 is the disconnect notification.  The return value of
ReadFromSource() cannot be used by TIdIOHandlerStack.Connected() because the
inherited Connected() methods check for other conditions when deciding
whether Connected() should return True or False.  It is not based on the
socket state alone.

> Seems it should update FClosedGracefully property

It already does.

> or not waste time calling select.

It has to.  select() needs to report readibility, and then recv() needs to
return 0, in order for a disconnect to be detected.

Remy Lebeau (TeamB)


In response to

a question about TIdIOHandlerStack.Connected posted by jvlad on Sat, 15 Jan 2011