Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Dreame Aqua10 Ultra Roller, la pulizia di casa con un rullo
Dreame Aqua10 Ultra Roller, la pulizia di casa con un rullo
Il più recente robot per la pulizia domestica di Dreame, modello Aqua10 Ultra Roller, abbina un potente motore di aspirazione della polvere a un sofisticato sistema di lavaggio con rullo integrato. Il tutto governato dalla logica di intelligenza artificiale, per i migliori risultati
Recensione Realme 15 Pro Game Of Thrones: un vero cimelio tech per pochi eletti
Recensione Realme 15 Pro Game Of Thrones: un vero cimelio tech per pochi eletti
Siamo volati fino a Belfast, capitale dell'Irlanda Del Nord, per scoprire il nuovo Realme 15 Pro 5G Game Of Thrones Limited Edition. Una partnership coi fiocchi, quella tra Realme e HBO, un esercizio di stile davvero ben riuscito. Ma vi raccontiamo tutto nel nostro articolo
GIGABYTE GAMING A16, Raptor Lake e RTX 5060 Laptop insieme per giocare al giusto prezzo
GIGABYTE GAMING A16, Raptor Lake e RTX 5060 Laptop insieme per giocare al giusto prezzo
Il Gigabyte Gaming A16 offre un buon equilibrio tra prestazioni e prezzo: con Core i7-13620H e RTX 5060 Laptop garantisce gaming fluido in Full HD/1440p e supporto DLSS 4. Display 165 Hz reattivo, buona autonomia e raffreddamento efficace; peccano però le USB e la qualità cromatica del pannello. Prezzo: circa 1200€.
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


Dreame Aqua10 Ultra Roller, la pulizia di casa con un rullo Dreame Aqua10 Ultra Roller, la pulizia di casa c...
Recensione Realme 15 Pro Game Of Thrones: un vero cimelio tech per pochi eletti Recensione Realme 15 Pro Game Of Thrones: un ver...
GIGABYTE GAMING A16, Raptor Lake e RTX 5060 Laptop insieme per giocare al giusto prezzo GIGABYTE GAMING A16, Raptor Lake e RTX 5060 Lapt...
iPhone 17 Pro: più di uno smartphone. È uno studio di produzione in formato tascabile iPhone 17 Pro: più di uno smartphone. &Eg...
Intel Panther Lake: i processori per i notebook del 2026 Intel Panther Lake: i processori per i notebook ...
Cina, effetto sanzioni USA: Cambricon - ...
La gamma Mac riceverà tante novit...
DDR5 supera i 13.000 MT/s, stavolta uffi...
Il nuovo iPhone con display pieghevole p...
ASUS ProArt PA32KCX: ecco a voi il primo...
DAZN ci riprova: piano Full a meno di 20...
Nuovi prezzi, più bassi: scendono...
PC Desktop HP Victus con RTX 4060 e Ryze...
Giù di altri 10€: solo 939€ per M...
Offerte Amazon da non credere: sconti fo...
Windows 11 scivola sugli aggiornamenti d...
Razer Kiyo V2: la nuova webcam 4K con AI...
ASUS ROG NUC 9: i mini PC (ex) Intel, ad...
Streaming illegale, il ministro dello Sp...
Microsoft avrebbe affidato a Intel la pr...
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: 04:16.


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