Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra integra un sensore da 1 pollice 8K, ottiche Leica e triplo chip IA. Tra schermo OLED rimovibile, workflow I-Log a 10 bit e stabilizzazione a tre assi, analizziamo le doti tecniche di una gimbal camera pensata per i professionisti
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 25-03-2006, 18:13   #1
Abdujaparov
Senior Member
 
Iscritto dal: Aug 2004
Città: Palermo
Messaggi: 1079
C programmazione socket, problemino, spero semplice.

Salve a tutti, ho un piccolo problemino. Sto scrivendo un semplice client ed un semplice server che scambiano i dati in binario, dopo averli convertiti in formato di rete.
Ora i dati devo essere inviati in questo ordine. Un primo byte con un numero, un altro byte con la dimensione del numero nei restanti byte, cioè invio un byte con il numero 8, poi invio il secondo byte con la dimensione del numero che invio come terzo argomento, per esempio 2 se invio un uint16_t, 4 se invio un uint32_t e poi invio il numero uint16_t o uint32_t.
Ora ho i seguenti problemini:
1) i primi due byte contengono un uint8_t ciascuno, come posso applicare la conversione in formato di rete (ntohs) se questa funzione mi restituisce un uint16_t?
2)Io per inviare questi dati al server li scrivo ad uno ad uno sul socket, per leggerli sul server io ho messo una read senza altri accorgimenti ma così facendo mi viene letto solo il primo numero, come faccio a far leggere gli altri due?
3)Se volessi mettere i dati da inviare in un buffer e poi inviare il buffer come dovrei fare? Io creo un array di char, nelle prime due posizioni inserisco i primi due byte, nelle restanti posizioni come posso copiare il terzo numero che sta su più byte?

Grazie a tutti, ciao ciao.
Abdujaparov è offline   Rispondi citando il messaggio o parte di esso
Old 25-03-2006, 20:35   #2
mr_hyde
Senior Member
 
Iscritto dal: Oct 2005
Città: Genova
Messaggi: 937
Non credo di aver capito bene...

Ricorda che vanno convertiti solo i tipi di dati che vengono memorizzati su piu' byte (quindi gli interi che sono su 2 o 4 byte).
Per i byte "singoli" invece non ci sono problemi, non c'e' la necessita' di convertirli.

Se ho capito bene, il tuo "pacchetto dati" e' una cosa del tipo:

typedef BYTE unsigned char;

BYTE the_id; /* vale sempre 8*/
BYTE the_size; /* contiene un valore numerico corrispondente al numero di byte che seguono */
BYTE* the_buffer; /* e' l'array di byte spedito/ricevuto, grande quanto indicato da the_size */

Se ho capito bene, puoi fare la segg. cosa per ricevere:

typedef struct headerTemplate {
BYTE the_id; /* vale sempre 8*/
BYTE the_size; /* contiene un valore numerico corrispondente al numero di byte che seguono */
} __attrbute__(packed)) headerType;


/* prima di tutto ricevo il pacchetto */
int rslt;
headerType the_header;
BYTE* pBuffer = NULL;

rslt = recv(socketId, (void*) &the_header, sizeof(headerType));
if (rslt < 0)
{
/* qualcosa e' andato storto */
perror("recv - some problem");
close(socketId);
return;
}

/* controllo l'id del pacchetto */
if (the_header.the_id != VALORE_CHE_MI_ASPETTO)
{
fprintf(stderr, "Got unexpected header. Id = 0x%2x\n", the_header.the_id);
close(socketId);
return;
}

/* a questo punto posso creare un buffer per ricevere il dato vero e proprio */
/* preparo il buffer di ricezione */
pBuffer = malloc(the_header.the_size);
if (pBuffer == NULL)
{
perror("malloc");
close(socketId);
return;
}

/* ed ora ricevo realmente il buffer */
rslt = recv(socketId, (void*) pBuffer, the_header.the_size);
if (rslt < 0)
{
/* qualcosa e' andato storto */
perror("recv - some problem while receiving data");
close(socketId);
return;
}


/* elabora pBuffer */


free(pBuffer);
close(socketId);

NOTA: l'ho buttata giu' cosi', sicuramente ci sono errori, quindi non prendere queste 2 istruzioni come oro colato!

NOTA2: eventualmente e' nel punto "elabora pBuffer" che devi usare le funzioni di conversione sul buffer ricevuto

NOTA3: ho scritto la struttura dell'header SOLO PER "DIDATTICA" (in questo semplice esempio non mi sembra che in realta' serva) infatti senza l'attributo packed, NON e' detto che la sizeof di una struttura corrisponda alla somma delle sieof dei singoli componenti della struttura.

Spero che come traccia ti possa andar bene.

Ciao,
Mr Hyde
__________________
MacMini Late 2009/MacMini 2018
mr_hyde è offline   Rispondi citando il messaggio o parte di esso
Old 26-03-2006, 22:11   #3
Abdujaparov
Senior Member
 
Iscritto dal: Aug 2004
Città: Palermo
Messaggi: 1079
Grazie per l'aiuto, in pratica io devo creare un server per un client di cui conosco solo il protocollo di comunicazione e quindi sto cercando di replicare un client di prova per testare il server. Per inviare i dati uso una struttura solo che c'è qualche problemino sulla dimensione dei dati inviati.
Io invio la struttura al server che effettivamente riceve 4 byte, poi cerco di far rispondere il server e invio una struttura con un byte che indica lo stato e due bytes che indicano il risultato di un'operazione, solo che quando invio i dati la struttura mi viene detto che è composta da 4 byte e non da 3 byte come dovrebbe essere. Un'altra cosa, il mio client dopo aver inviato i dati dovrebbe rimanere in attesa di una risposta dal server solo che mi viene lanciato un errore di segmentation fault.
Un'altra cosa se io volessi inviare i dati al server scrivendo 3 write es:

write(socket, primoByte, sizeof(primoByte));
write(socket, secondoByte, sizeof(secondoByte));
write(socket, ultimi2Byte, sizeof(ultimi2oByte));

Nel server cosa dovrei mettere per leggere tutti e 4 i byte?
Una semplice n=Read(socket,rbuf,MAXBUFF) non funziona, mi legge solo il primo byte. Come dovrei modificare il server per far ricevere sia i byte inviati in questo modo che quelli inviati con una struttura? Il client che sto scrivendo io è solo un "emulatore" per un client che non ho ma di cui ho solo le specifice sul protocollo di comunicazione.

Ti allego le parti che mi danno problemi.
Server:
uint16_t ris = sqrtn(base2, radice); //effettuo l'operazione radice n-esima
ris=htons(ris); // converto il risultato in formato di rete
struct risposta{uint8_t uris; uint16_t risultato;} dati; //definisco la struttura (dovrebbe essere 3 byte)
dati.uris=0; //imposto lo stato
dati.risultato=ris; //assegno risultato
#ifdef TRACE
err_msg("La dimensione dello stato è: %u\n", sizeof(dati.uris)); //mi viene dato 1
err_msg("La dimensione del risultato è: %u\n", sizeof(dati.risultato)); //mi viene dato 2
err_msg("La dimensione della risposta è: %u\n", sizeof(dati)); //mi viene dato 4?? Io devo rispondere per forza con 3 byte
#endif
Writen(connfd, &dati, sizeof(dati)); //invio i dati

Client:
invio.radice=3; //imposto i dati della struttura che invio
invio.dim=sizeof(pippo);
invio.operando=pippo;

#ifdef TRACE
err_msg("Dati inviati: %u\n", sizeof(invio));//la dimensione della struttura qua è correttamente 4
#endif

Writen(socket,&invio,sizeof(invio)); //invio la struttura
//qua mi viene dato segmentation fault, cosa posso avere sbagliato?
n=Read(socket,rbuf,MAXBUFF);

Grazie, ciao ciao.
Abdujaparov è offline   Rispondi citando il messaggio o parte di esso
Old 26-03-2006, 22:24   #4
mr_hyde
Senior Member
 
Iscritto dal: Oct 2005
Città: Genova
Messaggi: 937
Mi auto-quoto per quanto riguarda la tua struttura che DOVREBBE essere di 3 byte ma in realta' e' di quattro:

Quote:
NOTA3: ho scritto la struttura dell'header SOLO PER "DIDATTICA" (in questo semplice esempio non mi sembra che in realta' serva) infatti senza l'attributo packed, NON e' detto che la sizeof di una struttura corrisponda alla somma delle sieof dei singoli componenti della struttura.
__attribute__((packed)) e' la "clausola" che si usa con il compilatore gcc e su altri compilatori sotto Unix, se tu ne usi altri probabilmente devi mettere una cosa tipo "PACKED": questo fa in modo che gli elementi di una struttura vengano memorizzati esattamente uno consecutivamente all'altro e che non vengano aggiunti altri pezzi in coda (altrimenti il compilatore, per motivi vari, puo' decidere di fare diversamente).

Per il resto: ora e' un po' tardi, leggero' un po' meglio il messaggio e poi ti rispondero'

Ciao,
Mr Hyde
__________________
MacMini Late 2009/MacMini 2018
mr_hyde è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 06:31   #5
Abdujaparov
Senior Member
 
Iscritto dal: Aug 2004
Città: Palermo
Messaggi: 1079
Ti ringrazio per l'informazione sulla struct solo che il server deve essere compilato sotto varie piattaforme e non solo uni e questo potrebbe essere un problema, per questo sarebbe interessante capire come inserire i dati in un array di char o come ricevere i dati dopo 3 write consecutive.
Grazie, ciao ciao.
Abdujaparov è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 22:51   #6
mr_hyde
Senior Member
 
Iscritto dal: Oct 2005
Città: Genova
Messaggi: 937
Quote:
Originariamente inviato da Abdujaparov
Grazie per l'aiuto, in pratica io devo creare un server per un client di cui conosco solo il protocollo di comunicazione e quindi sto cercando di replicare un client di prova per testare il server. Per inviare i dati uso una struttura solo che c'è qualche problemino sulla dimensione dei dati inviati.
Io invio la struttura al server che effettivamente riceve 4 byte, poi cerco di far rispondere il server e invio una struttura con un byte che indica lo stato e due bytes che indicano il risultato di un'operazione, solo che quando invio i dati la struttura mi viene detto che è composta da 4 byte e non da 3 byte come dovrebbe essere. Un'altra cosa, il mio client dopo aver inviato i dati dovrebbe rimanere in attesa di una risposta dal server solo che mi viene lanciato un errore di segmentation fault.
Un'altra cosa se io volessi inviare i dati al server scrivendo 3 write es:

write(socket, primoByte, sizeof(primoByte));
write(socket, secondoByte, sizeof(secondoByte));
write(socket, ultimi2Byte, sizeof(ultimi2oByte));

Nel server cosa dovrei mettere per leggere tutti e 4 i byte?
Una semplice n=Read(socket,rbuf,MAXBUFF) non funziona, mi legge solo il primo byte. Come dovrei modificare il server per far ricevere sia i byte inviati in questo modo che quelli inviati con una struttura?
Io generalmente uso recv, ma il comportamento dovrebbe essere lo stesso di read.
Quindi se fai:

char buffer[4];
int n;
n = read(socket, (void*) buffer, 4)

ti viene in realta':
1) restituito 1
2) letto quindi solo il primo byte?

In teoria dovrebbe funzionare, la read restituisce un numero minore rispetto alla lunghezza solo in alcune condizioni (signal, errori...).
Un dubbio: non e' che dal lato server chiudi la connessione non appena spediti i 3 byte?


Quote:
Il client che sto scrivendo io è solo un "emulatore" per un client che non ho ma di cui ho solo le specifice sul protocollo di comunicazione.

Ti allego le parti che mi danno problemi.
Server:
Codice:
	uint16_t ris = sqrtn(base2, radice); //effettuo l'operazione radice n-esima
	ris=htons(ris); // converto il risultato in formato di rete
	struct risposta{uint8_t uris; uint16_t risultato;} dati; //definisco la struttura (dovrebbe essere 3 byte)
dall'altro 3ad ho visto che l'hai resa packed, spero quindi che questo abbia risolto il problema della lunghezza strana

Quote:
Codice:
	dati.uris=0; //imposto lo stato
	dati.risultato=ris; //assegno risultato
	#ifdef TRACE
            err_msg("La dimensione dello stato è: %u\n", sizeof(dati.uris)); //mi viene dato 1
	    err_msg("La dimensione del risultato è: %u\n", sizeof(dati.risultato)); //mi viene dato 2
            err_msg("La dimensione della risposta è: %u\n", sizeof(dati)); //mi viene dato 4?? Io devo rispondere per forza con 3 byte
      	#endif
       Writen(connfd, &dati, sizeof(dati)); //invio i dati
scusa ma cosa fa la "writen"? Io su Linux non la ho

Quote:
Client:
Codice:
invio.radice=3; //imposto i dati della struttura che invio
invio.dim=sizeof(pippo); 
invio.operando=pippo;

#ifdef TRACE
    err_msg("Dati inviati: %u\n", sizeof(invio));//la dimensione della struttura qua è correttamente 4	
#endif
Attento quando usi la sizeof con il nome di una variabile invece che con il tipo: puoi sbagliare specialmente nel passaggio di parametri, quando passi ad una funzione un array.

Per maggiori dettagli sull'uso di sizeof vedi

http://publications.gbdirect.co.uk/c...nd_malloc.html

(sul fondo della pagina e' riportato un errore comune)

Quote:
Codice:
Writen(socket,&invio,sizeof(invio)); //invio la struttura
//qua mi viene dato segmentation fault, cosa posso avere sbagliato?
n=Read(socket,rbuf,MAXBUFF);
Ti riferisci alla read?
Non vedo la dichiarazione di rbuf e neppure la definizione di MAXBUFF, Sicuro sia tutto ok?

Ciao,
Mr Hyde
__________________
MacMini Late 2009/MacMini 2018
mr_hyde è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Intel e SK hynix al tavolo per un'allean...
Osservare la Luna con la NASA, anche in ...
Wallbox per auto elettriche su Amazon: d...
Il mistero della stagione degli uragani ...
La Corte di Cassazione affida i ricorsi ...
Tutti i nuovi prodotti Apple prenotabili...
DDR5, un kit da 598 a 1.215 euro in un m...
Portatile ASUS Vivobook 14 a 837,95€: AM...
Sparita da anni, AppZapper torna nel 202...
Revolut, la truffa dei dati è partita da...
Geely E2: abbiamo visto dal vivo la regi...
HUAWEI Mate XT 2, importarlo dalla Cina ...
Orpheus, la calza smart che usa la music...
La causa antitrust di Musk contro Apple ...
Nitter archiviato e XCancel sospeso tre ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 10:56.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v