Hey Leute, Frage von einem C / Networking-Neuling ...
Ich mache eine Socket-Programmierung in C und versuche, mit Byte-Ordnungsproblemen zu ringen. Meine Anfrage (Senden) ist in Ordnung, aber wenn ich Daten erhalte, sind meine Bytes nicht in Ordnung. Ich beginne mit so etwas ...
%Vor%Wenn man sich mit dieser Antwort beschäftigt, scheint jedes 16-Bit-Wort seine Bytes umzukehren (ich benutze UDP). Ich habe versucht, das zu beheben, indem ich so etwas mache ...
%Vor%Das funktioniert gut, wenn ich die Daten als Kurzform behandle, aber wenn ich den Zeiger wieder auf ein Zeichen setze, werden die Bytes umgekehrt. Was mache ich falsch?
Danke!
Ok, es scheint Probleme auf zwei verschiedenen Ebenen zu geben. Ein Teil der Verwirrung scheint hier auf die Verwendung von Zeigern zurückzuführen zu sein, auf welche Art von Objekten sie zeigen, und dann auf die Interpretation der Kodierung der Werte im Speicher, auf die der Zeiger zeigt.
Die Codierung von Multi-Byte-Entitäten im Speicher wird als Endianess bezeichnet. Die beiden üblichen Kodierungen werden als Little Endian (LE) und Big Endian (BE) bezeichnet. Bei LE wird eine 16-Bit-Menge wie ein Kurzschluss zuerst als niedrigstwertiges Byte (LSB) codiert. Unter BE wird das höchstwertige Byte (MSB) zuerst codiert.
Per Konvention kodieren Netzwerkprotokolle normalerweise Dinge in etwas, das wir "Netzwerk-Byte-Reihenfolge" (NBO) nennen, das auch dasselbe ist wie BE. Wenn Sie Speicherpuffer auf Big-Endian-Plattformen senden und empfangen, treten keine Konvertierungsprobleme auf. Ihr Code wäre dann jedoch plattformabhängig von der BE-Konvention. Wenn Sie portablen Code schreiben möchten, der sowohl auf LE- als auch BE-Plattformen korrekt funktioniert, sollten Sie nicht von der Endgültigkeit der Plattform ausgehen.
Endian-Portabilität ist das Ziel von Routinen wie ntohs () , ntohl () und > htons () und htonl () . Diese Funktionen / Makros sind auf einer bestimmten Plattform definiert, um die erforderlichen Konvertierungen am sendenden und empfangenden Ende durchzuführen:
Verstehen Sie, dass Ihr Kommentar über den Zugriff auf den Speicher bei der Rückgabe an Zeichen keinen Einfluss auf die tatsächliche Reihenfolge der Entitäten im Speicher hat. Das heißt, wenn Sie auf den Puffer als eine Reihe von Bytes zugreifen, sehen Sie die Bytes in der Reihenfolge, in der sie tatsächlich in den Speicher geschrieben wurden, unabhängig davon, ob Sie eine BE- oder LE-Maschine haben. Wenn Sie also nach dem Empfang einen NBO-codierten Puffer betrachten, wird das MSB zuerst - immer. Wenn Sie nach der Konvertierung in die Host-Reihenfolge den Ausgabepuffer betrachten, bleibt die Byte-Reihenfolge unverändert, wenn Sie eine BE-Maschine haben. Umgekehrt werden die Bytes auf einer LE-Maschine nun alle im konvertierten Puffer umgekehrt.
Schließlich bezieht sich die Variable total
in Ihrer Konvertierungsschleife auf Bytes. Sie greifen jedoch auf den Puffer als shorts
zu. Ihr Schleifenwächter sollte nicht total
sein, sollte aber:
total / sizeof( unsigned short )
, um die Doppelbyte-Natur jedes short
zu berücksichtigen.
Das funktioniert, wenn ich die Daten als Kurzform behandle, aber wenn ich den Zeiger erneut auf ein Zeichen setze, werden die Bytes umgekehrt.
Das ist, was ich erwarten würde.
Was mache ich falsch?
Sie müssen wissen, was der Absender gesendet hat: wissen, ob es sich bei den Daten um Bytes handelt (die nicht reversiert werden müssen), oder um kurze oder lange (die das tun).
Google für Tutorials, die den APIs ntohs
, htons
und htons
zugeordnet sind.
Es ist nicht klar, was aResponse
darstellt (Zeichenkette? struct?). Endianness ist nur für numerische Werte relevant, nicht char
s. Sie müssen auch sicherstellen, dass auf der Senderseite alle numerischen Werte von Host in Netzwerk-Byte-Reihenfolge ( hton*
) konvertiert werden.
Abgesehen von Ihrer ursprünglichen Frage (die meiner Meinung nach bereits beantwortet wurde) sollten Sie sich Ihre malloc -Anweisung ansehen. malloc weist Bytes zu und eine vorzeichenlose Abkürzung ist höchstwahrscheinlich zwei Byte.
Ihre Aussage sollte wie folgt aussehen:
%Vor%Tags und Links c sockets endianness