In this section we will investigate one aspect of a connection-oriented protocol protocol like TCP, which is how a continuous data stream is transmitted from one side to the other. The complicated issues of starting and ending the connection require whole sections of their own and are not addressed herein. Also, we will focus on the situation where one side is the primary sender and the other is the primary receiver, although packets can and must flow in both directions. The transfer of a single file from one computer to another is an example of this type of transmission.
First, the sender, S, breaks the file into more or less equal sized chunks and encapsulates them into a packet. It also attaches sequence numbers to these chunks, usually starting with 0 or 1, so that the receiver can discover what order they should be in. Fig. 23.8.1 shows the transmission of the file if everything goes okay.
Fig. 23.8.1: Transmission of a reliable bit or byte stream over a
connection oriented protocol
But things do not always go okay. Sometimes packets are altered en route, which the receiver, R, can detect by recomputing the checksum and comparing it to what was sent in the packet. If the packet is damaged, R must request a retransmission of that packet, which it does by sending a NAK (negative acknowledgment) packet with the sequence number of the altered packet. The sender, S, then retransmits that packet and continues with the other packets, as shown in Fig. 23.8.2.
Fig. 23.8.2: NAK triggers retransmission of an earlier packet
An even worse thing can happen if the NAK is altered or even lost altogether. The receiver can only discover this if it sets a timer when it sends the NAK and if the new packet doesn't arrive before the timer goes off, it must resend the NAK.
The complications do not stop here, but in fact get thornier. Suppose that S keeps sending packets while R is waiting for the earlier packet. R is supposed to deliver a seamless bit stream up to the final destination process, all the bytes exactly in the order that the sender sends them. But memory is always limited and if S keeps sending packets, R is supposed to buffer them up but not deliver them to its upper level, because it must wait for the earlier packet to be retransmitted. Thus, R must have a way of yelling STOP! to the S. This is called flow control and is always a part of connection-oriented protocols. Otherwise, R will have to just ignore the incoming packets which causes S to waste its time and unnecessarily tie up the wire sending packets that will only have to be resent later.
An easy way to combine both flow control and retransmission requests is to have R always send a packet stating whether it received the packet or not. If the packet arrived okay, R sends an ACK with the sequence number back to S. If the packet arrives but is corrupted by a transmission error, R sends a NAK with the sequence number, as discussed earlier. If the packet never arrives at R, S must have a timer of its own and it must resend the packet or even back up to an earlier point in the bit stream and resend all packets from that point on. Fig. 23.8.3 shows the stream of packets and ACKs and NAKs.
Sending an ACK for every single packet will cause unnecessary traffic on the wire so many protocols, including TCP, arrange to send an ACK every so many packets. When S receives a message like "ACK 7", it knows that R received every packet from 0 up to and including 7. Separate ACKs for 4, 5 and 6 are not necessary.
Sometimes the packets arrive, but much later than expected. This almost never happens on local area networks but can happen on the Internet where packets travel through thousands of gateways and where routes constantly shift to accommodate changes in load. If R gets two packets with the same sequence number, it must keep only one of them, or else it will incorrectly duplicate some of the bits in the bit stream. But it should ACK every packet or else S may think that packet is never getting through and it will keep resending it. It is up to R to correctly piece together all the arriving packets in the sequence that S originally sent them and not to duplicate any part of it.
Fig. 23.8.4 gives a taste of how complicated this is. Notice that packet 3 was destroyed in transit so the receiver must send a NAK back to the sender, requesting a retransmission. Also notice that packet 4 was sent out of order, after packets 5 and 6. In order to conserve time on the wire, the receiver is asked to piece together a coherent data stream from all these bits and pieces.
Fig. 23.8.4: R's onerous task of reconstructing the exact same bit
stream as was transmitted
By now you should be awed by the tasks that connection-oriented protocols must perform in order to do something as conceptually simple as getting a single sequence of bits from point A to point B. Networking is like this; what seems trivially simple turns out to be horrendously complicated.