Ciao,
connessione client-server TCP
formato del pacchetto che devo inviare
|un intero (lunghezza campo dati) | campo dati |
devo inviare con la send un int il quale rappresenta la lunghezza di una stringa che verrà inviata subito dopo, in maniera che la recv possa sapere quanti byte è lungo il campo dati.
Il mio problema è il buffer dell'intero che non so proprio come farlo e il buffer della stringa ho il dubbio :
se invio la stringa "casa/0" , al ricevitore arriva prima la lettera "c" o la "/0" ?
Questo è il mio codice:
int recvTCP(int sd, void* buf, int len)
{
int ret;
ret = recv(sd,buf,len,0);
if (ret<len)
{
if(ret==0) //chiusura connessione da parte di un client oppure errore
{
//chiusura connessione da parte di un client oppure errore
FD_CLR(sd,&master); //rimuovo la socket dal master set
close(sd); //chiudo la socket
printf("%s si è disconnesso dal server\n",client->username);
if(client->impegnato==YES) //si è chiuso durante una partita quindi è un problema da notificare all'avversario
{
//notifica(client->enemy->socket);
}
if(client->ready==YES)
{
numerogiocatori--; //ho un giocatore pronto a giocare in meno
}
elem_remove(client); //rimuove l'elemento dalla lista connessi
return -1; //non ritorna nessun byte c'è solo stata una chiusura
}
return ret; //ritorna il numero di byte letti
}
return 0; // tutto ok
}
int riceviLength() //usando lo shift sistemo i byte in host order senza usare la funzione ntohl
{
//in realtà inviando un int per la dimensione invio ben 4byte, devo gestire un buffer per la lunghezza
int ret;
int temp; //al suo interno ci viene salvato il dato letto
ret = recvTCP(client->socket,&temp,4-client->last);
client->length=(client->length)<<(8*(ret));
client->length=(client->length)|temp;
if(ret<0) return -1; //c'è stata una chiusura della connessione già gestita dalla recvTCP o il dato è ricevuto correttamente
if (ret==0) //abbiamo finito di leggere
{
client->last=0;
return 0;
}
client->last=client->last-ret;
return ret;
}
int riceviMsg()
{
int ret;
ret = recvTCP(client->socket,&(client->buffer[client->last]),client->length);
if(ret<0) return -1; //c'è stata una chiusura della connessione
if(ret==0)
{
client->last=0; //rimetto a 0 la variabile che mi indica dove sono rimasto a leggere
return 0; //dato completamente ricevuto
}
client->last=ret;
client->length=(client->length)-(client->last); //aggiorno la lunghezza da leggere all'interno della struttura client
return ret;
}
La riceviLenght è iper provvisoria e credo di modificarla inviando l'intero convertendolo in una stringa , in maniera da gestire il buffer come con la riceviMsg().
La riceviMsg() viene richiamata dal main nel caso non sia finita la lettura ( lato server ho dovuto far così invece che con il while per evitare di bloccare la select , lato client ho fatto un while direttamente ) .
Il problema della riceviMsg è che ho paura che ricevo la stringa, ma la interpreto nell'ordine di arrivo sbagliato.
Spero possiate darmi una manina
Grazie in anticipo a tutti