├── README.md ├── chat-app ├── client.js └── server.js ├── simple-dns.js ├── simple-tcp ├── simple-sender.js └── simple-server.js ├── simple-udp ├── simple-receiver.js └── simple-sender.js └── uploader ├── client.js ├── server.js └── storage └── .keep /README.md: -------------------------------------------------------------------------------- 1 | # Source Code for Understanding Networking Video 2 | 3 | This repository contains all the final code we wrote in the Understanding Networking video of my Understanding Node.js Core Concepts course. You can find the video [here](https://www.youtube.com/watch?v=D62jtzr2Zcc). 4 | -------------------------------------------------------------------------------- /chat-app/client.js: -------------------------------------------------------------------------------- 1 | const net = require("net"); 2 | const readline = require("readline/promises"); 3 | 4 | const PORT = 4020; 5 | const HOST = "127.0.0.1"; 6 | 7 | const rl = readline.createInterface({ 8 | input: process.stdin, 9 | output: process.stdout, 10 | }); 11 | 12 | const clearLine = (dir) => { 13 | return new Promise((resolve, reject) => { 14 | process.stdout.clearLine(dir, () => { 15 | resolve(); 16 | }); 17 | }); 18 | }; 19 | 20 | const moveCursor = (dx, dy) => { 21 | return new Promise((resolve, reject) => { 22 | process.stdout.moveCursor(dx, dy, () => { 23 | resolve(); 24 | }); 25 | }); 26 | }; 27 | 28 | let id; 29 | 30 | const socket = net.createConnection({ host: HOST, port: PORT }, async () => { 31 | console.log("Connected to the server!"); 32 | 33 | const ask = async () => { 34 | const message = await rl.question("Enter a message > "); 35 | // move the cursor one line up 36 | await moveCursor(0, -1); 37 | // clear the current line that the cursor is in 38 | await clearLine(0); 39 | socket.write(`${id}-message-${message}`); 40 | }; 41 | 42 | ask(); 43 | 44 | socket.on("data", async (data) => { 45 | // log an empty line 46 | console.log(); 47 | // move the cursor one line up 48 | await moveCursor(0, -1); 49 | // clear that line that cursor just moved into 50 | await clearLine(0); 51 | 52 | if (data.toString("utf-8").substring(0, 2) === "id") { 53 | // When we are getting the id... 54 | 55 | // everything from the third character up until the end 56 | id = data.toString("utf-8").substring(3); 57 | 58 | console.log(`Your id is ${id}!\n`); 59 | } else { 60 | // When we are getting a message... 61 | 62 | console.log(data.toString("utf-8")); 63 | } 64 | 65 | ask(); 66 | }); 67 | }); 68 | 69 | socket.on("end", () => { 70 | console.log("Connection was ended!"); 71 | }); 72 | -------------------------------------------------------------------------------- /chat-app/server.js: -------------------------------------------------------------------------------- 1 | const net = require("net"); 2 | 3 | const PORT = 4020; 4 | const HOST = "127.0.0.1"; 5 | 6 | const server = net.createServer(); 7 | 8 | // an array of client sockets 9 | const clients = []; 10 | 11 | server.on("connection", (socket) => { 12 | console.log("A new connection to the server!"); 13 | 14 | const clientId = clients.length + 1; 15 | 16 | // Broadcasting a message to everyone when someone enters the chat room 17 | clients.map((client) => { 18 | client.socket.write(`User ${clientId} joined!`); 19 | }); 20 | 21 | socket.write(`id-${clientId}`); 22 | 23 | socket.on("data", (data) => { 24 | const dataString = data.toString("utf-8"); 25 | const id = dataString.substring(0, dataString.indexOf("-")); 26 | const message = dataString.substring(dataString.indexOf("-message-") + 9); 27 | 28 | clients.map((client) => { 29 | client.socket.write(`> User ${id}: ${message}`); 30 | }); 31 | }); 32 | 33 | // Broadcasting a message to everyone when someone leaves the chat room 34 | socket.on("end", () => { 35 | clients.map((client) => { 36 | client.socket.write(`User ${clientId} left!`); 37 | }); 38 | }); 39 | 40 | clients.push({ id: clientId.toString(), socket }); 41 | }); 42 | 43 | server.listen(PORT, HOST, () => { 44 | console.log("opened server on", server.address()); 45 | }); 46 | -------------------------------------------------------------------------------- /simple-dns.js: -------------------------------------------------------------------------------- 1 | const dns = require("node:dns/promises"); 2 | 3 | (async () => { 4 | const result = await dns.lookup("google.com"); 5 | console.log(result); 6 | })(); 7 | -------------------------------------------------------------------------------- /simple-tcp/simple-sender.js: -------------------------------------------------------------------------------- 1 | const net = require("net"); 2 | 3 | const socket = net.createConnection({ host: "127.0.0.1", port: 3099 }, () => { 4 | const buff = Buffer.alloc(8); 5 | buff[0] = 12; 6 | buff[1] = 34; 7 | 8 | socket.write(buff); 9 | }); 10 | -------------------------------------------------------------------------------- /simple-tcp/simple-server.js: -------------------------------------------------------------------------------- 1 | const net = require("net"); 2 | 3 | const server = net.createServer((socket) => { 4 | socket.on("data", (data) => { 5 | console.log(data); 6 | }); 7 | }); 8 | 9 | server.listen(8000, "127.0.0.1", () => { 10 | console.log("opened server on", server.address()); 11 | }); 12 | -------------------------------------------------------------------------------- /simple-udp/simple-receiver.js: -------------------------------------------------------------------------------- 1 | const dgram = require("dgram"); 2 | 3 | const receiver = dgram.createSocket("udp4"); 4 | 5 | receiver.on("message", (message, remoteInfo) => { 6 | console.log( 7 | `Server got: ${message} from ${remoteInfo.address}:${remoteInfo.port}` 8 | ); 9 | }); 10 | 11 | receiver.bind({ address: "127.0.0.1", port: 8000 }); 12 | 13 | receiver.on("listening", () => { 14 | console.log(`Server listening: `); 15 | console.log(receiver.address()); 16 | }); 17 | -------------------------------------------------------------------------------- /simple-udp/simple-sender.js: -------------------------------------------------------------------------------- 1 | const dgram = require("dgram"); 2 | 3 | // max size of buffer size by default: 9216 bytes 4 | const sender = dgram.createSocket({ type: "udp4", sendBufferSize: 20000 }); 5 | 6 | sender.send( 7 | Buffer.from("Some amount of data 1 ..."), 8 | 8000, 9 | "127.0.0.1", 10 | (e, bytes) => { 11 | if (e) console.log(e); 12 | console.log(bytes); 13 | } 14 | ); 15 | 16 | sender.send( 17 | Buffer.from("Some amount of data 2 ..."), 18 | 8000, 19 | "127.0.0.1", 20 | (e, bytes) => { 21 | if (e) console.log(e); 22 | console.log(bytes); 23 | } 24 | ); 25 | 26 | // Another syntax: 27 | sender.connect(8000, "127.0.0.1", (err) => { 28 | if (err) console.log(err); 29 | 30 | sender.send(Buffer.from("Some amount of data...")); 31 | }); 32 | -------------------------------------------------------------------------------- /uploader/client.js: -------------------------------------------------------------------------------- 1 | const net = require("net"); 2 | const fs = require("node:fs/promises"); 3 | const path = require("path"); 4 | 5 | const clearLine = (dir) => { 6 | return new Promise((resolve, reject) => { 7 | process.stdout.clearLine(dir, () => { 8 | resolve(); 9 | }); 10 | }); 11 | }; 12 | 13 | const moveCursor = (dx, dy) => { 14 | return new Promise((resolve, reject) => { 15 | process.stdout.moveCursor(dx, dy, () => { 16 | resolve(); 17 | }); 18 | }); 19 | }; 20 | 21 | const socket = net.createConnection({ host: "::1", port: 5050 }, async () => { 22 | const filePath = process.argv[2]; 23 | const fileName = path.basename(filePath); 24 | const fileHandle = await fs.open(filePath, "r"); 25 | const fileReadStream = fileHandle.createReadStream(); // the stream to read from 26 | const fileSize = (await fileHandle.stat()).size; 27 | 28 | // For showing the upload progress 29 | let uploadedPercentage = 0; 30 | let bytesUploaded = 0; 31 | 32 | socket.write(`fileName: ${fileName}-------`); 33 | 34 | console.log(); // to get a nice log for the progress percentage 35 | 36 | // Reading from the source file 37 | fileReadStream.on("data", async (data) => { 38 | if (!socket.write(data)) { 39 | fileReadStream.pause(); 40 | } 41 | 42 | bytesUploaded += data.length; // add the number of bytes read to the variable 43 | let newPercentage = Math.floor((bytesUploaded / fileSize) * 100); 44 | 45 | if (newPercentage !== uploadedPercentage) { 46 | uploadedPercentage = newPercentage; 47 | await moveCursor(0, -1); 48 | await clearLine(0); 49 | console.log(`Uploading... ${uploadedPercentage}%`); 50 | } 51 | }); 52 | 53 | socket.on("drain", () => { 54 | fileReadStream.resume(); 55 | }); 56 | 57 | fileReadStream.on("end", () => { 58 | console.log("The file was successfully uploaded!"); 59 | socket.end(); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /uploader/server.js: -------------------------------------------------------------------------------- 1 | const net = require("net"); 2 | const fs = require("node:fs/promises"); 3 | 4 | const server = net.createServer(() => {}); 5 | 6 | server.on("connection", (socket) => { 7 | console.log("New connection!"); 8 | let fileHandle, fileWriteStream; 9 | 10 | socket.on("data", async (data) => { 11 | if (!fileHandle) { 12 | socket.pause(); // pause receiving data from the client 13 | 14 | const indexOfDivider = data.indexOf("-------"); 15 | const fileName = data.subarray(10, indexOfDivider).toString("utf-8"); 16 | 17 | fileHandle = await fs.open(`storage/${fileName}`, "w"); 18 | fileWriteStream = fileHandle.createWriteStream(); // the stream to write to 19 | 20 | // Writing to our destination file, discard the headers 21 | fileWriteStream.write(data.subarray(indexOfDivider + 7)); 22 | 23 | socket.resume(); // resume receiving data from the client 24 | fileWriteStream.on("drain", () => { 25 | socket.resume(); 26 | }); 27 | } else { 28 | if (!fileWriteStream.write(data)) { 29 | socket.pause(); 30 | } 31 | } 32 | }); 33 | 34 | // This end event happens when the client.js file ends the socket 35 | socket.on("end", () => { 36 | if (fileHandle) fileHandle.close(); 37 | fileHandle = undefined; 38 | fileWriteStream = undefined; 39 | console.log("Connection ended!"); 40 | }); 41 | }); 42 | 43 | server.listen(5050, "::1", () => { 44 | console.log("Uploader server opened on", server.address()); 45 | }); 46 | -------------------------------------------------------------------------------- /uploader/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/agile8118/node-networking/081fbe6ce76149b1541d860413b4761f080f9a60/uploader/storage/.keep --------------------------------------------------------------------------------