CSocket-Klasse

Abgeleitet von CAsyncSocket, erbt seine Kapselung der Windows Sockets-API und stellt eine höhere Abstraktionsebene als die eines CAsyncSocket Objekts dar.

Syntax

class CSocket : public CAsyncSocket

Member

Öffentliche Konstruktoren

Name Beschreibung
CSocket::CSocket Erstellt ein CSocket-Objekt.

Öffentliche Methoden

Name Beschreibung
CSocket::Attach Fügt ein SOCKET Handle an ein CSocket Objekt an.
CSocket::CancelBlockingCall Bricht einen blockierten Aufruf ab, der derzeit ausgeführt wird.
CSocket::Create Erstellt einen Socket.
CSocket::FromHandle Gibt einen Zeiger auf ein CSocket Objekt zurück, wenn ein SOCKET Handle angegeben ist.
CSocket::IsBlocking Bestimmt, ob ein blockierter Aufruf ausgeführt wird.

Geschützte Methoden

Name Beschreibung
CSocket::OnMessagePending Wird aufgerufen, um ausstehende Nachrichten zu verarbeiten, während auf den Abschluss eines blockierten Anrufs gewartet wird.

Hinweise

CSocket arbeitet mit Klassen CSocketFile und CArchive zum Verwalten des Sendens und Empfangens von Daten.

Ein CSocket Objekt bietet auch Blockierung, was für den synchronen Betrieb von CArchive. Blockieren von Funktionen, z Receive. B. , Send, ReceiveFrom, , SendTound Accept (alle geerbt von CAsyncSocket), geben WSAEWOULDBLOCK keinen Fehler in CSocket. Stattdessen warten diese Funktionen, bis der Vorgang abgeschlossen ist. Darüber hinaus wird der ursprüngliche Aufruf mit dem Fehler WSAEINTR beendet, wenn CancelBlockingCall eine dieser Funktionen blockiert wird.

Um ein CSocket Objekt zu verwenden, rufen Sie den Konstruktor auf, und rufen Sie Create dann auf, um das zugrunde liegende SOCKET Handle (Typ SOCKET) zu erstellen. Die Standardparameter zum Create Erstellen eines Datenstromsockets, aber wenn Sie den Socket nicht mit einem CArchive Objekt verwenden, können Sie stattdessen einen Parameter angeben, um einen Datagrammsocket zu erstellen, oder eine Bindung an einen bestimmten Port zum Erstellen eines Serversockets. Verbinden zu einem Clientsocket, Connect das auf der Clientseite und Accept auf der Serverseite verwendet wird. Erstellen Sie dann ein CSocketFile Objekt, und ordnen Sie es dem CSocket Objekt im CSocketFile Konstruktor zu. Erstellen Sie als Nächstes ein CArchive Objekt zum Senden und ein Objekt zum Empfangen von Daten (nach Bedarf), und ordnen Sie es CSocketFile dem Objekt im CArchive Konstruktor zu. Wenn die Kommunikation abgeschlossen ist, zerstören Sie die CArchive, CSocketFileund CSocket Objekte. Der SOCKET Datentyp wird im Artikel Windows Sockets: Background beschrieben.

Bei Verwendung CArchive mit CSocketFile und CSocketkönnen Sie auf eine Situation stoßen, in der CSocket::Receive eine Schleife (nach PumpMessages(FD_READ)) auf die angeforderte Bytemenge wartet. Dies liegt daran, dass Windows-Sockets nur einen Recv-Anruf pro FD_READ Benachrichtigung zulassen, aber CSocketFileCSocket mehrere Recv-Anrufe pro FD_READBenachrichtigung zulassen. Wenn Sie einen FD_READ Zeitpunkt erhalten, an dem keine Zu lesenden Daten vorhanden sind, hängt die Anwendung. Wenn Sie nie eine andere FD_READerhalten, kommuniziert die Anwendung nicht mehr über den Socket.

Sie können dieses Problem wie folgt beheben. Rufen Sie in der OnReceive Methode Der Socketklasse auf CAsyncSocket::IOCtl(FIONREAD, ...) , bevor Sie die Serialize Methode der Nachrichtenklasse aufrufen, wenn die erwarteten Daten aus dem Socket gelesen werden, die Größe eines TCP-Pakets überschreitet (maximale Übertragungseinheit des Netzwerkmediums, in der Regel mindestens 1096 Byte). Wenn die Größe der verfügbaren Daten kleiner als erforderlich ist, warten Sie, bis alle Daten empfangen werden, und starten Sie dann den Lesevorgang.

Im folgenden Beispiel ist die ungefähre Anzahl von Bytes angegeben, m_dwExpected die der Benutzer empfängt. Es wird davon ausgegangen, dass Sie sie an anderer Stelle im Code deklarieren.

void CChatSocket::OnReceive(int nErrorCode)
{
   CSocket::OnReceive(nErrorCode);

   DWORD dwReceived;

   if (IOCtl(FIONREAD, &dwReceived))
   {
      if (dwReceived >= m_dwExpected) // Process only if you have enough data
         m_pDoc->ProcessPendingRead();
   }
   else
   {
      // Error handling here
   }
}

Hinweis

Wenn Sie MFC-Sockets in sekundären Threads in einer statisch verknüpften MFC-Anwendung verwenden, müssen Sie in jedem Thread aufrufen AfxSocketInit , der Sockets zum Initialisieren der Socketbibliotheken verwendet. Standardmäßig AfxSocketInit wird nur im primären Thread aufgerufen.

Weitere Informationen finden Sie unter Windows Sockets in MFC, Windows Sockets: Using Sockets with Archives, Windows Sockets: How Sockets with Archives Work, Windows Sockets: Sequence of Operations, Windows Sockets: Example of Sockets Using Archives.

Vererbungshierarchie

CObject

CAsyncSocket

CSocket

Anforderungen

Headerafxsock.h:

CSocket::Attach

Rufen Sie diese Memberfunktion auf, um das hSocket Handle an ein CSocket Objekt anzufügen.

BOOL Attach(SOCKET hSocket);

Parameter

hSocket
Enthält ein Handle für einen Socket.

Rückgabewert

Ungleich null, wenn die Funktion erfolgreich ist.

Hinweise

Das SOCKET Handle wird im Datenelement des m_hSocket Objekts gespeichert.

Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven.

Beispiel

class CSockThread : public CWinThread
{
public:
   SOCKET m_hConnected;

protected:
   CChatSocket m_sConnected;

   // remainder of class declaration omitted.

 

BOOL CSockThread::InitInstance()
{
   // Attach the socket object to the socket handle
   // in the context of this thread.
   m_sConnected.Attach(m_hConnected);
   m_hConnected = NULL;

   return TRUE;
}

 

// This listening socket has been constructed
// in the primary thread.
void CListeningSocket::OnAccept(int nErrorCode)
{
   UNREFERENCED_PARAMETER(nErrorCode);

   // This CSocket object is used just temporarily
   // to accept the incoming connection.
   CSocket sConnected;
   Accept(sConnected);

   // Start the other thread.
   CSockThread *pSockThread = (CSockThread*)AfxBeginThread(
       RUNTIME_CLASS(CSockThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
   if (NULL != pSockThread)
   {
      // Detach the newly accepted socket and save
      // the SOCKET handle in our new thread object.
      // After detaching it, it should no longer be
      // used in the context of this thread.
      pSockThread->m_hConnected = sConnected.Detach();
      pSockThread->ResumeThread();
   }
}

CSocket::CancelBlockingCall

Rufen Sie diese Memberfunktion auf, um einen derzeit ausgeführten Blockierungsaufruf abzubrechen.

void CancelBlockingCall();

Hinweise

Diese Funktion bricht alle ausstehenden Blockierungsvorgänge für diesen Socket ab. Der ursprüngliche Blockierungsaufruf wird so schnell wie möglich mit dem Fehler WSAEINTRbeendet.

Bei einem Blockierungsvorgang Connect beendet die Windows Sockets-Implementierung den Blockierungsaufruf so schnell wie möglich, aber es ist möglicherweise nicht möglich, dass die Socketressourcen freigegeben werden, bis die Verbindung abgeschlossen ist (und dann zurückgesetzt wurde) oder timeout. Dies ist wahrscheinlich nur dann spürbar, wenn die Anwendung sofort versucht, einen neuen Socket zu öffnen (wenn keine Sockets verfügbar sind) oder eine Verbindung mit demselben Peer herzustellen.

Abbrechen eines anderen Vorgangs als Accept das Verlassen des Sockets in einem unbestimmten Zustand. Wenn eine Anwendung einen Blockierungsvorgang für einen Socket abbricht, ist der einzige Vorgang, den die Anwendung für den Socket ausführen kann, ein Aufruf Close, obwohl andere Vorgänge möglicherweise für einige Windows Sockets-Implementierungen funktionieren. Wenn Sie eine maximale Portabilität für Ihre Anwendung wünschen, müssen Sie darauf achten, dass Sie nach einer Kündigung keine Vorgänge ausführen.

Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven.

CSocket::Create

Rufen Sie die Create Memberfunktion nach dem Erstellen eines Socketobjekts auf, um den Windows-Socket zu erstellen und anzufügen.

BOOL Create(
    UINT nSocketPort = 0,
    int nSocketType = SOCK_STREAM,
    LPCTSTR lpszSocketAddress = NULL);

Parameter

nSocketPort
Ein bestimmter Port, der mit dem Socket verwendet werden soll, oder 0, wenn MFC einen Port auswählen soll.

nSocketType
SOCK_STREAM oder SOCK_DGRAM

lpszSocketAddress
Ein Zeiger auf eine Zeichenfolge, die die Netzwerkadresse des verbundenen Sockets enthält, eine gepunktete Zahl wie "128.56.22.8". Das Übergeben der NULL-Zeichenfolge für diesen Parameter gibt an, dass die CSocket Instanz auf Clientaktivitäten auf allen Netzwerkschnittstellen lauschen soll.

Rückgabewert

Nonzero, wenn die Funktion erfolgreich ist; andernfalls 0 und ein bestimmter Fehlercode kann durch Aufrufen GetLastErrorabgerufen werden.

Hinweise

Create anschließend wird aufgerufen Bind , um den Socket an die angegebene Adresse zu binden. Die folgenden Sockettypen werden unterstützt:

  • SOCK_STREAM Stellt sequenzierte, zuverlässige, bidirektionale, verbindungsbasierte Bytestreams bereit. Verwendet tcp (Transmission Control Protocol) für die Internetadressenfamilie.

  • SOCK_DGRAM Unterstützt Datagramme, die verbindungslose, unzuverlässige Puffer einer festen (normalerweise kleinen) maximalen Länge sind. Verwendet das User Datagram Protocol (UDP) für die Internetadressenfamilie. Um diese Option zu verwenden, dürfen Sie den Socket nicht mit einem CArchive Objekt verwenden.

    Hinweis

    Die Accept Memberfunktion verwendet einen Verweis auf ein neues, leeres CSocket Objekt als Parameter. Sie müssen dieses Objekt erstellen, bevor Sie aufrufen Accept. Denken Sie daran, dass die Verbindung geschlossen wird, wenn dieses Socketobjekt den Gültigkeitsbereich überschreitet. Rufen Sie dieses neue Socketobjekt nicht auf Create .

Weitere Informationen zu Datenstrom- und Datagrammsockets finden Sie in den Artikeln Windows Sockets: Hintergrund, Windows Sockets: Ports und Socketadressen und Windows Sockets: Verwenden von Sockets mit Archiven.

CSocket::CSocket

Erstellt ein CSocket-Objekt.

CSocket();

Hinweise

Nach der Konstruktion müssen Sie die Create Memberfunktion aufrufen.

Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven.

CSocket::FromHandle

Gibt einen Zeiger auf ein CSocket Objekt zurück.

static CSocket* PASCAL FromHandle(SOCKET hSocket);

Parameter

hSocket
Enthält ein Handle für einen Socket.

Rückgabewert

Ein Zeiger auf ein CSocket Objekt oder NULL wenn kein CSocket Objekt angefügt hSocketist.

Hinweise

Wenn ein Handle angegeben wird, wenn ein SOCKETCSocket Objekt nicht an das Handle angefügt ist, gibt die Memberfunktion zurück NULL und erstellt kein temporäres Objekt.

Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven.

CSocket::IsBlocking

Rufen Sie diese Memberfunktion auf, um festzustellen, ob ein blockierter Aufruf ausgeführt wird.

BOOL IsBlocking();

Rückgabewert

Nonzero, wenn der Socket blockiert wird; andernfalls 0.

Hinweise

Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven.

CSocket::OnMessagePending

Überschreiben Sie diese Memberfunktion, um nach bestimmten Nachrichten von Windows zu suchen und in Ihrem Socket darauf zu reagieren.

virtual BOOL OnMessagePending();

Rückgabewert

Nonzero, wenn die Nachricht behandelt wurde; andernfalls 0.

Hinweise

Dies ist eine erweiterte Außerkraftsetzung.

Das Framework ruft auf OnMessagePending , während der Socket Windows-Nachrichten pumpt, um Ihnen die Möglichkeit zu geben, nachrichten von Interesse für Ihre Anwendung zu behandeln. Beispiele für die Verwendung OnMessagePendingfinden Sie im Artikel "Windows Sockets: Ableiten von Socketklassen".

Weitere Informationen finden Sie unter Windows Sockets: Verwenden von Sockets mit Archiven.

Siehe auch

CAsyncSocket Klasse
Hierarchiediagramm
CAsyncSocket Klasse
CSocketFile Klasse