1. Theory:
Introduction to Networking in Node.js
What is Networking?
- Networking refers to the communication between a client and a server using network protocols like HTTP, TCP, UDP, etc.
What is HTTP?
- HTTP (HyperText Transfer Protocol) is a protocol used for transferring data over the web. In Node.js, the
http
module allows you to create an HTTP server to listen for incoming requests and send responses to clients.
- HTTP (HyperText Transfer Protocol) is a protocol used for transferring data over the web. In Node.js, the
Understanding HTTP Protocols
Request and Response Cycle:
The client (browser, Postman, etc.) sends an HTTP request to the server.
The server processes the request and sends back an HTTP response.
HTTP Methods:
GET: Used to retrieve data from the server.
POST: Used to send data to the server.
PUT, DELETE: Other methods used for modifying or deleting data.
Basics of Creating an HTTP Server in Node.js
Using the
http
Module:The
http
module in Node.js allows you to create a simple web server that can handle incoming HTTP requests and send responses.You can handle different routes (e.g.,
/home
,/about
) and different HTTP methods (e.g., GET, POST) to serve different types of content.
TCP (Transmission Control Protocol):
Strengths:
Reliable: TCP ensures that all data is delivered in the correct order, with error checking and retransmission of lost packets.
Connection-Oriented: A reliable connection is established between the two endpoints before data transfer begins, ensuring consistency.
Use Case in Real-Time Communication:
Chat applications: Many real-time messaging apps, such as WhatsApp or Facebook Messenger, use TCP because reliability is crucial in text-based communication. Missing or out-of-order messages would disrupt the user experience.
VoIP with fallback to TCP: In cases where network conditions are unreliable, some VoIP systems fall back to TCP for improved reliability.
Video conferencing (with TCP fallback): Some systems use TCP to ensure delivery, but usually at the cost of higher latency.
const net = require("net");
const readline = require("readline");
// Create a TCP server
const server = net.createServer((socket) => {
console.log("Client connected");
socket.write("Hello, TCP World!\n");
// Receive data from the client
socket.on("data", (data) => {
console.log(`Client says: ${data}`);
socket.write(`You said: ${data}`); // Echo the message back
});
// Close the connection
socket.on("end", () => {
console.log("Client disconnected");
});
// Now allow input from the server terminal and send to client
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on("line", (input) => {
socket.write(`Server says: ${input}\n`);
});
});
// Listen on port 4000
server.listen(4000, () => {
console.log("TCP server listening on port 4000");
});
UDP (User Datagram Protocol):
Strengths:
Fast and Low Latency: UDP is faster than TCP because it doesn’t establish a connection or handle packet retransmission, which makes it ideal for real-time communication where speed is more important than reliability.
Connectionless: UDP sends packets without establishing a connection, so it is lightweight and better for real-time, high-speed transmissions.
Use Case in Real-Time Communication:
Voice over IP (VoIP): Applications like Zoom, Skype, or Google Meet often use UDP for transmitting voice data, as low latency is critical, and occasional packet loss is acceptable.
Online Gaming: Many real-time multiplayer games use UDP for transmitting game data, where speed and low latency are prioritized over perfect delivery. Lost packets are usually acceptable because real-time updates happen continuously.
Live Streaming: UDP is used for real-time video and audio streaming because it can handle large amounts of data without waiting for acknowledgment of each packet, reducing latency.
2. Practical:
Task 1: Create a Basic HTTP Server
What to do:
- Create a simple Node.js HTTP server using the
http
module that listens on port 3000 and responds with a message.
Example:
const http = require('http');
// Create an HTTP server
const server = http.createServer((req, res) => {
// Set the response header
res.writeHead(200, { 'Content-Type': 'text/plain' });
// Send a simple response
res.end('Hello, World!\n');
});
// The server listens on port 3000
server.listen(3000, () => {
console.log('Server is listening on port 3000...');
});
Run the server:
node server.js
- Open the browser and go to
http://localhost:3000
, and you will see "Hello, World!" displayed.
Task 2: Responding with Static Content (HTML and JSON)
What to do:
- Modify the server to respond with HTML content when the request URL is
/home
and with JSON data when the request URL is/api
.
Example:
const http = require('http');
// Create an HTTP server
const server = http.createServer((req, res) => {
if (req.url === '/home') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Welcome to the Home Page!</h1>');
} else if (req.url === '/api') {
res.writeHead(200, { 'Content-Type': 'application/json' });
const data = {
message: 'Hello, this is JSON data!',
status: 'success',
};
res.end(JSON.stringify(data));
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 - Not Found');
}
});
// The server listens on port 3000
server.listen(3000, () => {
console.log('Server is listening on port 3000...');
});
Test the server:
Go to
http://localhost:3000/home
, and you will see the HTML content.Go to
http://localhost:3000/api
, and you will receive the JSON response.
Task 3: Handling Different Routes and HTTP Methods (GET, POST)
What to do:
Modify the server to handle two different routes:
/about
: Responds with a simple HTML message using the GET method./submit
: Accepts POST requests and responds with the data that the client submits.
Example:
const http = require('http');
// Create an HTTP server
const server = http.createServer((req, res) => {
if (req.method === 'GET' && req.url === '/about') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>About Us</h1><p>This is the about page.</p>');
} else if (req.method === 'POST' && req.url === '/submit') {
let body = '';
// Collect the data sent by the client
req.on('data', chunk => {
body += chunk.toString();
});
// Once all data is received, respond with it
req.on('end', () => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Received data: ${body}`);
});
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 - Not Found');
}
});
// The server listens on port 3000
server.listen(3000, () => {
console.log('Server is listening on port 3000...');
});
Test the server:
Visit
http://localhost:3000/about
to see the GET request in action.Use Postman or
curl
to send a POST request with data tohttp://localhost:3000/submit
.
Example using curl
:
curl -X POST -d "name=John&age=25" http://localhost:3000/submit
Output:
Received data: name=John&age=25
3. Extended Practical Examples:
Task 4: Serve a Static HTML File
What to do:
- Create an HTML file (e.g.,
index.html
) and serve it using thefs
module with the HTTP server.
Example:
Create an
index.html
file:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Portfolio</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; background-color: #f4f4f4; color: #333; } header { background-color: #333; color: #fff; padding: 1rem 0; text-align: center; } header h1 { margin-bottom: 0.5rem; } header p { font-size: 1.1rem; } nav { background-color: #444; padding: 1rem; text-align: center; } nav a { color: #fff; margin: 0 15px; text-decoration: none; font-weight: bold; } nav a:hover { text-decoration: underline; } .container { max-width: 1100px; margin: 2rem auto; padding: 0 2rem; } .about, .projects { background-color: #fff; padding: 2rem; margin-bottom: 1.5rem; border-radius: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .about h2, .projects h2 { margin-bottom: 1rem; } .about p { font-size: 1.1rem; line-height: 1.8; } .projects { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; } .project-card { background-color: #f9f9f9; padding: 1.5rem; border-radius: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .project-card h3 { margin-bottom: 0.5rem; } .project-card p { margin-bottom: 1rem; } footer { background-color: #333; color: #fff; text-align: center; padding: 1rem 0; } footer p { margin: 0; } </style> </head> <body> <header> <h1>Sungava College</h1> <p>Web Developer | Designer | Programmer</p> </header> <nav> <a href="#about">About</a> <a href="#projects">Projects</a> <a href="#contact">Contact</a> </nav> <div class="container"> <section id="about" class="about"> <h2>About Me</h2> <p> Hello! I'm Apple, a passionate web developer with experience in building dynamic and responsive websites. I enjoy turning complex problems into simple, beautiful, and intuitive solutions. </p> </section> <section id="projects" class="projects"> <h2>Projects</h2> <div class="project-card"> <h3>Project One</h3> <p>A responsive website built with HTML, CSS, and JavaScript.</p> <a href="#">View Project</a> </div> <div class="project-card"> <h3>Project Two</h3> <p>A dynamic web application using the MERN stack.</p> <a href="#">View Project</a> </div> <div class="project-card"> <h3>Project Three</h3> <p>An eCommerce platform built using React and Node.js.</p> <a href="#">View Project</a> </div> </section> </div> <footer> <p>© 2024 Sungava College. All Rights Reserved.</p> </footer> </body> </html>
Modify the server to read and serve this file:
const http = require('http'); const fs = require('fs'); // Create an HTTP server const server = http.createServer((req, res) => { if (req.url === '/home') { fs.readFile('index.html', (err, data) => { if (err) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('500 - Internal Server Error'); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(data); } }); } else { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('404 - Not Found'); } }); // The server listens on port 3000 server.listen(3000, () => { console.log('Server is listening on port 3000...'); });
Test the server:
- Open
http://localhost:3000/home
to see the HTML file served by the Node.js server.
Task 5: Handle Query Parameters
What to do:
- Handle query parameters from a URL and return dynamic content based on those parameters.
Example:
const http = require("http");
const url = require("url");
// Create an HTTP server
const server = http.createServer((req, res) => {
// Parse the URL and extract query parameters
const parsedUrl = url.parse(req.url, true);
const queryObject = parsedUrl.query;
// Check if the path starts with /greet/
if (req.url.startsWith("/greet/")) {
// Extract the "name" query parameter, or default to "Guest"
const name = queryObject.name || "Guest";
// Set response header and send the greeting message
res.writeHead(200, { "Content-Type": "text/plain" });
res.end(`Hello, ${name}!`);
} else {
// Handle 404 Not Found if the route doesn't match /greet/
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("404 - Not Found");
}
});
// The server listens on port 3000
server.listen(3000, () => {
console.log("Server is listening on port 3000...");
});
Test the server:
- Open
http://localhost:3000/greet?name=John
to see dynamic content generated based on the query parameter (name=John
).