When designing application protocols and writing network code, we need to be careful to prevent a deadlock state. A deadlock is when both sides on a connection are waiting for the other side to do something. The worst-case scenario is when both sides end up waiting indefinitely.
A trivial example of a deadlock is if both the client and server call recv() immediately after the connection is established. In that case, both sides wait forever for data that is never going to come.
A less obvious deadlock situation can happen if both parties try to send data at the same time. Before we can consider this situation, we must first understand a few more details of how TCP connections operate.
When data is sent ...