π€ 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}`);
});