Calling close() on a non blocking socket from within an io watcher

Marc Lehmann schmorp at
Sat Aug 8 15:38:31 CEST 2009

On Sat, Aug 08, 2009 at 02:56:48PM +0200, Graham Leggett <minfrin at> wrote:
> > the correct solution is to use a protocol with handshake.
> Can you explain in more detail what you mean by this? I am already using
> a protocol with handshake, the message I am sending is the last goodbye.
> Trouble is the other side doesn't see they last goodbye, they just see
> connection reset by peer.

Then the other side is probably sending you soemthign, which would then
result in a tcp rst.

close'ing simply puts the socket into linger mode, it doesn't drop any data.
If the other side tries to send data to a closed socket, it will get a rst.

I assume you didn't do soemthign stupid such as disable lingering (google
for SO_LINGER to get the details)

> > blocking vs. non-blocking is not the issue, the behaviour is exactly the
> > same.
> That contradicts this:
> Specifically the bit that says "Stop trying to transmit data from this
> socket. Discard any data waiting to be sent.".

You surely mean the bit saying "If there is still data waiting to be
transmitted over the connection, normally close tries to complete this
transmission." :)

You quote from the wrong part of that page, namely shutdown. That has
obviously no relevance to close.

Besides, nothing is said about blockign vs. non-blocking. If you think
a while you will realise that it doesn't matter whether the socket was
blocking or not, as the write behaviour is exactly the same when you write
any data.

> I am seeing data waiting to be sent being discarded, thus the original
> question.

Well, it doesn't happen unless your operating system is *very* buggy or
you did soemthign stupid.

So what you describe will not happen when you use close.

So either your program does not do what you claim it does, your protocol does
nto work the way you claim it does, or your operating system is buggy.

If your kernel is linux or some bsd, it is almost certainly one of the
first two reasons - broken close would break most applications on this

> How, using libev, do I wait for an acknowledgment from the other side? I
> can get an event saying "ready to write", but I cannot find an event
> that says "ready to close".

There isn't any such event, and you do not use it. Design your protocol to
send an acknowledgment and wait for it, then close the socket.

It's really simple.

what you described does _not_ include an acknowledgment - what you
described is simply closing the socket after sending data, you do not wait
for an ack.

Design your protocol that way and your problem will be gone.

Note that this whole issue has nothing to do with libev or non-blocking
operations. The same failure mod exists with purely blocking code as well.

                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_    
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      pcg at
      -=====/_/_//_/\_,_/ /_/\_\

More information about the libev mailing list