Windows Sockets: Bytereihenfolge

In diesem Artikel und zwei Begleitartikeln werden verschiedene Probleme bei Windows Sockets-Programmierung erläutert. In diesem Artikel wird die Byte reihenfolge behandelt. Die anderen Probleme werden in den folgenden Artikeln behandelt: Windows Sockets: Blocking and Windows Sockets: Converting Strings.

Wenn Sie die CAsyncSocket-Klasse verwenden oder von ihr ableiten, müssen Sie diese Probleme selbst verwalten. Wenn Sie die CSocket-Klasse verwenden oder von ihr ableiten, werden sie von MFC für Sie verwaltet.

Bytereihenfolge

In verschiedenen Computerarchitekturen werden Daten manchmal mit unterschiedlichen Bytebestellungen gespeichert. Beispielsweise speichern Intel-basierte Computer Daten in umgekehrter Reihenfolge von Macintosh-Computern (Macintosh). Die Intel-Byte reihenfolge, die als "little-Endian" bezeichnet wird, ist auch die Umkehrung der "Big-Endian"-Reihenfolge des Netzwerkstandards. In der folgenden Tabelle werden diese Begriffe erläutert.

Groß- und Little-Endian Byte reihenfolge

Bytereihenfolge Bedeutung
Big-Endian Das wichtigste Byte befindet sich am linken Ende eines Worts.
Little-Endian Das wichtigste Byte befindet sich am rechten Ende eines Worts.

In der Regel müssen Sie sich keine Gedanken über die Konvertierung der Byte reihenfolge für Daten machen, die Sie über das Netzwerk senden und empfangen. Es gibt jedoch Situationen, in denen Sie Byteaufträge konvertieren müssen.

Wenn Sie Byteaufträge konvertieren müssen

Bytebestellungen müssen in den folgenden Situationen konvertiert werden:

  • Sie übergeben Informationen, die vom Netzwerk interpretiert werden müssen, im Gegensatz zu den Daten, die Sie an einen anderen Computer senden. Beispielsweise können Sie Ports und Adressen übergeben, die das Netzwerk verstehen muss.

  • Die Serveranwendung, mit der Sie kommunizieren, ist keine MFC-Anwendung (und Sie haben keinen Quellcode dafür). Dies erfordert Byteauftragskonvertierungen, wenn die beiden Computer nicht die gleiche Byte reihenfolge verwenden.

Wenn Sie keine Bytebestellungen konvertieren müssen

Sie können die Konvertierung von Byteaufträgen in den folgenden Situationen vermeiden:

  • Die Computer an beiden Enden können zustimmen, bytes nicht zu tauschen, und beide Computer verwenden die gleiche Byte reihenfolge.

  • Der Server, mit dem Sie kommunizieren, ist eine MFC-Anwendung.

  • Sie verfügen über Quellcode für den Server, mit dem Sie kommunizieren, damit Sie explizit erkennen können, ob Sie Byteaufträge konvertieren müssen.

  • Sie können den Server zu MFC portieren. Dies ist recht einfach, und das Ergebnis ist in der Regel kleinerer, schnellerer Code.

Bei der Arbeit mit CAsyncSocket müssen Sie alle erforderlichen Konvertierungen der Byte reihenfolge selbst verwalten. Windows Sockets standardisiert das "Big-Endian"-Byte-Order-Modell und stellt Funktionen zum Konvertieren zwischen dieser Reihenfolge und anderen funktionen zur Verfügung. CArchive, das Sie jedoch mit CSocket verwenden, verwendet die umgekehrte ("little-Endian")-Reihenfolge, CArchive übernimmt jedoch die Details der Konvertierungen der Byte reihenfolge für Sie. Indem Sie diese Standard reihenfolge in Ihren Anwendungen oder Windows Sockets-Byte reihenfolgenkonvertierungsfunktionen verwenden, können Sie Ihren Code portierbarer machen.

Das ideale Argument für die Verwendung von MFC-Sockets ist, wenn Sie beide Enden der Kommunikation schreiben und dabei eine MFC-Bibliothek an beiden Enden verwenden. Wenn Sie eine Anwendung schreiben, die mit Nicht-MFC-Anwendungen wie einem FTP-Server kommuniziert, müssen Sie den Bytetausch wahrscheinlich selbst verwalten, bevor Sie Daten mithilfe der Windows Sockets-Konvertierungsroutinen ntohs, ntprotokoll, htons und htonl an das Archivobjekt übergeben. Ein Beispiel für diese Funktionen, die bei der Kommunikation mit einer Nicht-MFC-Anwendung verwendet werden, finden Sie weiter später in diesem Artikel.

Hinweis

Wenn das andere Ende der Kommunikation keine MFC-Anwendung ist, müssen Sie auch das Streamen von C CObject ++-Objekten vermeiden, die von in Ihr Archiv abgeleitet wurden, da der Empfänger sie nicht verarbeiten kann. Weitere Informationen finden Sie in Windows Sockets: Using Sockets with Archives (Verwenden von Sockets mit Archiven).

Weitere Informationen zu Bytebestellungen finden Sie in der Windows Sockets-Spezifikation, die im Windows SDK verfügbar ist.

Beispiel Byte-Order Konvertierung

Das folgende Beispiel zeigt eine Serialisierungsfunktion für ein - CSocket Objekt, das ein Archiv verwendet. Außerdem wird die Verwendung der Konvertierungsfunktionen in bytegeordneter Reihenfolge in der Windows Sockets-API veranschaulicht.

Dieses Beispiel zeigt ein Szenario, in dem Sie einen Client schreiben, der mit einer Nicht-MFC-Serveranwendung kommuniziert, für die Sie keinen Zugriff auf den Quellcode haben. In diesem Szenario müssen Sie davon ausgehen, dass der Nicht-MFC-Server die Standardmäßige Netzwerk-Byte reihenfolge verwendet. Im Gegensatz dazu verwendet Ihre MFC-Clientanwendung CArchiveCSocket ein -Objekt mit einem -Objekt und CArchive die Byte reihenfolge "little-Endian", das Gegenteil des Netzwerkstandards.

Angenommen, der Nicht-MFC-Server, mit dem Sie kommunizieren möchten, verfügt über ein eingerichtetes Protokoll für ein Nachrichtenpaket wie das folgende:

struct Message
{
   long MagicNumber;
   unsigned short Command;
   short Param1;
   long Param2;
};

In MFC-Begriffen würde dies wie folgt ausgedrückt werden:

struct Message
{
   long m_lMagicNumber;
   short m_nCommand;
   short m_nParam1;
   long m_lParam2;

   void Serialize(CArchive &ar);
};

In C++ ist ein struct im Wesentlichen dasselbe wie eine Klasse. Die Message -Struktur kann Memberfunktionen haben, z. B. die Serialize oben deklarierte Memberfunktion. Die Serialize Memberfunktion könnte wie die folgenden aussehen:

void Message::Serialize(CArchive &ar)
{
   if (ar.IsStoring())
   {
      ar << (DWORD)htonl(m_lMagicNumber);
      ar << (WORD)htons(m_nCommand);
      ar << (WORD)htons(m_nParam1);
      ar << (DWORD)htonl(m_lParam2);
   }
   else
   {
      WORD w;
      DWORD dw;
      ar >> dw;
      m_lMagicNumber = ntohl((long)dw);
      ar >> w;
      m_nCommand = ntohs((short)w);
      ar >> w;
      m_nParam1 = ntohs((short)w);
      ar >> dw;
      m_lParam2 = ntohl((long)dw);
   }
}

In diesem Beispiel werden Konvertierungen der Byte reihenfolge von Daten aufgrund eines eindeutigen Konflikts zwischen der Byte reihenfolge der Nicht-MFC-Serveranwendung CArchive auf einem Ende und der in der MFC-Clientanwendung auf der anderen Seite verwendet. Das Beispiel veranschaulicht einige der Konvertierungsfunktionen in Byte reihenfolge, die Windows Sockets liefern. In der folgenden Tabelle werden diese Funktionen beschrieben.

Windows Von Sockets Byte-Order Konvertierungsfunktionen

Funktion Zweck
ntohs Konvertieren einer 16-Bit-Menge aus der Netzwerk-Byte reihenfolge in die Host-Byte-Reihenfolge (big-Endian in little-Endian).
nt durch Konvertieren einer 32-Bit-Menge aus der Netzwerk-Byte reihenfolge in die Host-Byte-Reihenfolge (big-Endian in little-Endian).
Htons Konvertieren einer 16-Bit-Menge von der Host-Byte-Reihenfolge in die Netzwerk-Byte reihenfolge (little-Endian in big-Endian).
Htonl Konvertieren einer 32-Bit-Menge von der Host-Byte-Reihenfolge in die Netzwerk-Byte reihenfolge (little-Endian in big-Endian).

Ein weiterer Punkt dieses Beispiels ist, dass Sie folgende Schritte vermeiden müssen, wenn es sich bei der Socketanwendung am anderen Ende der Kommunikation um eine Nicht-MFC-Anwendung handelt:

ar << pMsg;

, pMsg wobei ein Zeiger auf ein von der Klasse abgeleitetes C++-Objekt ist CObject. Dadurch werden zusätzliche MFC-Informationen gesendet, die Objekten zugeordnet sind, und der Server versteht sie nicht, wie es bei einer MFC-Anwendung der Fall wäre.

Weitere Informationen finden Sie unter

Weitere Informationen

Windows-Sockets in MFC