PDA

Visualizza la versione completa : [C++]Socket, messaggi e ascolto


FedeWar
08-03-2012, 18:04
Salve a tutti, sto creando un piccolo server su windows con l' header winsock.h (send e recv) solo che quando ascolto o invio messaggi mi fa usare solo il tipo di variabile char* e io devo usare anche i float, i double, gli int ecc..
avete da suggerirmi un altra funzione o un altro header?
grazie in anticipo!

ramy89
08-03-2012, 18:25
Ti conviene usare la sprintf per scrivere il double in formato stringa:



char* stringa=(char*)calloc(100,sizeof(char)); // potresti anche usare
// meno memoria
double valore;

// Prendi in input il valore

sprintf(stringa,"%f",valore);

// Ora la stringa contiene quel valore, ma scritto in caratteri



Il procedimento inverso si fa con la atof (qua trovi la documentazione (http://www.cplusplus.com/reference/clibrary/cstdlib/atof/)).

ESSE-EFFE
08-03-2012, 18:42
Originariamente inviato da ramy89
Ti conviene usare la sprintf per scrivere il double in formato stringa:

Credo sia meglio usare una memcpy e inviare il dato come si trova in memoria. Così facendo sa esattamente quanti byte occupa ed evita problemi di lunghezza, virgola, decimali, ecc.

ramy89
08-03-2012, 19:10
Originariamente inviato da ESSE-EFFE
Credo sia meglio usare una memcpy e inviare il dato come si trova in memoria. Così facendo sa esattamente quanti byte occupa ed evita problemi di lunghezza, virgola, decimali, ecc.

Con la strlen si conosce la lunghezza della stringa.

FedeWar
08-03-2012, 19:15
Grazie a tutti per l' aiuto

ESSE-EFFE
08-03-2012, 19:37
Originariamente inviato da ramy89
Con la strlen si conosce la lunghezza della stringa.
Non è così facile. Dall'altra parte ci sarà un socket a ricevere e non sa a priori quanto è lungo il dato. Quindi o si invia anche un separatore (il terminatore nullo ad esempio) oppure si invia la lunghezza della stringa. Con l'altra soluzione non serve, basta conoscere il protocollo (ma questo in entrambi i casi) e la lettura tra l'altro è molto più semplice.

ramy89
08-03-2012, 22:12
Originariamente inviato da ESSE-EFFE
Non è così facile. Dall'altra parte ci sarà un socket a ricevere e non sa a priori quanto è lungo il dato. Quindi o si invia anche un separatore (il terminatore nullo ad esempio) oppure si invia la lunghezza della stringa. Con l'altra soluzione non serve, basta conoscere il protocollo (ma questo in entrambi i casi) e la lettura tra l'altro è molto più semplice.

Non è vero, la sprintf ovviamente scrive anche il terminatore.
Tutte le stringhe in C finiscono col terminatore.
Quindi non serve alcun dato aggiuntivo, basta usare la strlen.

ESSE-EFFE
09-03-2012, 08:43
Originariamente inviato da ramy89
Non è vero, la sprintf ovviamente scrive anche il terminatore.
Non mi sembra di aver scritto il contrario...


Originariamente inviato da ramy89 Tutte le stringhe in C finiscono col terminatore. Quindi non serve alcun dato aggiuntivo, basta usare la strlen.
Sì, ma lo scopo non era quello di formattare il dato in una stringa, ma di inviarlo su uno stream. Quindi, inviando come stringa, un separatore (ad esempio il terminatore nullo) va aggiunto per ogni dato inviato. Di solito, invece, si tengono i dati da inviare in una struttura e si invia quella esattamente come è in memoria. E anche la lettura diventa più semplice. Prova.

ramy89
09-03-2012, 20:34
Originariamente inviato da ESSE-EFFE
Non mi sembra di aver scritto il contrario...


Ma lo dici di nuovo:



Quindi, inviando come stringa, un separatore (ad esempio il terminatore nullo) va aggiunto per ogni dato inviato


Se la sprintf lo aggiunge di suo, perchè dici che va aggiunto?



Di solito, invece, si tengono i dati da inviare in una struttura e si invia quella esattamente come è in memoria. E anche la lettura diventa più semplice. Prova.


E allora perchè non tenere tutto in un array allocato dinamicamente?
Se stai dicendo di inviare sizeof(double) byte, non è di certo la soluzione migliore perchè sizeof(double) non è uguale per tutte le macchine.



send(s,stringa,(int)strlen(stringa)+1,0);


E chi riceve la stringa riceve una dimensione fissa di caratteri (ad esempio 100), e usa la atof per convertire la stringa.
Secondo il tuo metodo si potrebbe fare così:



double val;
send(s,(char*)&val,sizeof(double),0);


Che è comunque interessante ma c'è il problema di sizeof(double) che anche se in genere è 8 byte, potrebbe non essere così.Lo steso vale per gli interi (sul mio computer li ho di 4 byte).

ESSE-EFFE
10-03-2012, 10:00
Originariamente inviato da ramy89
Se la sprintf lo aggiunge di suo, perchè dici che va aggiunto?
Va aggiunto allo stream, infatti anche tu hai aggiunto il +1.


Originariamente inviato da ramy89
Se stai dicendo di inviare sizeof(double) byte, non è di certo la soluzione migliore perchè sizeof(double) non è uguale per tutte le macchine.
Quello fa parte del protocollo, ci possono essere anche altre differenze. Ma il protocollo va conosciuto a prescindere, anche nel tuo caso.


Originariamente inviato da ramy89
E chi riceve la stringa riceve una dimensione fissa di caratteri (ad esempio 100), e usa la atof per convertire la stringa.
Se invii il separatore non ha senso che il campo abbia dimensione fissa. Se ha dimensione fissa non serve inviare il separatore.


Originariamente inviato da ramy89
Secondo il tuo metodo si potrebbe fare così:
Ti ringrazio, ma non è il "mio" metodo. In genere, quando si inviano dati binari, si fa come ho spiegato. Non che non si possa fare tramite stringhe, e quindi in ASCII, ma di solito in quel caso siamo in contesti diversi (HTTP ad esempio).

Loading