Recently wrote and launched a client-server system. The system itself is still very primitive, but initially there is a difficulty - it works 24/7/366, and, moreover, it is on the Internet, and not on the local network. Therefore, the requirements for reliability are very strict.
For each message, you must either receive a response from the receiver, or readenBytes = 0, or Exception, which indicates either a normal shutdown (the receiver sent RST) or a break (pulled out a cable, lost Wi-Fi and others)
I used blocking calls.
But realizing the algorithm, I noticed that all his logic comes down to this:
try { tcp.Write(request); } catch { ... } try { var response = tcp.Read(); } catch { ... } Naturally, everything is in one thread: 1 stream on the client, and on the server, too, only 1 stream on 1 client.
What is bad? If the answer just lingers on time - then nothing:
1) write
2) execution has reached read, read has become WAIT
3) N time passed
4) finally the answer came, and then read it counted and left WAIT
It's okay
But think about the possible loss of cable. And imagine this situation:
0) cable in place
1) write was executed. since the cable is in place, then came the ACK and the socket believes that everything is in order
2) execution has reached read, read has become WAIT
3) and then there was a cable break! But write is no longer called because read is still WAIT, as a result the socket will not know that a break has occurred.
I know that write does not block execution, and it is very unlikely that the ACK for write will arrive earlier than read will get into WAIT. During the week there was not a single such incident, although there were cliffs every day. But still, purely theoretically, the computer can slow down and the system will crash.
How to solve this problem, if you use blocking calls, and also do not use keepalive, and instead use your own implementation of heartbeat (it’s also that I have no guarantees of support for keepalive clients and servers)?
setsockopt(,, SO_RCVTIMEO)) suggests itself - Vladimir Gamalyan