Sockets

net module

Server

  • net.createServer() creates TCP/IPC server
  • net.Server represents TCP/IPC server
  • class http.Server extends net.Server
const net = require('net');
 
const server = net.createServer((socket) => {
  console.log('Client connected!');
 
  console.log(`\nLocal -> family: ${socket.localFamily}, address: ${socket.localAddress}, port: ${socket.localPort}`);
 
  console.log(`Remote -> family: ${socket.remoteFamily}, address: ${socket.remoteAddress}, port: ${socket.remotePort}\n`);
 
  // Handle incoming data from the client
  socket.on('data', (data) => {
    console.log(`Received data from client: ${data.toString()}`);
 
    const response = `Hello from the server! You sent: ${data}`;
    console.log(`Sending response to client: ${response}`);
    // Send a response back to the client
    socket.write(response);
  });
 
  // Handle client disconnection
  socket.on('end', () => {
    console.log('Client disconnected!');
  });
});
 
const port = 1337;
 
// INADDR_ANY: Bind to all interfaces
const anyHost = '0.0.0.0';
const anyHostIPv6 = '::';
 
// INADDR_LOOPBACK: Bind to loopback interface
const loopbackHost = '127.0.0.1';
const loopbackHostIPv6 = '::1';
 
const wlanInterface = '192.168.31.177';
const wlanInterfaceIPv6 = '2409:4090:f049:2a01:1034:a18b:4e5:d323';
 
server.listen(port, loopbackHost, () => {
  console.log(`Server listening on port ${port}`);
});

Client

const net = require('net');
 
const port = 1337;
 
// Connect with loopback address
const loopbackHost = '127.0.0.1';
const loopbackHostIPv6 = '::1';
 
// Connect with WLAN address
const wlanInterface = '192.168.31.177';
const wlanInterfaceIPv6 = '2409:4090:f049:2a01:1034:a18b:4e5:d323';
 
// Create a TCP client and connect to the server on localhost at port 1337
const client = net.createConnection({ port: port, host: loopbackHost }, () => {
  console.log('Connection created to the server');
  const data = 'Hi from Client!';
  console.log('Sending data to server:', data);
  // Send data to the server
  client.write(data);
});
 
// Handle data received from the server
client.on('data', (data) => {
  console.log('Response from server:', data.toString());
 
  // Close the connection after receiving a response
  client.end();
});
 
// Handle connection closure
client.on('close', () => {
  console.log('Connection closed');
});

net.Socket

  • https://nodejs.org/api/net.html
  • This class is an abstraction of a TCP socket or a streaming IPC endpoint (uses named pipes on Windows, and Unix domain sockets otherwise)
  • It is also an EventEmitter
  • A net.Socket can be created by the user and used directly to interact with a server
    • It is returned by net.createConnection() so the user can use it to talk to the server
  • It can also be created by Node.js and passed to the user when a connection is received
    • It is passed to the listeners of a ‘connection’ event emitted on a net.Server, so the user can use it to interact with the client.
  • Events:
    • lookup: after resolving DNS before connecting
    • connect: successful connection
      • connectionAttempt: connection attempt started
      • connectionAttemptFailed: connection attempt failed
      • connectionAttemptTimeout: connection attempt timeout
    • ready: when socket ready to be used after successful connection
    • data: when data is received, returns Buffer or String
    • drain: when write buffer becomes empty
    • end: when other end of the socket signals end of transmission
    • error: when error occurs
    • close: socket is fully closed
    • timeout: to notify that socket is idle, connection still needs to be closed manually

dgram.Socket

  • https://nodejs.org/api/dgram.html
  • Provides implementation of UDP sockets
  • It is also an EventEmitter
  • It is returned by dgram.createSocket() so the user can use it to talk to the server
  • Events
    • connect: successful connection
    • error: when error occurs
    • listening: when dgram.Socket is addressable and can receive data
      • after socket.bind()
      • after socket.send()
    • message: when new datagram is received
      • returns Buffer and remote info: address, family, port, size
    • close: socket is closed

Server

const dgram = require('dgram');
 
// Create a UDP server
const server = dgram.createSocket('udp4');
 
// Event listener for incoming messages
server.on('message', (msg, rinfo) => {
  console.log(`\nRemote -> family: ${rinfo.family}, address: ${rinfo.address}, port: ${rinfo.port}\n`);
 
  console.log(`Received data from client: ${msg}`);
 
  // Send a response back to the client
  const response = `Hello from the server! You sent: ${msg}`;
  server.send(response, rinfo.port, rinfo.address);
});
 
const port = 1337;
const loopbackHost = '127.0.0.1';
 
// Bind the server to a port and address
server.bind(port, loopbackHost, () => {
  console.log(`Server listening on ${port}`);
});

Client

const dgram = require('dgram');
 
// Create a UDP client
const client = dgram.createSocket('udp4');
 
// Server details
const port = 1337;
const loopbackHost = '127.0.0.1';
 
const message = 'Hi from Client!';
console.log('Sending data to server:', message);
// Send the message to the server
client.send(message, port, loopbackHost);
 
// Handle response from the server
client.on('message', (msg) => {
  console.log('Response from server:', msg.toString());
 
  // Close the client after receiving the response
  client.close();
});
 
client.on('close', () => {
  console.log('Connection closed');
});