Task #1776
openTransport: ensure all packets are sent before closing socket
0%
Description
In UNIX and TCP transports, ensure all packets are sent before closing the socket.
This requirement can be satisfied if Boost.Asio close() is blocking, or there's a way to guarantee that all packets are sent out.
Updated by Alex Afanasyev over 10 years ago
- Project changed from NFD to ndn-cxx
- Category changed from Faces to Base
- Target version changed from v0.3 to v0.3
Updated by Davide Pesavento over 10 years ago
I've had this problem a few years ago while writing a network game server in C++. I wasn't using boost but this is a general problem, not library-specific. I suppose boost's close
just wraps the close
socket API, which means that the call is not blocking and the closing is performed in the background.
If you want close
or shutdown
to block until all data has been flushed, you need to use the SO_LINGER socket option. However I don't think this is a good idea because it turns an asynchronous API into a synchronous one. And even with SO_LINGER you still do not have any guarantee that all the data has been sent to the remote endpoint (because of kernel and/or network adapter buffering).
Calling shutdown
before close
(as NFD already does) guarantees that (e.g. for TCP) a FIN packet is transmitted after all data submitted through write
has been sent. This still doesn't mean that the remote end received the data.
For a really robust solution I suggest reading http://ia600609.us.archive.org/22/items/TheUltimateSo_lingerPageOrWhyIsMyTcpNotReliable/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable.html
Updated by Alex Afanasyev over 10 years ago
I think if there is a guarantee that FIN is sent after all data currently in transmission buffer, then it should be good enough.
Updated by Junxiao Shi about 10 years ago
Does this Task refer to close()
in TCP socket, in UDP socket, or in UNIX Stream socket?
@Alex should add specifics in the Description.
Updated by Alex Afanasyev about 10 years ago
The question refers to all sockets (all our transports).
This issue is not that important and we can, technically, delete the target version.
Updated by Junxiao Shi about 10 years ago
- Subject changed from Investigate if Boost.Asio close() is blocking or whether there is a way to guarantee that all data was sent out before shutting down the socket to Transport: ensure all packets are sent before closing socket
- Description updated (diff)
- Target version deleted (
v0.3) - Start date deleted (
07/18/2014)
Updated by Eric Newberry over 6 years ago
It appears this (or a similar issue) is occurring in the current git HEAD version of ndn-cxx. In particular, it appears in producers like ndn-traffic-server that shutdown their face immediately after sending a Data packet with Face::put()
. In the case of ndn-traffic-server, if the producer is told to respond to n Interests before exiting, n-1 Data packets will be successfully sent out on the face, with the last Data seemingly lost. This issue appears to be resolved by scheduling the shutdown operation using a callback at some time in the future (I tested with 2 seconds), although this is definitely a sub-optimal solution.