Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird erläutert, wie ein CSocket-Objekt , ein CSocketFile-Objekt und ein CArchive-Objekt kombiniert werden, um das Senden und Empfangen von Daten über einen Windows Socket zu vereinfachen.
Der Artikel Windows Sockets: Beispiel für Sockets Using Archives stellt die PacketSerialize Funktion dar. Das Archivobjekt im PacketSerialize Beispiel funktioniert ähnlich wie ein Archivobjekt, das an eine MFC Serialize-Funktion übergeben wird. Der wesentliche Unterschied besteht darin, dass das Archiv für Sockets nicht an ein standardmäßiges CFile-Objekt (in der Regel einer Datenträgerdatei zugeordnet) sondern an ein CSocketFile Objekt angefügt wird. Anstatt eine Verbindung mit einer Datenträgerdatei herzustellen, stellt das CSocketFile Objekt eine Verbindung mit einem CSocket Objekt her.
Ein CArchive Objekt verwaltet einen Puffer. Wenn der Puffer eines speicherenden (sendenden) Archivs voll ist, schreibt ein zugeordnetes CFile Objekt den Inhalt des Puffers aus. Das Leeren des Puffers eines an einen Socket angefügten Archivs entspricht dem Senden einer Nachricht. Wenn der Puffer eines Ladearchivs (Empfangen) voll ist, wird das CFile Objekt nicht mehr gelesen, bis der Puffer wieder verfügbar ist.
Die Klasse CSocketFile leitet sich von CFile ab, unterstützt jedoch keine CFile-Memberfunktionsaufrufe wie die Positionierungsfunktionen (Seek, GetLength, SetLength und andere), die Sperrfunktionen (LockRange, UnlockRange) oder die GetPosition-Funktion. Das gesamte CSocketFile-Objekt muss Schreib- oder Lesesequenzen von Bytes in oder aus dem zugeordneten CSocket Objekt ausführen. Da eine Datei nicht beteiligt ist, ergeben Vorgänge wie Seek und GetPosition keinen Sinn. CSocketFile wird von CFileabgeleitet, sodass sie normalerweise alle diese Memberfunktionen erben würde. Um dies zu verhindern, werden die nicht unterstützten CFile-Memberfunktionen in CSocketFile überschrieben, um eine CNotSupportedException auszulösen.
Das CSocketFile Objekt ruft Memberfunktionen des CSocket Objekts auf, um Daten zu senden oder zu empfangen.
Die folgende Abbildung zeigt die Beziehungen zwischen diesen Objekten auf beiden Seiten der Kommunikation.
CArchive, CSocketFile und CSocket
Der Zweck dieser scheinbaren Komplexität besteht darin, Sie vor der Notwendigkeit zu schützen, die Details des Sockets selbst zu verwalten. Sie erstellen den Socket, die Datei und das Archiv, und beginnen dann mit dem Senden oder Empfangen von Daten, indem Sie ihn in das Archiv einfügen oder aus dem Archiv extrahieren. CArchive, CSocketFile und CSocket verwalten die Details hinter den Kulissen.
Ein CSocket Objekt ist tatsächlich ein Zwei-Zustands-Objekt: manchmal asynchron (der übliche Zustand) und manchmal synchron. In seinem asynchronen Zustand kann ein Socket asynchrone Benachrichtigungen vom Framework empfangen. Während eines Vorgangs wie dem Empfangen oder Senden von Daten wird der Socket jedoch synchron. Dies bedeutet, dass der Socket keine weiteren asynchronen Benachrichtigungen empfängt, bis der synchrone Vorgang abgeschlossen ist. Da sie Modi wechselt, können Sie z. B. wie folgt vorgehen:
void CMySocket::OnReceive(int nErrorCode)
{
if (0 == nErrorCode)
{
CSocketFile file(this);
CArchive ar(&file, CArchive::load);
CString str;
ar >> str;
}
}
Wenn CSocket nicht als Zwei-Zustands-Objekt implementiert wäre, könnte es dazu kommen, dass Sie gleichzeitig zusätzliche Benachrichtigungen für dieselbe Art von Ereignis erhalten, während Sie eine vorherige Benachrichtigung verarbeiten. Beispielsweise könnten Sie während der Bearbeitung eines OnReceive eine OnReceive-Benachrichtigung erhalten. Im obigen Codefragment kann das Extrahieren str aus dem Archiv zu Rekursionen führen. Durch das Wechseln von Zuständen verhindert CSocket eine Rekursion, indem es zusätzliche Benachrichtigungen unterbindet. Die allgemeine Regel lautet, keine Benachrichtigungen innerhalb von Benachrichtigungen.
Hinweis
A CSocketFile kann auch als (eingeschränkte) Datei ohne Objekt CArchive verwendet werden. Standardmäßig ist der CSocketFile des Konstruktors TRUE. Dadurch wird angegeben, dass das Dateiobjekt für ein Archiv verwendet werden soll. Um das Dateiobjekt ohne Archiv zu verwenden, übergeben Sie FALSE im bArchiveCompatible-Parameter .
Im Modus "archivkompatibel" bietet ein CSocketFile Objekt eine bessere Leistung und reduziert die Gefahr eines "Deadlocks". Ein Deadlock tritt auf, wenn sowohl die sende- als auch die empfangenden Sockets aufeinander warten oder auf eine gemeinsame Ressource warten. Diese Situation kann auftreten, wenn das CArchive Objekt auf dieselbe Weise mit der CSocketFile arbeitet, wie es mit einem CFile Objekt interagiert. Mit CFile kann das Archiv annehmen, dass das Ende der Datei erreicht wurde, wenn es weniger Bytes erhält als angefordert. Bei CSocketFileDaten handelt es sich jedoch um nachrichtenbasierte Daten. Der Puffer kann mehrere Nachrichten enthalten, sodass der Empfang weniger als die anzahl der angeforderten Bytes nicht das Ende der Datei bedeutet. Die Anwendung wird in diesem Fall nicht blockiert, wie dies möglicherweise bei CFile der Fall ist, und sie kann weiterhin Nachrichten aus dem Puffer lesen, bis der Puffer leer ist. Die IsBufferEmpty-FunktionCArchive ist nützlich, um den Zustand des Archivpuffers in einem solchen Fall zu überwachen.
Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven