Fundamentals 34 min read

Understanding Network Protocols, TCP/UDP, Sockets, and Socket Connection Pools in Node.js

This article explains the OSI seven‑layer model, the differences between TCP and UDP, the mechanics of TCP three‑way handshake and four‑step termination, how sockets work in Node.js, and how to implement custom protocols and a socket connection pool for high‑concurrency applications.

IT Services Circle
IT Services Circle
IT Services Circle
Understanding Network Protocols, TCP/UDP, Sockets, and Socket Connection Pools in Node.js

Seven‑Layer Network Model

The OSI model divides network communication into seven layers: physical, data link, network, transport, session, presentation, and application. IP operates at the network layer, TCP/UDP at the transport layer, and HTTP at the application layer.

TCP and UDP Connections

TCP provides reliable, connection‑oriented communication using a three‑way handshake (SYN, SYN‑ACK, ACK) and a four‑step termination (FIN, ACK, FIN, ACK). UDP is connection‑less, faster, but does not guarantee delivery.

Key differences:

TCP is reliable and ordered; UDP is unreliable and unordered.

TCP incurs higher overhead due to handshakes and acknowledgments; UDP has lower latency.

Common TCP Questions

1. Maximum concurrent TCP connections : Not limited by port numbers; limited by system resources such as the maximum number of open file descriptors (ulimit -n) and kernel parameters.

2. TIME_WAIT duration : The socket stays in TIME_WAIT for 2 MSL to retransmit any lost ACKs and ensure the remote side has closed the connection.

3. TIME_WAIT impact : Excessive TIME_WAIT sockets can exhaust local ports, causing "address already in use" errors. Tuning sysctl parameters (e.g., net.ipv4.tcp_tw_reuse, net.ipv4.tcp_tw_recycle, net.ipv4.tcp_fin_timeout) can mitigate the issue.

HTTP Protocol

HTTP is an application‑layer protocol that runs over TCP. It is typically short‑lived: a client opens a TCP connection, sends a request, receives a response, and closes the connection. Persistent connections require periodic keep‑alive messages.

Sockets (套接字)

Sockets provide a programming interface to the TCP/IP stack. In Node.js, the net module offers functions such as createServer, listen, connect, write, and event listeners for data, end, and error.

const net = require('net');
const server = net.createServer();
server.on('connection', (client) => {
  client.write('Hi!
');
});
server.listen(9000);

Clients can communicate with the server using curl or telnet:

$ curl http://127.0.0.1:9000
Bye!

Heartbeat and Long Connections

A heartbeat packet is a periodic message that confirms the connection is still alive. Implementing heartbeats prevents silent disconnections.

const heartbeat = 'HEARTBEAT';
setInterval(() => client.write(heartbeat), 10000);

Defining a Custom Protocol

To send structured data, a simple protocol can prepend a fixed‑length header indicating payload size, followed by a JSON payload.

function getHeader(num) {
  return 'length:' + ('0000000000000' + num).slice(-13);
}
client.write(getHeader(data.length));
client.write(data);

Socket Connection Pool

A socket connection pool maintains a set of long‑lived TCP connections, reusing them for multiple requests to avoid the overhead of repeatedly creating sockets. The pool tracks idle, active, and waiting connections, validates sockets before reuse, and discards invalid ones.

Key components:

Idle connection queue

Active connection queue

Waiting request queue

Invalid‑connection removal

Configurable pool size

Using generic‑pool

const genericPool = require('generic-pool');
function createPool({host, port, options}) {
  const factory = {
    create: () => new Promise((resolve, reject) => {
      const socket = new net.Socket();
      socket.connect(port, host, () => resolve(socket));
      socket.on('error', reject);
    }),
    destroy: (socket) => new Promise((resolve) => {
      socket.destroy();
      resolve();
    }),
    validate: (socket) => Promise.resolve(!socket.destroyed && socket.readable && socket.writable)
  };
  return genericPool.createPool(factory, options);
}

const pool = createPool({host: '127.0.0.1', port: 9000, options: {min: 0, max: 10}});

Acquiring a socket, sending a request, and releasing it back to the pool:

async function request(dataBuff) {
  const client = await pool.acquire();
  client.setTimeout(10000);
  client.write(getHeader(dataBuff.length));
  client.write(dataBuff);
  // handle response, then:
  pool.release(client);
}

Logs show that the first two requests create new sockets, while subsequent requests reuse existing connections from the pool.

Source Code Overview

The generic-pool library’s lib/Pool.js implements the pool logic, managing resource creation, validation, dispatch, and eviction.

Key methods include acquire() (queues a request), _dispense() (creates or validates resources), and _dispatchResource() (assigns an available socket to a waiting client).

Understanding these mechanisms helps developers build efficient, high‑concurrency network services.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Node.jsnetworkConnection PoolTCPprotocolSocket
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

0 followers
Reader feedback

How this landed with the community

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.