Understanding Network Protocols, TCP/UDP Handshakes, Socket Connections, and Socket Connection Pools
This article explains the OSI seven‑layer model, the mechanics of TCP three‑way handshakes and four‑way teardowns, differences between TCP and UDP, long‑ versus short‑lived socket connections, custom protocol design, and how to implement a socket connection pool using Node.js.
Introduction
Developers often encounter terms such as HTTP, TCP/IP, UDP, Socket, long‑lived Socket connections, and Socket connection pools, but the relationships, differences, and underlying principles are not always clear. This article starts from basic network protocol concepts and gradually explains each topic.
OSI Seven‑Layer Model
The OSI (Open System Interconnection) model divides network communication into seven layers: Physical, Data Link, Network, Transport, Session, Presentation, and Application. The diagram below maps common protocols and hardware to each layer.
From the diagram, IP belongs to the Network layer, TCP/UDP to the Transport layer, and HTTP to the Application layer. OSI does not define Socket; its details will be introduced later 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. UDP is connection‑less, faster, but 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 reach ESTABLISHED state.
Four‑Step TCP Teardown
First step: Host1 sends FIN and enters FIN_WAIT_1.
Second step: Host2 acknowledges with ACK, entering FIN_WAIT_2.
Third step: Host2 sends its own FIN, entering LAST_ACK.
Fourth step: Host1 acknowledges with ACK and enters TIME_WAIT; after 2 MSL the connection closes.
Thus a full TCP exchange involves at least seven messages, while UDP requires no handshake.
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.
Because UDP lacks the overhead of handshakes, it has lower latency and higher throughput, making it suitable for real‑time applications, though additional application‑level verification may be needed.
Common Questions
1. Maximum concurrent TCP connections? The limit is not the 65 535 port range; a server can handle many more connections limited by the OS file‑descriptor limit (ulimit -n) and system resources.
2. Why does TIME_WAIT wait for 2 MSL? To ensure any lost ACK can be retransmitted; the waiting period protects against stray packets causing confusion for future connections.
3. Problems caused by many TIME_WAIT sockets? Each TIME_WAIT consumes a local port; heavy short‑connection traffic can exhaust ports, leading to “address already in use” errors. Adjusting kernel parameters (e.g., tcp_tw_reuse, tcp_tw_recycle) can mitigate the issue.
Long‑Lived vs Short‑Lived Socket Connections
A long‑lived connection keeps a TCP socket open for multiple data exchanges, often using heartbeat packets to detect liveness. A short‑lived connection is created for a single request/response cycle and then closed.
Long connections are beneficial when operations are frequent and the overhead of repeated handshakes would degrade performance (e.g., database connections). Short connections are simpler but can waste resources under high request rates.
Heartbeat Packets
Heartbeat packets are periodic messages sent between client and server to confirm that the socket is still alive. TCP already provides a keep‑alive mechanism, but custom heartbeats can be defined to suit specific protocols.
Defining a Custom Application‑Layer Protocol
To give transmitted data meaning, an application‑layer protocol such as HTTP, MQTT, or Dubbo is used. When building a custom protocol on top of TCP, you need to define:
Heartbeat packet format.
Message header that includes the payload length.
Data serialization format (e.g., JSON).
Example header: length:000000000xxxx where xxxx is the data length (total header length 20 bytes).
Socket Connection Pool
A socket connection pool maintains a collection of reusable long‑lived sockets, automatically detecting and discarding invalid connections and creating new ones as needed. The pool typically tracks:
Idle connections queue.
Active connections queue.
Waiting request queue.
Invalid‑connection removal.
Pool size configuration.
Connection creation logic.
When a request arrives, the pool provides an idle socket; if none are available and the pool has not reached its maximum size, a new socket is created; otherwise the request waits.
Node.js’s generic‑pool module can be used to implement such a pool. The following images show the directory structure and initialization steps.
Initializing the Pool
Using the Pool with a 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 defines queues for idle, active, and waiting resources.
The acquire method contains the logic for retrieving or creating a socket, handling all edge cases until a long‑lived connection is obtained.
Further details can be explored by reviewing the full source code.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
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.