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
, , SendTo
und 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. Stellen Sie mithilfe Connect
der Clientseite und Accept
auf der Serverseite eine Verbindung mit einem Clientsocket her. 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
, CSocketFile
und CSocket
Objekte. Der SOCKET
Datentyp wird im Artikel Windows Sockets: Background beschrieben.
Bei Verwendung CArchive
mit CSocketFile
und CSocket
kö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 CSocketFile
CSocket
mehrere Recv-Anrufe pro FD_READ
Benachrichtigung 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_READ
erhalten, 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
CSocket
Anforderungen
Header: afxsock.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 WSAEINTR
beendet.
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 GetLastError
abgerufen 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 einemCArchive
Objekt verwenden.Hinweis
Die
Accept
Memberfunktion verwendet einen Verweis auf ein neues, leeresCSocket
Objekt als Parameter. Sie müssen dieses Objekt erstellen, bevor Sie aufrufenAccept
. Denken Sie daran, dass die Verbindung geschlossen wird, wenn dieses Socketobjekt den Gültigkeitsbereich überschreitet. Rufen Sie dieses neue Socketobjekt nicht aufCreate
.
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 hSocket
ist.
Hinweise
Wenn ein Handle angegeben wird, wenn ein SOCKET
CSocket
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 OnMessagePending
finden 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