bugl
bugl
HomeLearnPatternsSearch
HomeLearnPatternsSearch

Loading lesson path

Learn/Node.js/Node.js Reference
Node.js•Node.js Reference

Node.js Socket Reference

Concept visual

Node.js Socket Reference

Pointer walk
two pointers
leftright102132436485116
left=0
right=6
1
3

Start at both ends

Socket Object

The Socket class is a duplex stream that allows for reading and writing data across network connections. It is used for both client and server connections in Node.js's net module. A Socket represents a TCP or IPC connection to a remote endpoint, providing methods and events for managing the connection lifecycle and transferring data.

Import Net Module

// Import the net module const net = require('net');
// Create a Socket const socket = new net.Socket();

Socket Properties

Property

Description socket.bufferSize The number of bytes in the write buffer that have not yet been sent. socket.bytesRead The number of bytes received by the socket. socket.bytesWritten The number of bytes sent by the socket. socket.connecting Boolean indicating if the socket is connecting. socket.destroyed Boolean indicating if the socket has been destroyed. socket.localAddress The local IP address of the socket. socket.localPort The local port of the socket. socket.remoteAddress The remote IP address of the socket. socket.remoteFamily The IP family of the remote socket (e.g., 'IPv4' or 'IPv6'). socket.remotePort The remote port of the socket.

Socket Methods

Method

Description socket.connect(options[, connectListener]) Connects the socket to the specified address and port. options can include port, host, localAddress, localPort, and more. socket.connect(path[, connectListener]) Connects the socket to the specified IPC path. socket.connect(port[, host][, connectListener]) Connects the socket to the specified port and host. socket.destroy([error]) Destroys the socket. If error is provided, it will be emitted in an 'error' event. socket.end([data][, encoding][, callback]) Sends optional data and closes the socket, indicating no more data will be sent. socket.pause() Pauses the reading of data, allowing buffering of incoming data. socket.resume() Resumes reading data after a call to socket.pause(). socket.setEncoding([encoding]) Sets the socket to encode data in the specified encoding (default is null, which means Buffer objects are returned). socket.setKeepAlive([enable][, initialDelay])

Formula

Enables/disables keep - alive functionality with optional initialDelay in milliseconds.

socket.setNoDelay([noDelay])

Formula

Enables/disables Nagle's algorithm. When set to true, data is sent immediately rather than buffered.

socket.setTimeout(timeout[, callback]) Sets a timeout for the socket after which a 'timeout' event will be emitted if there's no activity. socket.write(data[, encoding][, callback]) Writes data to the socket. Returns true if data was flushed, or false if it was buffered.

Socket Events

Event

Description

'close' Emitted when the socket is fully closed. The argument hadError indicates if the socket was closed due to an error. 'connect' Emitted when a socket connection is successfully established. 'data' Emitted when data is received. The argument is the received data (Buffer or String). 'drain' Emitted when the write buffer becomes empty. 'end' Emitted when the other end of the socket signals the end of transmission. 'error' Emitted when an error occurs. The 'close' event will be emitted directly after this event. 'lookup' Emitted after resolving the hostname but before connecting. Includes details about the lookup. 'ready' Emitted when a socket is ready to be used. 'timeout'

Formula

Emitted if the socket times out from inactivity. It's just a notification - the socket will not be closed automatically.

Creating a TCP Client

This example shows how to create a TCP client that connects to a server:

const net = require('net');
// Create a new socket const client = new net.Socket();
// Connect to a server client.connect(8080, '127.0.0.1', () => {
console.log('Connected to server');
// Send data to the server client.write('Hello, server! From client.');
});
// Handle data received from the server client.on('data', (data) => {
console.log(`Received from server: ${data.toString()}`);
// Close the connection after receiving a response client.end();
});
// Handle connection closure client.on('close', () => {
console.log('Connection closed');
});
// Handle errors client.on('error', (err) => {
console.error(`Error: ${err.message}`);
});

Creating a TCP Server

This example demonstrates creating a TCP server that handles socket connections:

const net = require('net');
// Create a TCP server const server = net.createServer((socket) => {
// 'socket' is the client connection - an instance of net.Socket console.log(`Client connected: ${socket.remoteAddress}:${socket.remotePort}`);
// Set encoding socket.setEncoding('utf8');
// Handle data from client socket.on('data', (data) => {
console.log(`Received from client: ${data}`);
// Echo the data back to the client socket.write(`You said: ${data}`);
});
// Handle client disconnection socket.on('end', () => {
console.log('Client disconnected');
});
// Handle socket errors socket.on('error', (err) => {
console.error(`Socket error: ${err.message}`);
});
// Send a welcome message to the client socket.write('Welcome to the TCP server!\n');
});
// Start the server on port 8080 server.listen(8080, '127.0.0.1', () => {
console.log('Server listening on port 8080');
});
// Handle server errors server.on('error', (err) => {
console.error(`Server error: ${err.message}`);
});

Socket Timeout

This example demonstrates how to set and handle socket timeouts:

const net = require('net');
// Create a server with timeouts const server = net.createServer((socket) => {
console.log('Client connected');
// Set socket timeout to 10 seconds socket.setTimeout(10000);
// Handle socket timeout socket.on('timeout', () => {
console.log('Socket timeout - no activity for 10 seconds');
socket.write('You have been inactive for too long. The connection will be closed.');
socket.end();
});
// Handle data socket.on('data', (data) => {
console.log(`Received: ${data.toString()}`);
socket.write('Data received');
// Each time we receive data, the timeout is reset console.log('Timeout timer reset');
});
// Handle socket closure socket.on('close', () => {
console.log('Socket closed');
});
// Send welcome message socket.write('Welcome! This connection will timeout after 10 seconds of inactivity.\n');
});
// Start the server const PORT = 8081;
server.listen(PORT, () => {
console.log(`Timeout example server running on port ${PORT}`);

Formula

// For testing: create a client that connects but doesn't send data const client = new net.Socket();
client.connect(PORT, '127.0.0.1', () => {
console.log('Test client connected');
// We'll send a message after 5 seconds (before timeout)
setTimeout(() => {
client.write('Hello after 5 seconds');
}, 5000);
// We won't send anything else, so the connection should timeout

// after another 10 seconds

});
client.on('data', (data) => {
console.log(`Client received: ${data.toString()}`);
});
client.on('close', () => {
console.log('Client disconnected');
});
});

Socket Options

This example shows how to configure various socket options:

const net = require('net');
// Create a socket with options const socket = new net.Socket();
// Configure socket options socket.setKeepAlive(true, 1000); // Enable keep-alive with 1 second initial delay socket.setNoDelay(true); // Disable Nagle's algorithm (no buffering)
// Connect to a server socket.connect({
port: 80, host: 'example.com', family: 4, // IPv4 localAddress: '0.0.0.0', // Local interface to bind to localPort: 8000 // Local port to bind to
}, () => {
console.log('Connected with options');
// Display socket information console.log(`Local address: ${socket.localAddress}:${socket.localPort}`);
console.log(`Remote address: ${socket.remoteAddress}:${socket.remotePort}`);
console.log(`Remote family: ${socket.remoteFamily}`);
// Send a simple HTTP request socket.write('GET / HTTP/1.1\r\n');
socket.write('Host: example.com\r\n');
socket.write('Connection: close\r\n');
socket.write('\r\n');
});
// Handle data let responseData = '';
socket.on('data', (data) => {
const chunk = data.toString();
responseData += chunk;
// Show first line of the response if (responseData.includes('\r\n') && !socket.firstLineShown) {
const firstLine = responseData.split('\r\n')[0];
console.log(`First line of response: ${firstLine}`);
socket.firstLineShown = true;
}
});
// Handle end of data socket.on('end', () => {
console.log('Response complete');
console.log(`Total bytes received: ${socket.bytesRead}`);
console.log(`Total bytes sent: ${socket.bytesWritten}`);
});
// Handle errors socket.on('error', (err) => {
console.error(`Socket error: ${err.message}`);
});

Working with Socket Buffers

This example demonstrates socket buffering and the 'drain' event:

const net = require('net');
// Create server to demonstrate buffer handling const server = net.createServer((socket) => {
console.log('Client connected');
// Make buffer small to demonstrate filling it faster socket.bufferSize = 1024; // Note: This doesn't actually limit the buffer size
// Send a slow response to the client to demonstrate buffering socket.on('data', (data) => {
console.log(`Received data: ${data.toString().trim()}`);
console.log('Sending large response...');
// Function to write data until buffer is full const writeUntilBufferFull = () => {
// Generate some data to send const chunk = 'x'.repeat(1024);
// Keep writing until the buffer is full (write returns false)
let i = 0;
while (i < 100) {
const canContinue = socket.write(`Chunk ${i}: ${chunk}\n`);
console.log(`Wrote chunk ${i}, buffer full? ${!canContinue}`);
// If the buffer is full, wait for it to drain if (!canContinue) {
console.log(`Buffer is full after ${i} writes. Current buffer size: ${socket.bufferSize} bytes`);
// Stop writing and wait for the 'drain' event socket.once('drain', () => {
console.log('Buffer drained, resuming writes');
writeUntilBufferFull();
});
return;
}
i++;
}
// All chunks written console.log('All data sent');
socket.end('\nTransmission complete');
};
// Start the writing process writeUntilBufferFull();
});
socket.on('end', () => {
console.log('Client disconnected');
});
socket.on('error', (err) => {
console.error(`Socket error: ${err.message}`);
});
socket.write('Send any message to receive a large response\n');
});
// Start the server const PORT = 8082;
server.listen(PORT, () => {
console.log(`Buffer demonstration server running on port ${PORT}`);
// For demonstration, create a client that connects and sends a message const client = new net.Socket();
client.connect(PORT, '127.0.0.1', () => {
console.log('Test client connected');
// Send a message after 1 second setTimeout(() => {
client.write('Please send me a large response');
}, 1000);
});
let receivedData = 0;
client.on('data', (data) => {
receivedData += data.length;
console.log(`Client received ${data.length} bytes, total: ${receivedData}`);
});
client.on('end', () => {
console.log(`Client disconnected after receiving ${receivedData} bytes`);
process.exit(0);
});
client.on('error', (err) => {
console.error(`Client error: ${err.message}`);
});
});

IPC Socket Communication

Formula

This example demonstrates Inter - Process Communication (IPC) using Unix domain sockets:
const net = require('net');
const path = require('path');
const fs = require('fs');

Formula

// IPC path - depending on OS
const socketPath = process.platform === 'win32'

Formula

? path.join('\\\\?\\pipe', process.cwd(), 'ipc - demo.sock')
: path.join(process.cwd(), 'ipc-demo.sock');
// Remove existing socket file if it exists (Unix only)
if (process.platform !== 'win32' && fs.existsSync(socketPath)) {
fs.unlinkSync(socketPath);
}
// Create IPC server const server = net.createServer((socket) => {
console.log('Client connected to IPC socket');
socket.on('data', (data) => {
const message = data.toString().trim();
console.log(`Server received: ${message}`);
// Echo back socket.write(`Echo: ${message}`);
});
socket.on('end', () => {
console.log('Client disconnected from IPC socket');
});
socket.write('Connected to IPC server\n');
});
// Handle server errors server.on('error', (err) => {
console.error(`IPC server error: ${err.message}`);
});
// Start IPC server server.listen(socketPath, () => {
console.log(`IPC server listening on ${socketPath}`);
// Create client that connects to the IPC socket const client = new net.Socket();
client.on('data', (data) => {
console.log(`Client received: ${data.toString().trim()}`);
});
client.on('end', () => {
console.log('Disconnected from IPC server');
});
client.on('error', (err) => {
console.error(`IPC client error: ${err.message}`);
});
// Connect to the IPC server client.connect(socketPath, () => {
console.log('Connected to IPC server');
client.write('Hello via IPC socket');
// Send multiple messages setTimeout(() => {
client.write('Message 1');
}, 1000);
setTimeout(() => {
client.write('Message 2');
client.end(); // Close after sending the last message
}, 2000);
});
});
// Cleanup on exit process.on('exit', () => {
if (process.platform !== 'win32' && fs.existsSync(socketPath)) {
fs.unlinkSync(socketPath);
}
});

Formula

// Handle Ctrl + C
process.on('SIGINT', () => {
console.log('Shutting down...');
process.exit(0);
});

Half-Closed Sockets

This example demonstrates half-closed connections where one side has ended their write stream but can still receive data:

const net = require('net');
// Create server const server = net.createServer((socket) => {
console.log('Client connected');
// Send initial message socket.write('Welcome to the half-close demonstration server\n');
// Handle data from client socket.on('data', (data) => {
console.log(`Server received: ${data.toString().trim()}`);
});
// Handle socket end (client ended their write stream)
socket.on('end', () => {
console.log('Client ended their write stream (half-closed)');
// We can still write to the client after they've ended their write stream socket.write('You have ended your side of the connection, but I can still talk to you.');
// Close our side after a delay setTimeout(() => {
console.log('Server now closing its write stream');
socket.end('Goodbye! Closing my side of the connection now.');
}, 8080);
});
// Handle complete socket closure socket.on('close', (hadError) => {
console.log(`Socket fully closed. Had error: ${hadError}`);
});
socket.on('error', (err) => {
console.error(`Socket error: ${err.message}`);
});
});
// Start server const PORT = 8083;
server.listen(PORT, () => {
console.log(`Half-close demonstration server running on port ${PORT}`);
// Create a client for demonstration const client = new net.Socket();
client.connect(PORT, '127.0.0.1', () => {
console.log('Client connected');
// Send some data client.write('Hello from client');

Formula

// After a delay, end the client write stream (half - close)
setTimeout(() => {
console.log('Client ending its write stream (half-closing)');
client.end();
// We can't write anymore, but we can still receive data console.log('Client waiting to receive more data...');
}, 2000);
});
// Handle data from server client.on('data', (data) => {
console.log(`Client received: ${data.toString().trim()}`);
});
// Handle server closing its write stream client.on('end', () => {
console.log('Server ended its write stream, connection fully closed');
});
// Handle complete connection closure client.on('close', (hadError) => {
console.log(`Client connection fully closed. Had error: ${hadError}`);
});
client.on('error', (err) => {
console.error(`Client error: ${err.message}`);
});
});

Best Practices for Socket Programming

When working with sockets in Node.js, consider these best practices:

Error handling

: Always handle the 'error' event to prevent unhandled exceptions.

Clean up resources

: Ensure sockets are properly closed to avoid memory leaks.

Buffer management

: Monitor socket.bufferSize and use the 'drain' event to avoid memory issues when sending large amounts of data.

Timeouts

: Set appropriate timeouts with socket.setTimeout() to handle stale connections.

Keep-alive

Formula

: Configure keep - alive settings for long - running connections.

Data encoding

: Set appropriate encoding with socket.setEncoding() or handle binary data appropriately.

Security

Formula

: For secure communication, use the TLS/SSL module (

tls ) instead of raw TCP sockets.

Previous

Node.js Verify Reference

Next

Node.js ReadStream Reference