Fundamentals 42 min read

TCP Protocol: Overview, Mechanisms, and Practical Usage

This article provides a comprehensive English guide to the Transmission Control Protocol (TCP), covering its connection‑oriented design, reliability features, packet structure, three‑way handshake, data transfer process, flow and congestion control, four‑step termination, and example C++ socket code for establishing, sending, receiving, and closing TCP connections.

Deepin Linux
Deepin Linux
Deepin Linux
TCP Protocol: Overview, Mechanisms, and Practical Usage

1. TCP Protocol Overview

TCP (Transmission Control Protocol) is a connection‑oriented, reliable, byte‑stream transport‑layer protocol. It ensures ordered, error‑free delivery of data between a sender and a receiver using mechanisms such as sequence numbers, acknowledgments, retransmission, flow control, and congestion control.

1.1 History

TCP originated in the late 1960s with the ARPANET project. Vinton Cerf and Robert Kahn published the TCP/IP specification in 1974, and the protocol became the core of the Internet on January 1, 1983.

1.2 Main Characteristics

Connection‑oriented: a connection must be established before data transfer.

Reliability: uses acknowledgments, retransmission, and checksums.

Ordered delivery: sequence numbers guarantee correct order.

Flow control: sliding‑window mechanism prevents the sender from overwhelming the receiver.

Congestion control: algorithms adjust the sending rate based on network conditions.

1.3 Common Questions

What is a connection‑oriented protocol? Both ends establish a session (handshake) before exchanging data.

What makes a protocol reliable? It detects and corrects errors, retransmits lost packets, and ensures in‑order delivery.

What does “byte‑stream” mean? Data is treated as a continuous stream of bytes without inherent message boundaries; length or delimiter fields are used to separate messages.

2. TCP Working Principles

2.1 Packet Format

A TCP segment consists of a header and optional data. Key header fields include:

Source and destination ports (identify application processes).

Sequence number and acknowledgment number (reliability).

Data offset (header length).

Reserved bits.

Control flags: URG, ACK, PSH, RST, SYN, FIN.

Window size (flow control).

Checksum (error detection).

Urgent pointer.

Options and padding.

Data payload (optional).

1、Port numbers: identify different application processes on the same host.
1) Source port: together with source IP, it specifies the return address.
2) Destination port: indicates the receiving application’s interface.
1) URG: urgent pointer valid when set to 1.
2) ACK: acknowledgment number valid when set to 1.
3) PSH: push function – deliver data to the application immediately.
4) RST: reset the connection.
5) SYN: synchronize sequence numbers (connection establishment).
6) FIN: finish – close the connection.

2.2 Three‑Way Handshake

The handshake establishes a reliable connection in three steps:

Client sends SYN with initial sequence number x .

Server replies with SYN‑ACK, acknowledging x+1 and providing its own sequence number y .

Client sends ACK acknowledging y+1 . Both sides enter the ESTABLISHED state.

The three‑step process guarantees that both parties can send and receive data.

2.3 Data Transmission

Data is placed in the application’s write buffer, segmented into TCP segments, and sent. The receiver stores incoming segments in its receive buffer, acknowledges them, and delivers ordered data to the application.

2.4 Four‑Way Termination

Connection teardown uses four messages:

Client sends FIN, entering FIN‑WAIT‑1.

Server acknowledges with ACK, entering CLOSE‑WAIT.

Server sends its own FIN, entering LAST‑ACK.

Client acknowledges the server’s FIN, enters TIME‑WAIT, then closes.

The extra step ensures both sides have confirmed the closure.

3. Using TCP in C++

3.1 Establishing a Connection

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serverAddress;
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(8000);
    inet_pton(AF_INET, "127.0.0.1", &(serverAddress.sin_addr));
    if (connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
        std::cerr << "Failed to connect to the server." << std::endl;
        return -1;
    }
    // ... use the socket ...
    close(clientSocket);
    return 0;
}

3.2 Sending Data

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    // set up serverAddress as above
    if (connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
        std::cerr << "Failed to connect to the server." << std::endl;
        return -1;
    }
    const char* message = "Hello, server!";
    if (send(clientSocket, message, strlen(message), 0) < 0) {
        std::cerr << "Failed to send data to the server." << std::endl;
        return -1;
    }
    close(clientSocket);
    return 0;
}

3.3 Receiving Data

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8000);
    inet_pton(AF_INET, "127.0.0.1", &(serverAddr.sin_addr));
    connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
    char buffer[1024];
    ssize_t bytesRead = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
    if (bytesRead > 0) {
        buffer[bytesRead] = '\0';
        std::cout << "Received data: " << buffer << std::endl;
    }
    close(sockfd);
    return 0;
}

3.4 Closing the Connection

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    // set up serverAddr and connect as shown earlier
    // ... perform communication ...
    close(sockfd);
    return 0;
}

4. Reliable Transmission Features of TCP

4.1 Sequence Numbers and Acknowledgments

Each byte is assigned a sequence number; the receiver acknowledges the next expected number, allowing the sender to know which data has been successfully received.

4.2 Retransmission Timeout

If an ACK is not received within the calculated RTO, the sender retransmits the segment. The RTO adapts to measured round‑trip times.

4.3 Flow Control (Sliding Window)

The receiver advertises a window size indicating how much data it can accept. The sender limits its transmission to this window, preventing buffer overflow.

4.4 Congestion Control

TCP employs algorithms such as Slow Start, Congestion Avoidance, Fast Retransmit, and Fast Recovery to adjust the congestion window based on network feedback, avoiding network collapse.

5. Common Application Scenarios

5.1 Web Browsing (HTTP/HTTPS)

Browsers establish TCP connections to web servers, request pages via HTTP/HTTPS, and rely on TCP’s reliability and flow/congestion control to deliver HTML, images, and video smoothly.

5.2 Email (SMTP, POP3, IMAP)

Mail clients use TCP to communicate with mail servers for sending (SMTP) and retrieving (POP3/IMAP) messages, ensuring that email content and attachments arrive intact.

5.3 File Transfer (FTP, SFTP)

File‑transfer protocols run over TCP, guaranteeing that large files are transferred without loss or corruption.

TCPreliabilitythree-way handshakeflow controlnetwork protocolcongestion controlC++ Socket
Deepin Linux
Written by

Deepin Linux

Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.