WSAAccept-Funktion (winsock2.h)
Die WSAAccept-Funktion akzeptiert bedingt eine Verbindung basierend auf dem Rückgabewert einer Bedingungsfunktion, stellt Qualitätsspezifikationen für den Dienstfluss bereit und ermöglicht die Übertragung von Verbindungsdaten.
Syntax
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Parameter
[in] s
Ein Deskriptor, der einen Socket identifiziert, der nach einem Aufruf der Listenfunktion auf Verbindungen lauscht.
[out] addr
Ein optionaler Zeiger auf eine sockaddr-Struktur , die die Adresse der Verbindungsentität empfängt, wie für die Kommunikationsebene bekannt. Das genaue Format des addr-Parameters wird durch die Adressfamilie bestimmt, die beim Erstellen des Sockets eingerichtet wurde.
[in, out] addrlen
Ein optionaler Zeiger auf eine ganze Zahl, die die Länge der sockaddr-Struktur enthält, auf die der addr-Parameter in Bytes verweist.
[in] lpfnCondition
Die Adresse einer optionalen, von der Anwendung angegebenen Bedingungsfunktion, die basierend auf den als Parameter übergebenen Aufruferinformationen eine Annahme-/Ablehnungsentscheidung trifft und optional eine Socketgruppe erstellt oder verknüpft, indem sie dem Ergebnisparameter g dieser Funktion einen geeigneten Wert zuweisen. Wenn dieser Parameter NULL ist, wird keine Bedingungsfunktion aufgerufen.
[in] dwCallbackData
Rückrufdaten, die an die anwendungsspezifische Bedingungsfunktion als Wert des dwCallbackData-Parameters zurückgegeben werden, der an die Bedingungsfunktion übergeben wird. Dieser Parameter ist nur anwendbar, wenn der lpfnCondition-Parameter nicht NULL ist. Dieser Parameter wird nicht von Windows Sockets interpretiert.
Rückgabewert
Wenn kein Fehler auftritt, gibt WSAAccept einen Wert vom Typ SOCKET zurück, der ein Deskriptor für den akzeptierten Socket ist. Andernfalls wird der Wert INVALID_SOCKET zurückgegeben, und ein bestimmter Fehlercode kann durch Aufrufen von WSAGetLastError abgerufen werden.
Die ganze Zahl, auf die von addrlen verwiesen wird, enthält zunächst den Abstand, auf den addr verweist. Bei der Rückgabe enthält sie die tatsächliche Länge der zurückgegebenen Adresse in Byte.
Fehlercode | Bedeutung |
---|---|
Der Zugriff auf einen Socket war aufgrund der Zugriffsrechte des Sockets unzulässig. Dieser Fehler wird zurückgegeben, wenn für die angebotene Verbindungsanforderung ein Timeout aufgetreten ist oder zurückgezogen wurde. | |
Es konnte keine Verbindung hergestellt werden, da diese vom Zielcomputer aktiv verweigert wurde . Dieser Fehler wird zurückgegeben, wenn die Verbindungsanforderung erzwungen abgelehnt wurde, wie im Rückgabewert der Bedingungsfunktion angegeben (CF_REJECT). | |
An existing connection was forcibly closed by the remote host. Dieser Fehler wird zurückgegeben, wenn eine eingehende Verbindung angezeigt wurde, die jedoch vor der Annahme des Anrufs vom Remotepeer beendet wurde. | |
Das System hat beim Versuch, ein Zeigerargument in einem Aufruf zu verwenden, eine ungültige Zeigeradresse erkannt. Dieser Fehler wird zurückgegeben, da der addrlen-Parameter zu klein ist oder der addr oder lpfnCondition nicht Teil des Benutzeradressraums ist. | |
Ein blockierender Vorgang wurde durch einen Aufruf von WSACancelBlockingCall unterbrochen. Dieser Fehler wird zurückgegeben, wenn ein blockierender Windows Sockets 1.1-Aufruf über WSACancelBlockingCall abgebrochen wurde. | |
Ein Blockierungsvorgang wird momentan ausgeführt. Dieser Fehler wird zurückgegeben, wenn ein blockierter Windows Sockets 1.1-Aufruf ausgeführt wird. | |
Ein ungültiges Argument wurde angegeben. Dieser Fehler wird zurückgegeben, wenn die Überwachung vor WSAAccept nicht aufgerufen wurde, der Rückgabewert der Bedingungsfunktion kein gültiger ist oder wenn sich der angegebene Socket in einem ungültigen Zustand befindet. | |
Zu viele geöffnete Sockets. Dieser Fehler wird zurückgegeben, wenn die Warteschlange beim Eintritt in WSAAccept nicht leer ist und keine Socketdeskriptoren verfügbar sind. | |
Bei einem Socketvorgang war das Netzwerk inaktiv. Dieser Fehler wird zurückgegeben, wenn das Netzwerksubsystem fehlgeschlagen ist. | |
Ein Vorgang für einen Socket konnte nicht ausgeführt werden, weil dem System ausreichender Pufferspeicherplatz fehlte oder eine Warteschlange voll war. Dieser Fehler wird zurückgegeben, wenn kein Pufferspeicher verfügbar ist. | |
Es wurde ein Vorgang für eine Komponente versucht, die kein Socket ist. Dieser Fehler wird zurückgegeben, wenn der im s-Parameter übergebene Socketdeskriptor kein Socket ist. | |
Die Protokollfamilie wurde nicht im System konfiguriert, oder es ist keine Implementierung dafür vorhanden. Dieser Fehler wird zurückgegeben, wenn der Socket, auf den verwiesen wird, kein Typ ist, der den verbindungsorientierten Dienst unterstützt. | |
Ein nicht blockierender Socketvorgang konnte nicht sofort abgeschlossen werden. Dieser Fehler wird zurückgegeben, wenn der Socket als nicht blockiert markiert ist und keine Verbindungen vorhanden sind, um akzeptiert zu werden. | |
Entweder hat die Anwendung WSAStartup nicht aufgerufen, oder WSAStartup ist fehlgeschlagen. Dieser Fehler wird von einem erfolgreichen Aufruf der WSAStartup-Funktion zurückgegeben, die vor der Verwendung dieser Funktion nicht auftritt. | |
Hierbei handelt es sich in der Regel um einen temporären Fehler, der während der Auflösung von Hostnamen auftritt und einen Hinweis darauf liefert, dass der lokale Server keine Antwort von einem autorisierenden Server erhalten hat. Dieser Fehler wird zurückgegeben, wenn die Annahme der Verbindungsanforderung verzögert wurde, wie im Rückgabewert der Bedingungsfunktion angegeben (CF_DEFER). |
Hinweise
Die WSAAccept-Funktion extrahiert die erste Verbindung in der Warteschlange der ausstehenden Verbindungen für Sockets und überprüft sie anhand der Bedingungsfunktion, sofern die Bedingungsfunktion angegeben ist (d. h. nicht NULL). Wenn die Bedingungsfunktion CF_ACCEPT zurückgibt, erstellt WSAAccept einen neuen Socket. Der neu erstellte Socket verfügt über die gleichen Eigenschaften wie Sockets, einschließlich asynchroner Ereignisse, die mit WSAAsyncSelect oder WSAEventSelect registriert sind. Wenn die Bedingungsfunktion CF_REJECT zurückgibt, lehnt WSAAccept die Verbindungsanforderung ab. Die Bedingungsfunktion wird im selben Thread wie diese Funktion ausgeführt und sollte so schnell wie möglich zurückgegeben werden. Wenn die Entscheidung nicht sofort getroffen werden kann, sollte die Bedingungsfunktion CF_DEFER zurückgeben, um anzugeben, dass keine Entscheidung getroffen wurde, und dass keine Aktion des Dienstanbieters zu dieser Verbindungsanforderung durchgeführt werden sollte. Wenn die Anwendung bereit ist, eine Aktion für die Verbindungsanforderung auszuführen, ruft sie WSAAccept erneut auf und gibt entweder CF_ACCEPT oder CF_REJECT als Rückgabewert aus der Bedingungsfunktion zurück.
Ein Socket im Standardmodus (blockierend) wird blockiert, bis eine Verbindung vorhanden ist, wenn eine Anwendung WSAAccept aufruft und keine Verbindungen in der Warteschlange ausstehen.
Ein Socket im Nichtblockierungsmodus (Blockieren) schlägt mit dem Fehler WSAEWOULDBLOCK fehl, wenn eine Anwendung WSAAccept aufruft und keine Verbindungen in der Warteschlange ausstehen. Nachdem WSAAccept erfolgreich war und ein neues Sockethandle zurückgibt, kann der akzeptierte Socket nicht mehr verwendet werden, um weitere Verbindungen zu akzeptieren. Der ursprüngliche Socket bleibt geöffnet und lauscht auf neue Verbindungsanforderungen.
Der addr-Parameter ist ein Ergebnisparameter, der mit der Adresse der Verbindungsentität ausgefüllt wird, wie auf der Kommunikationsebene bekannt. Das genaue Format des addr-Parameters wird durch die Adressfamilie bestimmt, in der die Kommunikation stattfindet. Addrlen ist ein Wert-Ergebnis-Parameter. Sie sollte zunächst den Platz enthalten, auf den der Addr verweist. Bei der Rückgabe enthält sie die tatsächliche Länge (in Byte) der zurückgegebenen Adresse. Dieser Aufruf wird für verbindungsorientierte Sockettypen wie SOCK_STREAM verwendet. Wenn addr und/oder addrlengleich NULL sind, werden keine Informationen zur Remoteadresse des akzeptierten Sockets zurückgegeben. Andernfalls werden diese beiden Parameter ausgefüllt, wenn die Verbindung erfolgreich akzeptiert wurde.
Ein Prototyp der Bedingungsfunktion wird in der Winsock2.h
Headerdatei wie folgt als LPCONDITIONPROC definiert.
int CALLBACK
ConditionFunc(
IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
IN LPWSABUF lpCalleeData,
OUT GROUP FAR * g,
IN DWORD_PTR dwCallbackData
);
ConditionFunc ist ein Platzhalter für die anwendungsspezifische Rückruffunktion. Die tatsächliche Bedingungsfunktion muss sich in einer DLL oder einem Anwendungsmodul befinden. Sie wird in die Moduldefinitionsdatei exportiert.
Der parameter lpCallerId verweist auf eine WSABUF-Struktur, die die Adresse der Verbindungsentität enthält, wobei der len-Parameter die Länge des Puffers in Bytes und der buf-Parameter ein Zeiger auf den Puffer ist. LpCallerData ist ein Wertparameter, der beliebige Benutzerdaten enthält. Die Informationen in diesen Parametern werden zusammen mit der Verbindungsanforderung gesendet. Wenn keine Aufruferidentifikation oder Aufruferdaten verfügbar sind, sind die entsprechenden Parameter NULL. Viele Netzwerkprotokolle unterstützen keine Aufruferdaten zur Verbindungszeit. Von den meisten herkömmlichen Netzwerkprotokollen kann erwartet werden, dass sie Informationen zum Aufruferbezeichner zum Zeitpunkt der Verbindungsanforderung unterstützen. Der buf-Teil des WSABUF , auf den lpCallerId verweist, verweist auf einen sockaddr. Die sockaddr-Struktur wird entsprechend ihrer Adressfamilie interpretiert (in der Regel durch Umwandlung der Sockaddr in einen typspezifischen Typ für die Adressfamilie).
Der lpSQOS-Parameter verweist auf die FLOWSPEC-Strukturen für vom Aufrufer angegebene Sockets , eine für jede Richtung, gefolgt von zusätzlichen anbieterspezifischen Parametern. Die sendenden oder empfangenden Datenflussspezifikationswerte werden für alle unidirektionalen Sockets entsprechend ignoriert. Ein NULL-Wert gibt an, dass keine vom Aufrufer bereitgestellte Dienstqualität vorhanden ist und dass keine Aushandlung möglich ist. Ein lpSQOS-Zeiger ungleich NULL gibt an, dass eine Dienstqualitätsaushandlung erfolgen soll oder dass der Anbieter bereit ist, die Qualität der Dienstanforderung ohne Aushandlung zu akzeptieren.
Der lpGQOS-Parameter ist reserviert und sollte NULL sein. (reserviert für die zukünftige Verwendung mit Socketgruppen) verweist auf die FLOWSPEC-Struktur für die Socketgruppe, die der Aufrufer erstellen soll, eine für jede Richtung, gefolgt von zusätzlichen anbieterspezifischen Parametern. Ein NULL-Wert für lpGQOS gibt keine vom Aufrufer angegebene Dienstqualität der Gruppe an. Informationen zur Dienstqualität können zurückgegeben werden, wenn eine Aushandlung erfolgen soll.
Die lpCalleeId ist ein Parameter, der die lokale Adresse der verbundenen Entität enthält. Der buf-Teil des WSABUF, auf den von lpCalleeId verwiesen wird, verweist auf eine sockaddr-Struktur . Die sockaddr-Struktur wird entsprechend ihrer Adressfamilie interpretiert (in der Regel durch Umwandlung der Sockaddr in einen typspezifischen Typ für die Adressfamilie, z. B. struktur sockaddr_in).
LpCalleeData ist ein Ergebnisparameter, der von der Bedingungsfunktion verwendet wird, um Benutzerdaten an die Verbindungsentität zurückzuliefern. Das lpCalleeData-len> enthält zunächst die Länge des Puffers, der vom Dienstanbieter zugeordnet wird und auf den lpCalleeData-buf> verweist. Der Wert 0 (null) bedeutet, dass die Übergabe von Benutzerdaten an den Aufrufer nicht unterstützt wird. Die Bedingungsfunktion sollte bis zu lpCalleeData-len> Bytes der Daten in lpCalleeData-buf> kopieren und dann lpCalleeData-len> aktualisieren, um die tatsächliche Anzahl der übertragenen Bytes anzugeben. Wenn keine Benutzerdaten an den Aufrufer zurückgegeben werden sollen, sollte die Bedingungsfunktion lpCalleeData-len> auf Null festlegen. Das Format aller Adress- und Benutzerdaten ist spezifisch für die Adressfamilie, zu der der Socket gehört.
Der Parameter g wird innerhalb der Bedingungsfunktion zugewiesen, um eine der folgenden Aktionen anzugeben:
- Wenn g ein vorhandener Socketgruppenbezeichner ist, fügen Sie dieser Gruppe s hinzu, sofern alle von dieser Gruppe festgelegten Anforderungen erfüllt sind.
- Wenn g = SG_UNCONSTRAINED_GROUP, erstellen Sie eine uneingeschränkte Socketgruppe, und verwenden Sie s als erstes Mitglied.
- Wenn g = SG_CONSTRAINED_GROUP, erstellen Sie eine eingeschränkte Socketgruppe, und verwenden Sie s als erstes Mitglied.
- Wenn g = null ist, wird kein Gruppenvorgang ausgeführt.
Der dwCallbackData-Parameterwert , der an die Bedingungsfunktion übergeben wird, ist der Wert, der als dwCallbackData-Parameter im ursprünglichen WSAAccept-Aufruf übergeben wird. Dieser Wert wird nur vom Windows Socket Version 2-Client interpretiert. Dadurch kann ein Client kontextbezogene Informationen vom WSAAccept-Aufrufstandort an die Bedingungsfunktion übergeben. Dadurch werden der Bedingungsfunktion auch alle zusätzlichen Informationen bereitgestellt, die erforderlich sind, um zu bestimmen, ob die Verbindung akzeptiert werden soll oder nicht. Eine typische Verwendung besteht darin, einen (entsprechend umgewandelten) Zeiger an eine Datenstruktur zu übergeben, die Verweise auf anwendungsdefinierte Objekte enthält, denen dieser Socket zugeordnet ist.
Beispielcode
Im folgenden Beispiel wird die Verwendung der WSAAccept-Funktion veranschaulicht.#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
/* Define an example conditional function that depends on the pQos field */
int CALLBACK ConditionAcceptFunc(
LPWSABUF lpCallerId,
LPWSABUF lpCallerData,
LPQOS pQos,
LPQOS lpGQOS,
LPWSABUF lpCalleeId,
LPWSABUF lpCalleeData,
GROUP FAR * g,
DWORD_PTR dwCallbackData
)
{
if (pQos != NULL) {
RtlZeroMemory(pQos, sizeof(QOS));
return CF_ACCEPT;
} else
return CF_REJECT;
}
int main() {
/* Declare and initialize variables */
WSADATA wsaData;
SOCKET ListenSocket, AcceptSocket;
struct sockaddr_in saClient;
int iClientSize = sizeof(saClient);
u_short port = 27015;
char* ip;
sockaddr_in service;
int error;
/* Initialize Winsock */
error = WSAStartup(MAKEWORD(2,2), &wsaData);
if (error) {
printf("WSAStartup() failed with error: %d\n", error);
return 1;
}
/* Create a TCP listening socket */
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("socket() failed with error: %d\n", WSAGetLastError() );
WSACleanup();
return 1;
}
/*-----------------------------------------
* Set up the sock addr structure that the listening socket
* will be bound to. In this case, the structure holds the
* local IP address and the port specified. */
service.sin_family = AF_INET;
service.sin_port = htons(port);
hostent* thisHost;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
service.sin_addr.s_addr = inet_addr(ip);
/*-----------------------------------------
* Bind the listening socket to the IP address.
* and port number specified by the sockaddr structure. */
error = bind(ListenSocket, (SOCKADDR *) &service, sizeof(SOCKADDR));
if (error == SOCKET_ERROR) {
printf("bind() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
/* Make the socket listen for incoming connection requests */
error = listen(ListenSocket, 1);
if (error == SOCKET_ERROR) {
printf("listen() failed with error: %d\n", WSAGetLastError() );
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Listening...\n");
/*-----------------------------------------
* Accept an incoming connection request on the
* listening socket and transfer control to the
* accepting socket. */
AcceptSocket = WSAAccept(ListenSocket, (SOCKADDR*) &saClient, &iClientSize,
&ConditionAcceptFunc, NULL);
/* Now do some work with the AcceptSocket
* At this point, the application could
* handle data transfer on the socket, or other socket
* functionality.*/
/* Then clean up and quit */
closesocket(AcceptSocket);
closesocket(ListenSocket);
WSACleanup();
return 0;
}
Windows Phone 8: Diese Funktion wird für Windows Phone Store-Apps ab Windows Phone 8 unterstützt.
Windows 8.1 und Windows Server 2012 R2: Diese Funktion wird für Windows Store-Apps auf Windows 8.1, Windows Server 2012 R2 und höher unterstützt.
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Windows 8.1, Windows Vista [Desktop-Apps | UWP-Apps] |
Unterstützte Mindestversion (Server) | Windows Server 2003 [Desktop-Apps | UWP-Apps] |
Zielplattform | Windows |
Kopfzeile | winsock2.h |
Bibliothek | Ws2_32.lib |
DLL | Ws2_32.dll |
Weitere Informationen
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für