Backend Development 17 min read

Understanding Network Protocols, TCP/UDP Handshakes, Socket Long Connections, and Socket Connection Pools

This article explains the fundamentals of network protocols—including the OSI model, TCP three‑way handshake and four‑way termination, UDP characteristics, long versus short socket connections, custom application‑layer protocols, and how to implement a reusable socket connection pool in Node.js.

Architect's Guide
Architect's Guide
Architect's Guide
Understanding Network Protocols, TCP/UDP Handshakes, Socket Long Connections, and Socket Connection Pools

As developers we often encounter terms such as HTTP, TCP/IP, UDP, Socket, long‑living Socket connections, and Socket connection pools, yet many do not fully understand their relationships, differences, and underlying principles; this article starts from basic network protocol concepts and walks step‑by‑step through to Socket connection pools.

Seven‑Layer Network Model

The OSI (Open System Interconnection) model divides network communication into seven layers from bottom to top: Physical, Data Link, Network, Transport, Session, Presentation, and Application. The accompanying diagram maps common protocols and hardware to each layer, showing that IP belongs to the Network layer, TCP/UDP to the Transport layer, and HTTP to the Application layer.

While OSI does not define Socket, the later sections will introduce Socket in detail together with code examples.

TCP and UDP Connections

TCP is connection‑oriented and reliable, requiring a three‑way handshake to establish a connection and a four‑step termination to close it; UDP is connection‑less, faster, and does not guarantee delivery.

TCP Three‑Way Handshake

First handshake: Client sends SYN (sequence number x) and enters SYN_SEND state.

Second handshake: Server replies with SYN+ACK (acknowledgment x+1, its own SYN with sequence y) and enters SYN_RECV state.

Third handshake: Client sends ACK (acknowledgment y+1) and both sides move to ESTABLISHED state.

TCP Four‑Way Termination

First termination: Host 1 sends FIN and enters FIN_WAIT_1.

Second termination: Host 2 acknowledges with ACK, moving Host 1 to FIN_WAIT_2.

Third termination: Host 2 sends its own FIN, entering LAST_ACK.

Fourth termination: Host 1 acknowledges with ACK and enters TIME_WAIT; after 2 MSL the connection closes.

TCP requires at least seven message exchanges for a complete request‑response cycle, while UDP needs only the data packet.

Differences Between TCP and UDP

TCP is connection‑oriented and provides reliability through handshakes and acknowledgments; UDP is connection‑less and does not guarantee delivery, making it faster but less reliable.

Because UDP avoids the overhead of handshakes, its transmission latency is lower, which is why protocols such as DNS or real‑time media often prefer UDP.

Common Questions About the Transport Layer

1. Maximum concurrent TCP connections? The limit is not the 65 535 port range; a single server port can handle far more connections, limited mainly by the OS file‑descriptor limit (ulimit -n) and system resources.

2. Why does TIME_WAIT wait for 2 MSL before moving to CLOSED? To ensure any lost ACK can be retransmitted; the waiting period protects against delayed packets that might otherwise be misinterpreted as belonging to a new connection.

3. Problems caused by many TIME_WAIT sockets? Each TIME_WAIT consumes a local port; heavy short‑connection traffic can exhaust the port range, leading to “address already in use” errors. Adjusting kernel parameters (e.g., tcp_tw_reuse, tcp_tw_recycle) can mitigate the issue.

To apply kernel tweaks, edit /etc/sysctl.conf (or a dedicated file) and run /sbin/sysctl -p :

net.ipv4.tcp_syncookies = 1  # enable SYN cookies

net.ipv4.tcp_tw_reuse = 1 # allow reuse of TIME_WAIT sockets

net.ipv4.tcp_tw_recycle = 1 # fast recycle of TIME_WAIT sockets

net.ipv4.tcp_fin_timeout = value # adjust FIN timeout

Socket Long Connections vs. Short Connections

A long connection keeps a TCP socket open for multiple data exchanges, often using heartbeat packets to detect liveness; a short connection is created, used for a single request, then closed.

Typical flow for short connections: connect → data transfer → close . For long connections: connect → data transfer → heartbeat → data transfer → … → close .

Long connections are preferred when operations are frequent and the number of concurrent connections is manageable, such as database connections, because they avoid the overhead of repeated handshakes.

Heartbeat Packets

Heartbeat packets are periodic messages sent by client and server to confirm that the socket is still alive; they can be custom structures or rely on TCP’s built‑in keep‑alive mechanism.

Defining a Custom Application‑Layer Protocol

To give transmitted data meaning, an application‑layer protocol (e.g., HTTP, MQTT, Dubbo) is needed. A custom protocol built on TCP typically defines:

Heartbeat packet format and handling.

Message header that includes the payload length (e.g., length:000000000xxxx ).

Serialization format (commonly JSON).

Example header definition: length:000000000xxxx where the total header length is 20 bytes.

Socket Connection Pool

A Socket connection pool maintains a collection of reusable long‑living sockets, automatically checks their health, discards invalid ones, and creates new sockets as needed. The pool typically tracks:

Idle (available) long connections.

Active (in‑use) long connections.

Pending requests waiting for a free connection.

Mechanisms for removing invalid connections.

Configuration of the pool size.

Logic for creating new connections.

When a request arrives, the pool provides an idle socket; if none are available and the active count is below the configured limit, a new socket is created; otherwise the request is queued.

Node.js Generic‑Pool Example

The following images illustrate the directory structure, pool initialization, and usage with the custom protocol defined earlier.

Initializing the Pool

Using the Pool

The pool is used with the previously defined custom protocol.

Log output shows that the first two requests create new sockets; subsequent requests reuse existing sockets from the pool.

Source Code Analysis

The core implementation resides in lib/Pool.js . The constructor sets up queues for idle, active, and waiting resources.

The acquire method (shown in the following screenshots) handles the logic of retrieving an idle socket, creating a new one if needed, or queuing the request when the pool is exhausted.

Further code details can be explored by reviewing the full source.

backend developmentConnection PoolTCPSocketnetwork protocolUDP
Architect's Guide
Written by

Architect's Guide

Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.

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.