Understanding TCP Protocol and Its Implementation

TCP Overview

The Transmission Control Protocol (TCP) is a reliable, connection-oriented protocol operating at the transport layer. Defined by IETF's RFC 793, TCP ensures data integrity through sequencing, acknowledgment, and retransmission mechanisms.

Communication using TCP requires three stages: establishing a connection, transferring data, and terminating the connection.

Key Characteristics of TCP

Connection-Oriented Nature

Before data transfer begins, both parties must establish a communication channel. This is analogous to making a phone call before exchanging information. Each connection involves allocating system resources for managing state and transmission.

Once established, all data exchanges occur over this single channel. After communication completes, the connection must be closed to free up system resources. TCP supports one-to-one connections exclusively, making it unsuitable for broadcast scenarios which prefer UDP.

Byte Stream Based

Data Handling in TCP

When an application writes multiple times to a TCP socket, these bytes are queued into a send buffer. The TCP stack then packages them into segments based on network constraints like MTU limits.

Segments sent may not correspond directly to write operations. Similarly, received segments can be read in chunks depending on the application's receive buffer size.

Comparison with UDP

In contrast, UDP sends each write operation as a single datagram. If a datagram is too large for the link layer, it will be fragmented at the IP level. Also, missing datagrams are discarded unless explicitly handled by the application.

Reliability Mechanisms

  1. Acknowledgement System: Every segment must be acknowledged before being considered successfully transmitted.

  2. Retransmission Timeout: If no ACK arrives within a timeout period, the segment is resent.

  3. Error Checking: A checksum validates data integrity during transmission.

  4. Flow Control and Congestion Avoidance: Prevents sender from overwhelming receiver with data faster than it can process.

TCP vs UDP

Feature TCP UDP
Connection Required Not required
Ordering Guaranteed No order guarantee
Reliability Reliable Unreliable
Overhead Higher Lower
Use Case Applications requiring delivery assurance

Three-Way Handshake

TCP establishes a connection using a three-step handshake:

  1. Client → Server: SYN packet with initial sequence number (e.g., 1000).
  2. Server → Client: SYN+ACK packet acknowledging client’s SYN and sending its own initial sequence number (e.g., 8000).
  3. Client → Server: ACK packet confirming server’s SYN.

During this process, both sides exchange sequence numbers and maximum segment sizes.

If a host receives a SYN for a non-existent port, it responds with a RST packet indicating refusal.

Data Transfer Process

After connection establishment:

  1. Client sends data starting from sequence number 1001.
  2. Server acknowledges receipt and sends back data starting from sequence number 8001.
  3. Client confirms server’s data and requests further transmission.

Each segment includes sequence numbers and acknowledgments ensuring ordered delivery.

Four-Way Handshake for Termination

Since TCP supports full-duplex communication, each direction needs independent closure:

  1. Client → Server: FIN flag signals termination request.
  2. Server → Client: ACK confirms receipt of FIN.
  3. Server → Client: FIN flag initiates server-side shutdown.
  4. Client → Server: ACK confirms server’s FIN.

This allows half-closed states where one side can still send while the other has stopped.

Implementation Examples

Basic TCP Server

import socket

# Create socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind address
server_socket.bind(('', 8000))

# Listen for connections
server_socket.listen(128)

# Accept client connection
client_socket, client_address = server_socket.accept()
print(f"Connected to {client_address}")

# Receive data
received = client_socket.recv(1024)
print(f"Received: {received.decode()}")

# Send response
client_socket.send("Thank you!\n".encode())

# Close connections
client_socket.close()
server_socket.close()

Basic TCP Client

import socket

# Create client socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to server
client_socket.connect(('127.0.0.1', 8000))

# Send message
message = input("Enter message: ")
client_socket.send(message.encode())

# Receive response
response = client_socket.recv(1024)
print(f"Server response: {response.decode()}")

# Close connection
client_socket.close()

Connection States

  • CLOSED: Initial state
  • LISTEN: Waiting for incoming connections
  • SYN_SENT: Sent SYN, waiting for ACK+SYN
  • SYN_RCVD: Received SYN, sent ACK+SYN
  • ESTABLISHED: Connection ready
  • FIN_WAIT_1: Sent FIN, waiting for ACK
  • FIN_WAIT_2: Sent ACK, waiting for FIN
  • TIME_WAIT: Waited for final ACK
  • CLOSE_WAIT: Received FIN, waiting to close
  • LAST_ACK: Final ACK being sent
  • CLOSING: Both sides closing simultaneously

TIME_WAIT Considerations

The TIME_WAIT state lasts for twice the Maximum Segment Lifetime (2MSL). It prevents:

  1. Retransmitted segments from interfering with new connections.
  2. Lost duplicate packets causing confusion in new connections.

To avoid issues with server ports in TIME_WAIT, set SO_REUSEADDR option:

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

Long vs Short Connections

Short Connection

Each operation involves:

  1. Establishing connection
  2. Sending/receiving data
  3. Closing connection

Best for infrequent communications due to overhead.

Long Connection

  1. Establish connection once
  2. Multiple data exchanges
  3. Close when done

Ideal for frequent interactions where setup costs outweigh benefits.

Applications typically use long connections for database connections and short ones for web services.

Tags: tcp networking protocol socket connection

Posted on Sun, 01 Nov 2026 16:41:42 +0000 by rotarypot