Quote:
Originariamente inviato da mfonz85
Ciao a tutti,
avrei un problema: devo far parlare un client e un server scritti in C che gireranno su Unix, e devo praticamente fare una sorta di handshaking iniziale dove il client manda un carattere di saluto (codificato in ASCII - 1 byte) seguito da un'altro numero, scritto sempre su 1 byte, che può assumere il valore 1, 2 o 4: questo valore serve praticamente a far capire al server che da quel momento io (client) inizierò a mandargli dei numeri interi codificati appunto su 1, 2 o 4 byte.
I problemi miei sono i seguenti:
1) ma per il little/big endian?? Non succedono casini quando invio dati binari?
|
Sì. Infatti, se non abbiamo problemi di "traffico", a volte quando si inviano molti dati strutturati si preferisce usare XML.
C'è comunque la possibilità di usare funzioni di libreria che rendono indipendenti i dati scritti dall'architettura: guarda il man di htonl e compagni.
Quote:
Originariamente inviato da mfonz85
2) per ricostruire lo stream al server, che si vede sostanzialmente arrivare uno stream di byte, come faccio??
|
Devi costruirti un protocollo. Il server deve sapere a priori la dimensione dai dati. Te lo spiego sotto.
Quote:
Originariamente inviato da mfonz85
3) E anche al client, come faccio a concatenare in modo intelligente questi byte??
|
Non importa, usa una struttura dati. Riempila con le debite conversioni hton* ed inviala per intero.
Quote:
Originariamente inviato da mfonz85
Poniamo il caso che devo fare un programma così: handshaking con una "R" seguita dal numero 1, 2, o 4 scritto sempre su 1 byte. (byte di CODIFICA). Nel nostro esempio voglio che il client invii da quel momento in poi solo interi codificati su 2 byte.
Il server lo deve ricevere, e capire come aspettarsi i prossimi dati. (ovvero da adesso in poi si aspetta SOLO interi su 2 byte)
Poi da client voglio inviargli 4 numeri consecutivi codificati sul numero di byte scritto in precedenza sul secondo campo del primo invio (byte di CODIFICA)
Per esempio gli voglio inviare 67, 621 e 715 scritti su 2 byte. Questi numeri devono essere codificati su 2 byte, e messi in un'unico stream grosso di 4*2 = 8 byte (che saranno poi spezzettati al server)
|
Hai descritto un protocollo. Il modo migliore per gestire un protocollo è quello di una macchina a stati, ad esempio (me lo invento):
avviene la connessione: passo allo stato IDENTIFYING
IDENTIFYING: devo ricevere username e password. La codifica dei dati deve essere composta da (in sequenza di lettura):
- 2 byte per la dimensione dello username
- stringa username
- 2 byte per la dimensione della password
- stringa password
se l'autenticazione ha successo passo a ENCODING
se l'autenticazione non ha successo passo a FAIL
ENCODING: devo ricevere R seguito da 1 byte, quindi leggo 2 byte.
Se le informazioni non sono corrette passo a FAIL
Se ricevo 1 passo a 1BYTE_ENCODED
Se ricevo 2 passo a 2BYTE_ENCODED
Se ricevo 4 passo a 4BYTE_ENCODED
1BYTE_ENCODED: leggo la dimensione dei dati da leggere, leggo un byte alla volta e faccio quello che ci devo fare
2BYTE_ENCODED: leggo la dimensione dei dati da leggere, leggo due byte alla volta e faccio quello che ci devo fare
4BYTE_ENCODED: leggo la dimensione dei dati da leggere, leggo quattro byte alla volta e faccio quello che ci devo fare
FAIL: rispondo con una stringa di errore (sempre dimensione, seguito dalla stringa). Vado a CLOSING
CLOSING: termino la connessione
La macchina a stati te la gestisci in maniera semplice con un enum, in base al valore dello stato sai quello che devi fare (il modo più immediato per implementarlo è uno switch),