Project

General

Profile

Actions

Task #1776

open

Transport: ensure all packets are sent before closing socket

Added by Alex Afanasyev almost 10 years ago. Updated almost 6 years ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Base
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:

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.

Actions #1

Updated by Alex Afanasyev almost 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
Actions #2

Updated by Davide Pesavento almost 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

Actions #3

Updated by Alex Afanasyev almost 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.

Actions #4

Updated by Junxiao Shi over 9 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.

Actions #5

Updated by Alex Afanasyev over 9 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.

Actions #6

Updated by Junxiao Shi over 9 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)
Actions #7

Updated by Eric Newberry almost 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.

Actions

Also available in: Atom PDF