Windows Sockets: Beispiel für Sockets mithilfe der Archive
In diesem Artikel wird ein Beispiel für die Verwendung von Klassen-CSocket dargestellt. Im Beispiel werden CArchive
Objekte verwendet, um Daten über einen Socket zu serialisieren. Beachten Sie, dass dies keine Dokument serialisierung in oder aus einer Datei ist.
Im folgenden Beispiel wird veranschaulicht, wie Sie das Archiv zum Senden und Empfangen von Daten über CSocket
Objekte verwenden. Das Beispiel ist so konzipiert, dass zwei Instanzen der Anwendung (auf demselben Computer oder auf verschiedenen Computern im Netzwerk) Daten austauschen. Eine Instanz sendet Daten, die die andere Instanz empfängt und bestätigt. Entweder kann eine Anwendung einen Austausch initiieren und entweder als Server oder als Client für die andere Anwendung fungieren. Die folgende Funktion wird in der Ansichtsklasse der Anwendung definiert:
void PacketSerialize(long nPackets, CArchive &arData, CArchive &arAck)
{
BYTE bValue = 0;
WORD nCopies = 0;
if (arData.IsStoring())
{
CString strText;
errno_t err;
unsigned int number;
for (int p = 0; p < nPackets; p++)
{
err = rand_s(&number);
// if (err == 0)...
bValue = (BYTE)(number % 256);
err = rand_s(&number);
// if (err == 0)...
nCopies = (WORD)(number % 32000);
// Send header information
arData << bValue << nCopies;
for (int c = 0; c < nCopies; c++)
{
// Send data
arData << bValue;
}
strText.Format(_T("Sender sent packet %d of %d (Value = %d, Copies = %d)"),
p + 1, nPackets, (int)bValue, nCopies);
// Send receipt string
arData << strText;
arData.Flush();
// Receive acknowledgment
arAck >> strText;
// display it
DisplayMessage(strText);
}
}
else
{
CString strText;
BYTE bCheck;
for (int p = 0; p < nPackets; p++)
{
// Receive header information
arData >> bCheck >> nCopies;
for (int c = 0; c < nCopies; c++)
{
// Receive data
arData >> bValue;
if (bCheck != bValue)
{
AfxMessageBox(_T("Packet Failure"));
}
}
// Receive receipt string and display it
arData >> strText;
DisplayMessage(strText);
strText.Format(_T("Recipient received packet %d of %d (Value = %d, Copies = %d)"),
p + 1, nPackets, (int)bValue, nCopies);
// Send acknowledgment
arAck << strText;
arAck.Flush();
}
}
}
Das Wichtigste an diesem Beispiel ist, dass die Struktur parallel zu einer MFC-Funktion Serialize
ist. Die PacketSerialize
Memberfunktion besteht aus einer if
Anweisung mit einer else
Klausel. Die Funktion empfängt zwei CArchive-Verweise als Parameter: arData und arAck. Wenn das arData-Archivobjekt zum Speichern (Senden) festgelegt ist, wird die if
Verzweigung ausgeführt. Andernfalls wird arData zum Laden (Empfangen) festgelegt, übernimmt die Funktion die else
Verzweigung. Weitere Informationen zur Serialisierung in MFC finden Sie unter Serialisierung.
Hinweis
Das arAck-Archivobjekt wird angenommen, dass es sich um das Gegenteil von arData handelt. Wenn arData zum Senden dient, empfängt arAck und umgekehrt.
Beim Senden wird die Beispielfunktion für eine bestimmte Anzahl von Wiederholungen ausgeführt, wobei jedes Mal zufällige Daten zu Demonstrationszwecken generiert werden. Ihre Anwendung würde echte Daten aus einer Quelle abrufen, z. B. eine Datei. Der Einfügeoperator des arData-Archivs (<<) wird verwendet, um einen Datenstrom mit drei aufeinander folgenden Datenblöcken zu senden:
Ein "Header", der die Art der Daten angibt (in diesem Fall der Wert der bValue-Variablen und wie viele Kopien gesendet werden).
Beide Elemente werden zufällig für dieses Beispiel generiert.
Die angegebene Anzahl der Kopien der Daten.
Die innere
for
Schleife sendet bValue die angegebene Anzahl von Malen.Eine Zeichenfolge namens strText , die der Empfänger für den Benutzer anzeigt.
Für den Empfang funktioniert die Funktion ähnlich, mit der Ausnahme, dass sie den Extraktionsoperator (>>) des Archivs zum Abrufen von Daten aus dem Archiv verwendet. Die empfangende Anwendung überprüft die empfangenen Daten, zeigt die endgültige "Empfangene" Nachricht an und sendet dann eine Nachricht zurück, die "Gesendet" besagt, damit die sendende Anwendung angezeigt wird.
In diesem Kommunikationsmodell wird das Wort "Empfangen", die in der strText-Variable gesendete Nachricht, am anderen Ende der Kommunikation angezeigt, sodass der empfangende Benutzer angibt, dass eine bestimmte Anzahl von Datenpaketen empfangen wurde. Der Empfänger antwortet mit einer ähnlichen Zeichenfolge, die "Gesendet" lautet, für die Anzeige auf dem Bildschirm des ursprünglichen Absenders. Der Empfang beider Zeichenfolgen gibt an, dass eine erfolgreiche Kommunikation aufgetreten ist.
Achtung
Wenn Sie ein MFC-Clientprogramm für die Kommunikation mit etablierten (nicht MFC)-Servern schreiben, senden Sie keine C++-Objekte über das Archiv. Es sei denn, der Server ist eine MFC-Anwendung, die die Art der zu sendenden Objekte versteht, kann sie Ihre Objekte nicht empfangen und deserialisieren. Ein Beispiel im Artikel Windows Sockets: Byte-Sortierung zeigt eine Kommunikation dieses Typs.
Weitere Informationen finden Sie unter Windows Sockets Specification: htonl, htons, ntohl, ntohs. Weitere Informationen finden Sie auch unter:
Siehe auch
Windows-Sockets in MFC
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize