net Module - TCP Networking Made Easy
The net module provides an implementation of TCP (Transmission Control Protocol) sockets.
-
Connection-Oriented: A client and server must perform a “handshake” to establish a dedicated connection before any data can be exchanged.
-
Reliable and Ordered: TCP guarantees that every packet of data sent will be received, and that the packets will be assembled in their original order. If a packet is lost, it’s automatically re-transmitted.
-
Stream-Based: Data is treated as a continuous stream of bytes, not as a series of distinct messages.
Analogy: If UDP is like sending a postcard (fast, no guarantees), then TCP is like making a telephone call. You have to establish a connection first, and the conversation is a reliable, ordered, two-way stream of information.
This makes TCP the right choice for applications where data integrity is non-negotiable, like APIs, chat applications, and database connections.
- Use Cases: File transfers, web browsing, email, and other applications where reliability and order are critical.
⚙️ The Core net Workflow
The net module allows you to create TCP sockets to send and receive data streams.
-
The Server: You create a server using
net.createServer(). This server then listens on a specific port for incoming connections usingserver.listen(). When a client connects, the server emits a ‘connection’ event, providing asocketobject. -
The Client: A client uses
net.connect()ornet.createConnection()to establish a connection with a server at a specific address and port. -
The
socketObject: This is the heart of a TCP connection. Thesocketobject (an instance ofnet.Socket) is a Duplex Stream. This means you can read from it to receive data and write to it to send data over the same channel.
💻 Practical Example: A TCP Client & Server
This example demonstrates a simple multi-client chat room. The server will broadcast any message it receives from one client to all other connected clients.
const net = require("net");
const PORT = 9000;
const clients = []; // Array to hold connected client sockets
const server = net.createServer((socket) => {
// A new client has connected.
const clientId = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(`New client connected: ${clientId}`);
clients.push(socket);
// When this client sends data...
socket.on("data", (data) => {
console.log(`Received from ${clientId}: ${data.toString().trim()}`);
// ...broadcast it to all other clients.
clients.forEach((client) => {
if (client !== socket) {
// Don't send the message back to the sender
client.write(`> ${clientId}: ${data.toString().trim()}`);
}
});
});
// When the client disconnects...
socket.on("end", () => {
clients.splice(clients.indexOf(socket), 1); // Remove from the array
console.log(`Client disconnected: ${clientId}`);
});
// Handle socket errors
socket.on("error", (err) => {
console.log(`Error with client ${clientId}: ${err.message}`);
clients.splice(clients.indexOf(socket), 1);
});
});
server.listen(PORT, "127.0.0.1", () => {
console.log(`TCP server listening on port ${PORT}`);
});const net = require("net");
const client = net.connect({ port: 9000, host: "127.0.0.1" });
client.on("connect", () => {
console.log("Connected to the server!");
console.log("You can now type messages and press Enter to send.");
});
// When data is received from the server, log it to the console.
client.on("data", (data) => {
console.log(data.toString());
});
// Pipe keyboard input directly to the server socket.
process.stdin.pipe(client);
client.on("end", () => {
console.log("Disconnected from the server.");
process.exit();
});
client.on("error", (err) => {
console.error(`Connection error: ${err.message}`);
});