Dunque, mi son trovato diverse volte a "smanettare" con (ed a creare veri e propri client per) vari protocolli di comunicazione che si appoggiano al TCP/IP, e ci sono due diversi "filoni" che ho identificato e che uso spesso per pensare a come potrebbe essere architettato il "protocollo" di trasmissione delle informazioni del server e del client che sto sviluppando in uno dei tanti progetti.
In particolare, dal mio punto di vista, ci sono quelli "telnet-compatibile", e quelli non "telnet-compatible". Anche se la descrizione può sembrare "strana" (telnet è a se un protocollo), in realtà l'intenzione è quella di indicare due tipologie di cui una è molto simile a come telnet invia le informazioni.
In uno dei tanti che ho avuto modo di leggere/interpretare/studiare, l'IRC è uno di quelli che più mi piace, e il NAP (famoso per Napster) è l'altro. Sono due molto simili, ma anche molto diversi. In cosa differiscono?
Un protocollo "telnet-compatible", o meglio "text/plain", come l'IRC, prevede l'invio di un comando di testo ASCII, come ad esempio JOIN, PART, ecc. e l'invio di parametri, separati da uno spazio. L'invio effettivo di un comando si ha con un ritorno a capo. Un po' come un comando da terminale. Questo lo rende usabile anche con un "client grezzo" come telnet oppure netcat. Questo può essere un vantaggio per chi non ha un client installato, oppure per le prove, poiché tutti i sistemi hanno un qualcosa di simile ad un telnet che si può usare per collegarsi e "dialogare con il server".
Cosa diversa è il protocollo NAP. Tale protocollo prevede l'invio di 2 byte per indicare la lunghezza del terzo "campo" che sarebbero i dati, e una seconda coppia di byte (secondo campo) che identifica il codice del comando (tra l'altro queste prime coppie sono in formato little-endian, cioè "il byte meno significativo viene prima"). E poi ovviamente i dati in ASCII o giù di lì. Senza ritorni a capo, il terzo campo finisce infatti esattamente alla lunghezza inviata nei primi due byte. Come si può capire, questo protocollo è praticamente impossibile da utilizzare mediante netcat o telnet, poiché richiede l'inserimento di codici che probabilmente non saremo in grado di inserire con la tastiera.
Ora, avrebbe poco senso parlare di "protocollo migliore" in generale, ma ha molto senso se facciamo un'analisi approfondita di quello che sono i limiti dei due, e dove poterli applicare con sicurezza.
Un protocollo, come il NAP, che ha un valore che rappresenta la lunghezza, ha il grosso limite di avere una dimensione massima dell'intero pacchetto ad un valore ben preciso, nel caso del NAP si aggira intorno a 2^16, ovvero 64K (che, anche se può sembrare tanto, potrebbe essere poco delle volte) più ovviamente 4 che sono la coppia di byte della dimensione e la coppia di byte del codice del comando; anche i comandi sono limitati a 64K. Nel protocollo IRC invece, tale limite è fissato dalle specifiche a 510 caratteri (gli altri 2 sono per il ritorno a capo e l'avanzamento riga, CR-LF), ma nulla vieta di "derivare", aggiungendo praticamente infinite posizioni. E' ovvio però che a quel punto si "sovraccarica" il pacchetto di dati che potrebbe rallentare il server, fino a provocare malfunzionamenti: dare un limite di 100 mega al pacchetto infatti, può voler dire che quando 5 persone inviano un solo pacchetto (anche di login) il sistema debba allocare minimo 500 mega in RAM per gestire il buffer in ingresso. E se fossero 50 persone?
Il fatto di avere un terminatore "di pacchetto" (come la coppia CR-LF, ovvero l'invio, dell'IRC) inoltre, può portare diversi problemi: il principale è che tale carattere non deve essere presente nei parametri del comando, altrimenti il "parser" del messaggio finisce l'analisi lì. Si potrebbe allora sostituire tale carattere, in fase di invio, con un'altra sequenza, ma poi il destinatario non saprà (programma o utente) se la stringa XY era riferito ad un ritorno a capo (o qualsiasi carattere fosse il terminatore), oppure proprio a XY. Si perde insomma la possibilità di inviare il carattere che si usa come fine messaggio, amenoché creare diversi disagi all'utente, o complicazioni nel codice.
Tirando le somme, ogni protocollo ha dei limiti, e un'attenta valutazione prima di iniziare a sviluppare il codice può essere di aiuto nella fase implementativa, e per scongiurare spiacevoli sorprese.
Enrico
Etichette: irc, napster, opennap, protocollo, rete, socket