1

According to this answer Blocking sockets: when, exactly, does “send()” return?, send() on a blocking socket will return as soon as the user buffer has been copied into kernel buffer. In the case of a delivery failure (i.e., the client doesn't receive the bytes), how does the process that called send() get notified that a failure occurred?

Community
  • 1
  • 1
Guillaume Paris
  • 10,303
  • 14
  • 70
  • 145
  • depends on the type of socket. UDP doesn't care whether packets are delivered or not. TCP does, and your OS will automatically resend packets that did not get acknowledged. How your socket will notify you about a dead connection depends on the socket library you are using. – user2950911 Jul 08 '15 at 13:50

3 Answers3

1

The POSIX/BSD socket APIs do not provide an interrupt driven asynchronous interface to TCP connection errors. Since TCP is reliable, the only way the data was not delivered is if the connection itself suffered a failure that prevented complete delivery.

You have to detect the error by performing some kind of synchronous operation on the (perhaps non-blocking) socket. The most asynchronous mechanism is using select or poll (or OS specific alternatives), which allows waiting for status updates on more than one socket in a single synchronous call. Errors may appear in the exceptfds set of select, or as an error indication when using poll for read or write. In addition, an error will be delivered when you attempt to read or write to a socket that is no longer connected.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • Note that there is another kind of "failure" where the receiver does not drain the receive queue, so your send queue stays full. In that case, your blocking send may block forever. Usually a timer is used to decide that you have waited too long for the send queue to clear, and then you can sever the connection from the sender side (or whatever mitigation action you deem fit). – jxh Jul 08 '15 at 16:37
1

Packets being lost and resent are a normal condition under TCP/IP, even under normal operation (congestion control relies on packets being lost!).

This is not an error, and therefore you shouldn't receive one (indeed, send couldn't possibly return an error, since it has already returned by the time this is detected). Instead, the datagrams are silently resent until acknowledged (or until TCP gives up).

You normally use poll (or select) in combination with blocking sockets, so in case the other end closes the connection or someone pulls out the ethernet cable, you will (well, should, and not necessarily immediately) see POLLHUP, POLLRDHUP, or POLLERR.
When that happens, you know that nobody is listening at the other end any more.

Note that events like routers going down and cables being pulled do not necessarily break a TCP connection, at least not immediately. This can only be detected when a send is attempted, and the destination isn't reachable. That could, in theory, happen only after minutes or hours (or someone could in the mean time plug the cable back in, and you never know!).

Damon
  • 67,688
  • 20
  • 135
  • 185
  • thanks for precision about routers going down and cables being pulled do not necessarily break a TCP connection. Hearbeat is usefull in this case! – Guillaume Paris Jul 08 '15 at 16:27
0

Short answer there is no way of knowing whether data was delivered to the remote end or not unless such a check is incorporated into session layer protocol. It is for this reason that protocols like HTTP require the remote end to send a response even for PUT requests.

Since IP packets traverse multiple networks and may very well take different routes to the destination, there is no way of knowing when sending a packet whether it will reach the remote end. At best the host will continue to resend a packet until the remote end acknowledges the packet or give up after a timeout.

So if you want to be sure whether data is received by the remote end, require a response from the remote end as part of your protocol.

doron
  • 27,972
  • 12
  • 65
  • 103