There was a need to organize a specific protocol on top of TCP, which works on the principle:

1) Side A sends data to side B (int, char, double, not important);

2) Side A expects 1 byte - confirmation that the data is received and processed on side B, rather than lying in the internal system buffer on side A (or even on side B).

The problem is that party B can disrupt the logical consistency of actions, for example, with the goal of side A. collapse.

Side B in response to incoming data can send not 1 byte with confirmation, but two or more. Or even send one byte immediately, but somewhere after receiving a byte on side A, but before sending the next data on side A, send more.

Thus, there will be a mismatch, and I do not understand how to control him on the side of A.

For the sake of simplicity, we can assume that A sends data and B sends confirmation that it is a one-way data sending channel.

For example, how is this problem solved in protocols such as SIP? How is it controlled that the answer came precisely from "ACK", and not from "ACK ^ 53"?

I hope I managed to describe the essence of the problem quite clearly.

  • one
    You can expect not just one byte, but some kind of ID (for example, crc32 sent by A side of the message). - zed
  • I understand. Most protocols generally work on top of TCP in text mode, the same SIP, for example. But this problem will not solve. It will come to us in response to "OK" or even "OK" + the hash sum of the received data ... There may be something else in the buffer. How to control this? - user294535
  • one
    As soon as side A sees that there is rubbish or something extra in the buffer, it should inform side B about the error and close the connection, without waiting for any more confirmation. - zed
  • That is, it is usually done this way? And I thought it was my bike, and there is a better solution. Thank! - user294535

1 answer 1

Strict solution to the problem:

  1. Add two fields to the protocol header that you impose on TCP: message ID and CRC32
  2. The sending party, after transmitting the data packet, enters its ID, CRC32 and the time of sending the packet to the list of sent messages
  3. The receiving party, having received the data packet, retains the data, and sends the header with the ID and CRC32 back
  4. The sender, having received confirmation, deletes this packet from the list of sent ones.
  5. At the same time, the sender checks whether the list of sent packets that did not receive a confirmation after a timeout has occurred. Such packets are retransmitted.
  • I do, but the problem is slightly different: how to control the size of the incoming data? Suppose we send the data and wait for confirmation, let's say the confirmation size is 100 bytes. We are waiting, no matter how - blocking recv (..., ..., 100, ...); or select () in the + recv () loop until the expected 100 bytes arrive. After we have received 100 bytes - some data may remain in the receiving buffer, which should not be there if properly exchanged. And so the next time you send data and wait for a response, this data will have an impact. - user294535
  • some data may remain in the receive buffer. If you have a select in a loop, then by taking your 100 bytes, you return to select and find that there is data in the receive socket. What problems could there be - I don’t really understand ... - Sergey
  • The problem is that the data remaining in the receive buffer can at least interfere with the processing of the next acknowledgment. As a maximum - holes in the logic of the protocol. In my case, this, undoubtedly, will not lead to big problems, because the logic is very simple. But if the protocol logic is more or less complicated, like, for example, the SIP protocol, then it is very difficult to predict what will happen if the other party deliberately starts sending not what is expected. So I'm trying to figure out how to solve this problem. - user294535
  • one
    Those. in fact, you are interested in how to SEPARATE one message from another. Well, there are only two standard methods: 1. Messages of exactly defined length, as in UDP. There the driver will tell you the actual length of the message. 2. Use the message delimiter character. For example - two blank lines. - Sergey