Ich versuche, die gesamte Struktur vom Client zum Server oder umgekehrt zu übergeben. Nehmen wir meine Struktur wie folgt an
struct temp {
int a;
char b;
}
ich benutze senden an und Senden der Adresse der Strukturvariablen und Empfangen auf der anderen Seite unter Verwendung der recvfrom Funktion. Aber ich bin nicht in der Lage, die ursprünglichen Daten zu erhalten, die auf der Empfängerseite gesendet werden. In der sendto-Funktion speichere ich die empfangenen Daten in einer Variablen vom Typ struct temp.
n = sendto(sock, &pkt, sizeof(struct temp), 0, &server, length);
n = recvfrom(sock, &pkt, sizeof(struct temp), 0, (struct sockaddr *)&from,&fromlen);
Wobei pkt die Variable vom Typ struct temp ist.
Ich erhalte zwar 8 Byte Daten, aber wenn ich versuche zu drucken, werden einfach Müllwerte angezeigt. Irgendwelche Hilfe für eine Lösung?
HINWEIS:Es müssen keine Bibliotheken von Drittanbietern verwendet werden.
EDIT1: Ich bin wirklich neu in diesem Serialisierungskonzept. Aber ohne Serialisierung kann ich keine Struktur über Sockets senden?
EDIT2: Wenn ich versuche, eine Zeichenfolge oder eine Integer-Variable mit dem zu senden senden an und recvfrom funktioniert Ich erhalte die Daten auf der Empfängerseite ordnungsgemäß. Warum nicht bei einer Struktur? Wenn ich keine Serialisierungsfunktion verwenden muss, sollte ich dann jedes einzelne Mitglied der Struktur einzeln senden? Dies ist wirklich keine geeignete Lösung, denn wenn es ‘n’ Mitglieder gibt, dann werden ‘n’ Codezeilen hinzugefügt, nur um Daten zu senden oder zu empfangen.
Können Sie Ihren Sende-/Empfangscode posten?
– Brian Agnew
16. Oktober 2009 um 9:52 Uhr
Warum machen Sie meine Änderungen rückgängig, um die seltsamen doppelten Fragezeichen zu korrigieren?
– abschalten
16. Oktober 2009 um 12:07 Uhr
Verwenden Sie keine Strukturen als Netzwerkprotokolle. Verwenden Sie Netzwerkprotokolle als Netzwerkprotokolle. Entwerfen Sie Ihr Protokoll in Oktetts und schreiben Sie sich eine Bibliothek, um es zu senden und zu empfangen. Oder verwenden Sie eine vorhandene wie DML, XDR, … Die Verwendung von Strukturen führt zu mindestens sechs Abhängigkeiten, die Sie möglicherweise nicht einmal kennen, und verursacht weitere Probleme wie diese.
– Benutzer207421
11. Juli 2014 um 21:34 Uhr
@EJP – Ich stimme dir zu
– Programmierfreak
12. März 2015 um 5:11 Uhr
entspannen
Das ist eine sehr schlechte Idee. Binäre Daten sollten immer so gesendet werden, dass:
Schreiben Sie niemals eine ganze Struktur binär, nicht in eine Datei, nicht in einen Socket.
Schreiben Sie jedes Feld immer separat und lesen Sie es auf die gleiche Weise.
Sie müssen Funktionen wie haben
unsigned char * serialize_int(unsigned char *buffer, int value)
{
/* Write big-endian int value into buffer; assumes 32-bit int and 8-bit char. */
buffer[0] = value >> 24;
buffer[1] = value >> 16;
buffer[2] = value >> 8;
buffer[3] = value;
return buffer + 4;
}
unsigned char * serialize_char(unsigned char *buffer, char value)
{
buffer[0] = value;
return buffer + 1;
}
unsigned char * serialize_temp(unsigned char *buffer, struct temp *value)
{
buffer = serialize_int(buffer, value->a);
buffer = serialize_char(buffer, value->b);
return buffer;
}
unsigned char * deserialize_int(unsigned char *buffer, int *value);
Oder das Äquivalent, es gibt natürlich mehrere Möglichkeiten, dies in Bezug auf die Pufferverwaltung und so weiter einzurichten. Dann müssen Sie die übergeordneten Funktionen ausführen, die ganze Strukturen serialisieren/deserialisieren.
Dies setzt voraus, dass die Serialisierung zu/von Puffern erfolgt, was bedeutet, dass die Serialisierung nicht wissen muss, ob das endgültige Ziel eine Datei oder ein Socket ist. Es bedeutet auch, dass Sie etwas Speicheraufwand bezahlen, aber es ist im Allgemeinen aus Leistungsgründen ein gutes Design (Sie möchten nicht jeden Wert in den Socket schreiben).
Sobald Sie das oben Gesagte haben, können Sie wie folgt eine Strukturinstanz serialisieren und übertragen:
@codingfreak: Sie haben wahrscheinlich auf derselben Maschine getestet. Haben Sie versucht, von der Bigendian-Maschine zur Littleendian-Maschine und umgekehrt zu wechseln?
– Ergebnisweg
26. März 2013 um 17:20 Uhr
@purpletech – Hmm, das könnte ein Problem sein
– Programmierfreak
12. März 2015 um 5:10 Uhr
qrdl
Es müssen keine eigenen Serialisierungsroutinen geschrieben werden short und long Integer-Typen – verwenden htons()/htonl() POSIX-Funktionen.
@qrdl: Meine Funktion auch, wie dokumentiert. Es wird immer nach Big-Endian serialisiert. Sie können natürlich auch htonX()/ntohX()-Funktionen verwenden, aber hier wurde versucht, einen allgemeineren Ansatz zu veranschaulichen.
– abschalten
16. Oktober 2009 um 11:47 Uhr
@codingfreak Ich habe nicht gesagt, es für die Struktur zu verwenden. Es ist der richtige Weg, kurze oder lange Ganzzahlen zu serialisieren, das war’s
– qrdl
16. Oktober 2009 um 12:50 Uhr
@qrdl – Aber meine Frage ist, wie man eine Struktur über Sockets sendet … auch ohne die Funktionen htons () / htonl () zu verwenden, kann ich Daten mit den Funktionen sendto () und recvfrom () ordnungsgemäß senden und empfangen …. .
– Programmierfreak
20. Oktober 2009 um 8:13 Uhr
@qrdl: Meine Funktionen setzen nichts über die Endianness des Hosts voraus.
– abschalten
20. Oktober 2009 um 10:25 Uhr
@unwind Mein Übel. Es tut mir leid, ich vergesse immer wieder, dass Shift Endianness-bewusst ist. Ich werde meinen Beitrag ändern
– qrdl
20. Oktober 2009 um 12:11 Uhr
Wenn Sie den Serialisierungscode nicht selbst schreiben möchten, finden Sie ein geeignetes Serialisierungsframework und verwenden Sie dieses.
Serialisierung ist eine gute Idee. Sie können auch verwenden Wireshark um den Datenverkehr zu überwachen und zu verstehen, was tatsächlich in den Paketen weitergegeben wird.
Anstatt zu serialisieren und von Bibliotheken von Drittanbietern abhängig zu sein, ist es einfach, ein primitives Protokoll mit Tag, Länge und Wert zu erstellen.
Tag: 32 bit value identifying the field
Length: 32 bit value specifying the length in bytes of the field
Value: the field
Verketten Sie nach Bedarf. Verwenden Sie Aufzählungen für die Tags. Und verwenden Sie die Netzwerk-Byte-Reihenfolge …
Einfach zu codieren, einfach zu decodieren.
Auch wenn Sie TCP verwenden, denken Sie daran, dass es a ist Strom von Daten, wenn Sie also zB 3 Pakete senden, werden Sie nicht unbedingt 3 Pakete empfangen. Sie können unter anderem abhängig vom Nodelay / Nagel-Algorithmus in einen Stream “zusammengeführt” werden, und Sie können sie alle in einem Recv erhalten … Sie müssen die Daten beispielsweise mit RFC1006 begrenzen.
UDP ist einfacher, Sie erhalten für jedes gesendete Paket ein eigenes Paket, aber es ist viel weniger sicher.
der_mandrill
Wenn das Format der Daten, die Sie übertragen möchten, sehr einfach ist, dann ist die Konvertierung in und aus einer ANSI-Zeichenfolge einfach und portabel.
@mandrill – Nehmen wir an, es ist komplex —- eine generische Lösung wäre die beste Antwort, wenn möglich … ??
– Programmierfreak
16. Oktober 2009 um 12:35 Uhr
Wenn das Format komplexer ist, verweise ich auf die überlegenen Lösungen, die an anderer Stelle in diesem Thread angegeben sind! Alternativ zu etwas allgemeinerem wie XML oder einem SOAP-ähnlichen Wrapper serialisieren.
– der_Mandrill
16. Oktober 2009 um 15:28 Uhr
Letztendlich besteht das Ziel darin, Ihre Daten portabel zu serialisieren, sodass die Konvertierung in und aus einer Zeichenfolge portabel, einfach und lesbar ist. Dies ist möglicherweise nicht die sicherste oder effizienteste Methode, erfordert jedoch keine Bibliotheken von Drittanbietern.
– der_Mandrill
16. Oktober 2009 um 15:31 Uhr
Wie konvertiere ich die Zeichenfolge wieder in die Daten, die in eine Struktur eingefügt werden können …. es wäre komplexer, denke ich?
– Programmierfreak
17. Oktober 2009 um 13:45 Uhr
Um die Zeichenfolge wieder in Daten umzuwandeln, müssten Sie die Zeichenfolge analysieren, indem Sie Dinge wie atof(), atoi(), sscanf() usw. verwenden (na ja, vielleicht nicht sscanf(), es ist gefährlich). Sie haben Recht, das Analysieren der Zeichenfolge kann für nicht einfache Daten komplex werden. Ich würde stattdessen die Verwendung einer Serialisierungsbibliothek eines Drittanbieters empfehlen.
– Jeremy Friesner
17. Oktober 2009 um 17:14 Uhr
14123800cookie-checkÜbergeben einer Struktur durch Sockets in Cyes
Können Sie Ihren Sende-/Empfangscode posten?
– Brian Agnew
16. Oktober 2009 um 9:52 Uhr
Warum machen Sie meine Änderungen rückgängig, um die seltsamen doppelten Fragezeichen zu korrigieren?
– abschalten
16. Oktober 2009 um 12:07 Uhr
Verwenden Sie keine Strukturen als Netzwerkprotokolle. Verwenden Sie Netzwerkprotokolle als Netzwerkprotokolle. Entwerfen Sie Ihr Protokoll in Oktetts und schreiben Sie sich eine Bibliothek, um es zu senden und zu empfangen. Oder verwenden Sie eine vorhandene wie DML, XDR, … Die Verwendung von Strukturen führt zu mindestens sechs Abhängigkeiten, die Sie möglicherweise nicht einmal kennen, und verursacht weitere Probleme wie diese.
– Benutzer207421
11. Juli 2014 um 21:34 Uhr
@EJP – Ich stimme dir zu
– Programmierfreak
12. März 2015 um 5:11 Uhr