V
V
Vermut7562016-12-08 18:59:08
Delphi
Vermut756, 2016-12-08 18:59:08

TCP: why does a “black hole” form when the cable is disconnected, that is, Write loses data for some time, but does not give an error?

I am creating a server. Online, not local.
The connection is persistent.
Here at the client in a network cable contact vanishes.
And just at this time the client is going to send a message.
The client calls Writeand... that's it! Silence!
Writesuccessfully fulfills, no exception, but the data is lost, they are not sent even if you immediately plug the cable into place. Once again: data is lost, irretrievably.
And what's more, I call again Write, and again the same thing!
However, if you wait half a minute after removing the cable and only then call Write, then there will be an expansion.
Why not right away?
Why is data lost and (it turns out) there is even a term "black hole" when everyone is trumpeting about TCP's reliability?
I don't know what to do and how to do it right.
I could Writeimmediately call after that Read, so it seems to work as it should, but the fact is that according to the condition of the task, I have to constantly spin this one Readin the background thread on the client in a waiting loop, and on the server there is also a loop, so I can’t use Readin other places - this will confuse the code, well, if only with Peek, but is this the right solution?
They say that heartbeat / keepalive will help to work correctly, but I don’t understand how, just as I don’t understand the essence of the problem. Well, Write should not lose data.
PS The described phenomenon is very strange. After all, the server always sends a packet with the ACK flag in response, and if there is no cable, then this packet will not arrive, so why doesn’t the client’s OS check whether it has arrived and throw out an exception?
And why does she start throwing it away with a longer cable break (about half a minute)?
PPS
OS - Windows 8.1 x64 client, Windows 2000 x64 server.
Server language - C#.
The client's language is C# or Delphi 7 (Indy 9), the same in both languages.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Sergey, 2016-12-08
@begemot_sun

The network stack has buffers for sending and receiving.
You have sent the package, this does not mean that you are waiting for confirmation of delivery from the other end.
You send next and next packets.
The system accumulates "such confirmation needs", and when they come from the other side, the system removes "this need" from memory and sends it further.
That. a streaming write to the port is performed, as well as a streaming confirmation of delivery.
When something goes wrong, confirmations stop coming. The data you want to send is stored in the send buffer. At this time, the system is waiting for confirmation from the other party.
When you plug in the cable, the send buffer is full.
+ the system cannot send other packages because there is no delivery confirmation about the previous ones.
That. if the send buffer is full, then your data is lost.
The system never knows when you have turned on the cable. She can just send a packet ala ping after a while. In Linux, this time is around 2 hours by default. That. an inactive socket can live for 2 hours and nothing will happen to it, you will write to it, but nothing will happen.
PS This is not my exact description, purely "description by concept" \m/

M
Maxim, 2016-12-08
@khrisanfov

This is solved by setting keepalive to the desired value (on the server or client side). A packet without data is sent at the specified interval to check whether the connection is alive or not. If not, then the socket is closed.

M
MrJeos, 2016-12-08
@MrJeos

Similar situations are well analyzed here: https://habrahabr.ru/company/mailru/blog/316128/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question