S
S
simply_user2016-08-27 16:45:18
C++ / C#
simply_user, 2016-08-27 16:45:18

Do I need to validate received data and send notification of receipt when using TCP?

Hello!
I am writing a program for exchanging files in C# using the TCP protocol and sockets. I know that this protocol provides reliable and ordered data delivery. But is it possible to rely on it completely, in terms of the fact that the received data does not contain errors that occurred during transmission? Here is a quote from the wiki:

Although the protocol performs a checksum check on each segment, the algorithm used is considered weak. (...) In general, distributed network applications are encouraged to use additional software to ensure the integrity of the transmitted information.

If transmission errors are indeed possible, then here is how I propose to work around them. My program has a NetMessage class that encapsulates the logic for sending and receiving data. It contains an instance of the Header structure - a header, in the simplest case, this is the length of the data and the command code; and, in fact, the data itself is a byte array. This is how the data is sent:
public async Task ReceiveAsync()
        {
            await header.ReceiveAsync(netHelper); //Получаю заголовок.

            if (header.LengthData != -1)
                buffer = await netHelper.ReceiveAsync(header.LengthData); //Если в сообщении есть данные, то получаю их.
        }

Assuming that errors are possible during transmission, then both after receiving the header and after receiving the data, it is necessary to send notifications that the data was received successfully or not. It might look something like this:
public async Task ReceiveAsync()
        {
            const byte SUCCESS = 1;
            const byte FAILURE = 2;

            if (await header.ReceiveAsync(netHelper))
                await netHelper.SendAsync(new byte[1] { SUCCESS });
            else
                await netHelper.SendAsync(new byte[1] { FAILURE });

            if (header.LengthData != -1)
            {
                buffer = await netHelper.ReceiveAsync(header.LengthData);

                if (CheckHash(buffer, header.Hash))
                    await netHelper.SendAsync(new byte[1] { SUCCESS });
                else
                    await netHelper.SendAsync(new byte[1] { FAILURE });
            }
        }

It looks good, but only now, for each data send, in addition to two calls to the ReceiveAsync method to send data, two more calls to the SendAsync method will be added to send notifications, and, accordingly, two calls to ReceiveAsync on the receiving side to receive them in a similar SendAsync method of the NetMessage class. These extra calls will also affect the data transfer rate and increase the load on the communication channel, especially if there are a lot of them (when transferring a large file, for example, it will be divided into parts, say 8 kb each, and each part will be transferred using NetMessage) .
The question is, is it necessary to do all this? Are mistakes really possible? And if possible, then you need to use the approach that I suggested, or can you do it differently and save on network operations?
Thank you for your attention.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
Jacob E, 2016-08-27
@simply_user

The whole question is criticality - if an accident can occur from broken data, then check again, and if you post cats, then you don’t need to bother.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question