TCP Reliable Transmission Mechanisms and Implementation Details
This article explains how TCP ensures reliable data transfer through connection management, sequence and acknowledgment mechanisms, retransmission strategies, flow control, and congestion control, and includes C++ example code illustrating a simple client‑server file transfer implementation.
1. TCP Reliable Transmission
1.1 Overview
TCP (Transmission Control Protocol) is a connection‑oriented, reliable, byte‑stream transport‑layer protocol defined by IETF RFC 793. It provides reliable communication services for paired processes on different hosts across a network.
1.2 Working Principle
Because the underlying IP layer offers only best‑effort delivery, TCP adds mechanisms such as three‑way handshake for connection establishment, four‑way handshake for termination, sliding‑window flow control, and various retransmission strategies to guarantee that data sent by the sender is correctly received by the receiver without loss, duplication, or reordering.
Key mechanisms include:
Stop‑and‑wait protocol
Go‑back‑N (backward N‑frame) protocol
Selective repeat protocol
Ideal transmission conditions assume a perfect channel and unlimited processing speed at the receiver; real networks require the above protocols to achieve reliability.
1.3 Stop‑and‑Wait Details
The sender transmits one segment and waits for an ACK or NAK. If a timeout expires before an acknowledgment arrives, the segment is retransmitted. Sequence numbers (often a single bit) distinguish new data from retransmissions.
1.4 Impact of ACK Loss and Delay
Lost ACKs cause unnecessary retransmissions, reducing channel utilization. Delayed ACKs can be mistaken for new data acknowledgments, leading to confusion unless ACKs are also numbered.
2. Key Mechanisms
2.1 Connection Management
TCP establishes connections with a three‑way handshake (SYN, SYN‑ACK, ACK) and terminates them with a four‑way handshake (FIN, ACK, FIN, ACK). The handshake synchronizes initial sequence numbers and confirms that both ends are ready to send and receive.
State diagram highlights states such as LISTEN, SYN_SENT, SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, TIME_WAIT, CLOSE_WAIT, LAST_ACK, and CLOSED.
2.2 Sequence Number and Acknowledgment
Each byte in a TCP stream is assigned a sequence number. The receiver acknowledges the next expected byte number, enabling the sender to detect loss and perform retransmission.
Data fragmentation and reassembly: sequence numbers allow the receiver to reorder segments correctly.
Reliability: mismatched sequence numbers trigger retransmission.
Flow‑control assistance: combined with the advertised window size, they regulate the sender’s rate.
2.3 Retransmission Mechanisms
TCP uses timeout‑based retransmission (RTO) and fast retransmission. RTO is computed from smoothed RTT (SRTT) and RTT variance (RTTVAR) using the formula:
srtt = (1‑g) * srtt + g * M
rttvar = (1‑h) * rttvar + h * (|M| - srtt)
RTO = srtt + 4 * rttvarFast retransmission is triggered after receiving three duplicate ACKs, indicating a likely lost segment without waiting for the timer.
2.4 Flow Control
TCP employs a variable‑size sliding window. The receiver advertises its available buffer (rwnd) in each ACK; the sender limits outstanding data to the minimum of cwnd (congestion window) and rwnd. Zero‑window probes are sent when the receiver’s window is zero.
2.5 Congestion Control
Congestion control prevents the network from being overloaded. TCP maintains a congestion window (cwnd) and adjusts it based on network feedback:
Slow start: cwnd grows exponentially until it reaches the slow‑start threshold (ssthresh).
Congestion avoidance: cwnd grows linearly after ssthresh.
Fast retransmit and fast recovery: on three duplicate ACKs, cwnd is reduced, ssthresh is set to half of the current cwnd, and transmission resumes with linear growth.
3. How TCP Guarantees Reliability
3.1 Reliability Mechanisms Summary
Sequence numbers (32‑bit)
Acknowledgment numbers (ACK, 32‑bit)
Checksum (16‑bit) for error detection
Sliding‑window flow control
Retransmission timeout (RTO)
Congestion control (slow start, congestion avoidance, fast retransmit, fast recovery)
Connection management (three‑way handshake, four‑way termination)
3.2 Flow‑Control Implementation Details
The receiver advertises its window size; the sender adjusts its sending rate accordingly. If the window becomes zero, the sender may send a one‑byte probe to check for window updates.
3.3 Congestion‑Control Algorithms
TCP starts with slow start, switches to congestion avoidance after reaching ssthresh, and reacts to loss events by halving cwnd and re‑entering slow start. Fast retransmit/recovery handle isolated packet loss without waiting for a timeout.
4. Case Study: File Transfer
A simple client‑server file transfer demonstrates the use of the above mechanisms. The client establishes a TCP connection, splits the file into segments, sends each segment with a sequence number, and waits for ACKs. The server acknowledges each segment and writes data to disk. Flow control is exercised via the advertised window, and congestion control adapts the sending rate.
4.1 C++ Example – Server
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
const int PORT = 8888;
const std::string SERVER_IP = "127.0.0.1";
int main() {
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
std::cerr << "Failed to create server socket" << std::endl;
return -1;
}
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP.c_str());
serverAddress.sin_port = htons(PORT);
if (bind(serverSocket, reinterpret_cast
(&serverAddress), sizeof(serverAddress)) < 0) {
std::cerr << "Bind failed" << std::endl;
close(serverSocket);
return -1;
}
if (listen(serverSocket, 10) < 0) {
std::cerr << "Listen failed" << std::endl;
close(serverSocket);
return -1;
}
std::cout << "Server listening on port " << PORT << "..." << std::endl;
int clientSocket = accept(serverSocket, nullptr, nullptr);
if (clientSocket < 0) {
std::cerr << "Accept failed" << std::endl;
close(serverSocket);
return -1;
}
char buffer[1024];
while (true) {
int bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0);
if (bytesRead <= 0) {
std::cerr << "Receive error or client closed" << std::endl;
break;
}
std::cout << "Received: " << buffer << std::endl;
send(clientSocket, "ACK", 3, 0);
}
close(clientSocket);
close(serverSocket);
return 0;
}4.2 C++ Example – Client
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
const int PORT = 8888;
const std::string SERVER_IP = "127.0.0.1";
bool sendDataWithConfirmation(int socket, const char* data, int dataLength) {
int bytesSent = send(socket, data, dataLength, 0);
if (bytesSent < 0) {
std::cerr << "Send failed" << std::endl;
return false;
}
char ackBuffer[4];
int bytesRead = recv(socket, ackBuffer, sizeof(ackBuffer), 0);
if (bytesRead < 0) {
std::cerr << "Receive ACK failed" << std::endl;
return false;
}
if (std::string(ackBuffer, bytesRead) == "ACK") {
std::cout << "Data sent and ACK received" << std::endl;
return true;
} else {
std::cerr << "Incorrect ACK" << std::endl;
return false;
}
}
int main() {
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1) {
std::cerr << "Failed to create client socket" << std::endl;
return -1;
}
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP.c_str());
serverAddress.sin_port = htons(PORT);
if (connect(clientSocket, reinterpret_cast
(&serverAddress), sizeof(serverAddress)) < 0) {
std::cerr << "Connection failed" << std::endl;
close(clientSocket);
return -1;
}
std::string message = "Hello, Server!";
if (!sendDataWithConfirmation(clientSocket, message.c_str(), message.length())) {
std::cerr << "Message send failed" << std::endl;
}
close(clientSocket);
return 0;
}These examples illustrate how the three‑way handshake, sequence numbers, ACKs, and retransmission logic work together to achieve reliable file transfer over TCP.
Deepin Linux
Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.