Domanda

Ho un programma client server e dove voglio inviare un intero struct dal client e poi in uscita il membro struct "ID" sul server.

Ho fatto tutto l'etc collegamento e già riusciti a inviare una stringa attraverso:

send(socket, string, string_size, 0);

Quindi, è possibile inviare una struttura invece di una stringa attraverso send ()? Posso sostituire il mio tampone sul server per essere uno struct vuoto dello stesso tipo e andare?

È stato utile?

Soluzione

Welll ... inviare le strutture attraverso la rete è un po 'difficile se si sta facendo in modo corretto.

Carl è giusto - è possibile inviare una struct attraverso una rete dicendo:

send(socket, (char*)my_struct, sizeof(my_struct), 0);

Ma ecco la cosa:

  • sizeof (my_struct) potrebbe cambiare tra il client e il server. I compilatori spesso fanno una certa quantità di imbottitura e l'allineamento, quindi a meno che non si definisce l'allineamento in modo esplicito (forse utilizzando un pacchetto #pragma ()), che le dimensioni può essere diversa.
  • L'altro problema tende ad essere byte-ordine. Alcune macchine sono grandi-endian e altri sono little-endian, quindi la disposizione dei byte potrebbero essere differenti. In realtà, a meno che il server o client è in esecuzione su hardware non Intel (che probabilmente non è il caso), allora questo problema esiste più in teoria che in pratica.

Quindi la soluzione la gente spesso propongono è quello di avere una routine che serializza lo struct. Cioè, invia il membro di dati struct uno alla volta, in modo che il client e il server solo send () e recv () il numero esatto di byte specificato che si codifica nel programma.

Altri suggerimenti

sono le macchine client e server "lo stesso"? Quello che proponete funzionerà solo se i compilatori C ad ogni estremità lay out la struttura in memoria esattamente lo stesso. Ci sono un sacco di ragioni per cui questo non può essere il caso. Per esempio i macines client e server potrebbero avere diverse architetture, quindi il loro modo di rappresentare i numeri in memoria (big-endian, little-endian) potrebbe differire. Anche se i clienti macchine e macchina server hanno la stessa architettura di due diversi compilatori C possono avere politiche diverse per il modo in cui lay out le strutture in memoria (ad es. Imbottitura tra i campi per allineare int sui confini di parola). Anche il stesso conmpiler con diverse bandiere potrebbe dare risultati diversi.

In concreto, sto cercando di indovinare che il client e il server sono lo stesso tipo di macchina e così ciò che si sta proponendo lavorerò, tuttavia è necessario essere consapevoli del fatto che, come regola generale non lo farà ed è per questo standard come CORBA sono stati inventati, o perché la gente usa un po 'di rappresentazione generale come XML.

È possibile, se il client e il server hanno steso la struct esattamente nello stesso modo, il che significa che i campi sono tutti della stessa dimensione, con la stessa imbottitura. Per esempio se si dispone di un long nella vostra struct, che potrebbe essere 32bit su una macchina e 64 bit, dall'altro, nel qual caso lo struct non verrà ricevuto correttamente.

Nel tuo caso, se il client e il server sono sempre sarà su implementazioni C molto simili (ad esempio se questo è solo il codice che si sta utilizzando per imparare alcuni concetti di base, o se per qualche altro motivo si conosce il codice sempre e solo avere per funzionare sul vostro attuale versione di OSX), allora probabilmente si può farla franca. Basta ricordare che il codice non necessariamente funziona correttamente su altre piattaforme, e che non c'è più lavoro da fare prima che sia adatto per l'uso nella maggior parte delle situazioni del mondo reale.

Per la maggior parte delle applicazioni client-server, questo significa che la risposta è che non si può fare in generale. Quello che effettivamente fare è definire il messaggio in termini di numero di byte inviati, che ordine, che cosa significano, e così via. Poi ad ogni estremità, fai qualcosa piattaforma specifica per garantire che lo struct si sta utilizzando ha esattamente il layout desiderato. Anche così, potrebbe essere necessario fare un po 'di byte-swapping, se si sta inviando i membri interi della struct little-endian, e poi si desidera che il codice eseguito su un big-endian macchina. formati di interscambio di dati come XML, JSON e buffer di protocollo di Google esistere in modo che non si deve fare questa roba poco pratici.

[Edit: anche ricordare, naturalmente, che alcuni membri struct non possono mai essere inviati attraverso la rete. Ad esempio se la struttura ha un puntatore in esso, l'indirizzo si riferisce alla memoria sul fax trasmittente, ed è inutile sul lato di ricezione. Mi scuso se questo è già evidente a voi, ma di certo non è evidente a tutti quando stanno solo cominciando con C].

È possibile, ma è necessario essere consapevoli di 2 cose importanti.

  1. I programmi su entrambe le estremità devono essere ABI compatibili. Essi sono di solito se entrambe le estremità eseguito sulla stessa architettura di processore, stesso sistema operativo, compilato con lo stesso compilatore e del compilatore bandiere.
  2. TCP è un flusso. È necessario assicurarsi che si sta inviando tutta la struct. Guardate la documentazione per la chiamata send () - restituisce il nr di byte inviati - che potrebbe essere meno di quanto si è detto di. Stesso sul lato ricevente. Solo perché hai inviato la struct con 1 chiamata di invio, non significa che si avrà con 1 chiamata RECV. Si rendono necessari diversi chiamata recv per ottenere tutti i pezzi.

Sì, le strutture dello stesso tipo sono tutti delle stesse dimensioni. Se si ottiene il puntatore fusione destra sta bene ad andare.

In generale, è una cattiva idea di fare questo, anche se il client e il server si rivelano per disporre la struttura in memoria allo stesso modo.

Anche se non avete intenzione di passare strutture dati più complesse (che comporterebbe puntatori) avanti e indietro, vi consiglio di serializzare i dati prima di inviarlo attraverso la rete.

Invia i dati come file di testo e poi decodificarlo dopo averlo ricevuto. Questo è il modo migliore se si desidera che i dati come il suo inviati !!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top