Curioso di conoscere come Node.js definisce i costrutti per lavorare con i Socket TCP?

Ci sono tre varianti di socket in node: TCP, UDP, UNIX domain.
In questo particolare post, faremo vedere le basi della programmazione di socket TCP in node.js.

Ci sono due categorie universali a tal proposito: server, client. Un Server TCP rimane in attesa di connessioni da un client e invia dati al client. Un client TCP si connette ad un server TCP e scambia dati con lui. La comunicazione tra client e server avviene via socket.

La programmazione di socket TCP in node richiede l’utilizzo del modulo net, che espone un contenitore asincrono per la programmazione di rete. Con il modulo “net” si possono fare un bel po’ di cose, oggi vedremo di creare solamente un server ed un client TCP.

Scrivere un Server TCP

Questo sotto è un esempio semplicissimo di server TCP scritto in Node. I commenti nel codice meglio esplicano il suo funzionameno:

var net = require('net');
 
var HOST = '127.0.0.1';
var PORT = 6969;
 
// Creaiamo un istanza del server, e concateniamo la funzione listen
// La funzione passata a net.createServer() diventerà l'event handler per l'evento 'connection'
// l'oggetto sock che la callback prende come parametro è univoco per ogni connessione.
net.createServer(function(sock) {
 
    // abbiamo una connessione - un oggetto è assegnato alla connessione automaticamente
    console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
 
    // Aggiungiamo l'event handler 'data' per questa instanza di socket
    sock.on('data', function(data) {
 
        console.log('DATA ' + sock.remoteAddress + ': ' + data);
        // Rispondiamo al client, il client riceverà questi dati dal server.
        sock.write('You said "' + data + '"');
 
    });
 
    // Aggiungiamo l'event handler 'close' per questa istanza di socket
    sock.on('close', function(data) {
        console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
    });
 
}).listen(PORT, HOST);
 
console.log('Server listening on ' + HOST +':'+ PORT);

La stessa cosa può essere fatta in un altra maniera molto simile:

var server = net.createServer();
server.listen(PORT, HOST);
console.log('Server listening on ' + server.address().address +':'+ server.address().port);
server.on('connection', function(sock) {
 
    console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
    // l'atra parte di codice è uguale a quella dell'esempio precedente 
 
});

Ma quali sono le differenze? Alla base sono la stessa cosa, usano soltanto differenti convenzioni del linguaggio javascript. Nel primo esempio, passiamo l’event handler “connection” a net.createServer(), e successivamente si concatena la funzione listen(), nell’ultimo esempio abbiamo invece usato un approccio più convenzionale. Entrambi i codici funzionano perfettamente.

Scrivere un client TCP

Adesso iniziamo a scrivere un client per connettersi al server che abbiamo creato. Il codice che segue crea un semplice client che si connette al server, invia un messaggio e si sconnette dopo aver ricevuto una risposta.

var net = require('net');
 
var HOST = '127.0.0.1';
var PORT = 6969;
 
var client = new net.Socket();
client.connect(PORT, HOST, function() {
 
    console.log('CONNECTED TO: ' + HOST + ':' + PORT);
    // Inviamo un messaggio al server non appena il client si è connesso, il server riceverà questo messaggio dal client.
    client.write('I am Iron Man!');
 
});
 
// Aggiungiamo l'event handler 'data' per il client socket
// data sono i dati che il server invia a questo socket 
client.on('data', function(data) {
 
    console.log('DATA: ' + data);
    // chiude il client socket 
    client.destroy();
 
});
 
// Aggiungiamo l'event handler 'close' per il client socket.
client.on('close', function() {
    console.log('Connection closed');
});

Queste sono le basi dell’utilizzo dei socket in node.js. Nota bene, la programmazione di socket va ben oltre questo semplice esempio.
Nuovi concetti come Stream e Buffer vengono introdotti man mano che si inizia a scambiare grossi quantitativi di dati.