linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Glynn Clements <glynn@gclements.plus.com>
To: Bogdan Cristea <cristeab@gmail.com>
Cc: linux-c-programming@vger.kernel.org
Subject: Re: close socket and TCP RST
Date: Thu, 12 Apr 2012 00:31:41 +0100	[thread overview]
Message-ID: <20358.5213.624894.840711@cerise.gclements.plus.com> (raw)
In-Reply-To: <5706767.2IZuFMGXdL@desktop>


Bogdan Cristea wrote:

> > In many cases, shutdown() is not necessary. Normally, one side knows
> > whether the other side will send more data. E.g. for (non-pipelined)
> > HTTP, the client sends a request, the server sends a response, then
> > closes the connection.
> 
> It is exactly what he does, but the question is how to close the connection so 
> that the client receives the last message. 
> He is using for this:
> 
>  err = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lin, sizeof(lin));
> 
> but for some reason it does not work as it should.

IIUC, he close()s a socket which has unread data. Whether the data had
already been received when close() was called or whether it arrived
afterwards doesn't matter.

Normal behaviour is simply not to use close() or shutdown(SHUT_RD) if
you expect to receive more data, e.g. wait until you have seen EOF
(i.e. read(), recv() etc return a zero count) before closing the read
side of the socket.

Current Linux behaviour is that receiving data on a close()ed socket
sends a RST. No data can be sent after a RST.

SO_LINGER doesn't affect this; it just affects whether close() or
shutdown(SHUT_WR) wait until the data has been sent (i.e. for the FIN
to be ACK'd).

AFAIK, there is no way to make close() or shutdown(SHUT_RD) silently
discard subsequent inbound data.

The exact behaviour of SHUT_RD isn't specified by any standard. The
RFCs don't deal with the sockets API, and POSIX just says "Disables
further receive operations". For Unix-domain sockets, a writer will
receive SIGPIPE/EPIPE; Linux' current behaviour for TCP sockets is at
least consistent with that.

Alternatives include:

1. ACK and discard the data. But then there would be no way for the
sender to identify that it's writing to a closed socket.

2. Do nothing. The receive buffer will fill, the window will close,
and the sender will block until someone kills it (it won't time out
because probes will still be met with an ACK of the last byte which
fitted into the buffer).

If the OP wants to send outstanding data, but doesn't want to wait for
EOF from the sender, the solution is to use SO_LINGER with a long
timeout and shutdown(SHUT_WR). The shutdown() won't return until the
FIN (and everything before it) has been ACK'd. At that point, he can
just close() the socket; presumably it won't matter if subsequent data
results in a RST (if it does matter, there is no alternative to
reading until EOF).

-- 
Glynn Clements <glynn@gclements.plus.com>

  reply	other threads:[~2012-04-11 23:31 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-09 23:46 close socket and TCP RST Celelibi
2012-04-10 21:01 ` Bogdan Cristea
2012-04-11  0:38   ` Celelibi
2012-04-11 13:33 ` Glynn Clements
2012-04-11 18:42   ` Bogdan Cristea
2012-04-11 23:31     ` Glynn Clements [this message]
2012-04-13  1:54       ` Celelibi
2012-04-13  1:37   ` Celelibi
2012-04-13  7:32     ` Glynn Clements
2012-04-14 15:37       ` Celelibi
2012-04-14 16:13         ` Glynn Clements
2012-04-15  0:41           ` Celelibi
2012-04-16 20:43             ` Glynn Clements

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20358.5213.624894.840711@cerise.gclements.plus.com \
    --to=glynn@gclements.plus.com \
    --cc=cristeab@gmail.com \
    --cc=linux-c-programming@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).