Fonction WSAAccept (winsock2.h)
La fonction WSAAccept accepte conditionnellement une connexion en fonction de la valeur de retour d’une fonction de condition, fournit une qualité des spécifications de flux de service et permet le transfert de données de connexion.
Syntaxe
SOCKET WSAAPI WSAAccept(
[in] SOCKET s,
[out] sockaddr *addr,
[in, out] LPINT addrlen,
[in] LPCONDITIONPROC lpfnCondition,
[in] DWORD_PTR dwCallbackData
);
Paramètres
[in] s
Descripteur qui identifie un socket qui écoute les connexions après un appel à la fonction écouter.
[out] addr
Pointeur facultatif vers une structure sockaddr qui reçoit l’adresse de l’entité de connexion, telle qu’appelée couche de communications. Le format exact du paramètre addr
[in, out] addrlen
Pointeur facultatif vers un entier qui contient la longueur du structure sockaddr pointée par le paramètre addr, en octets.
[in] lpfnCondition
Adresse d’une fonction de condition facultative spécifiée par l’application qui prendra une décision d’acceptation/rejet en fonction des informations de l’appelant transmises en tant que paramètres, et éventuellement créer ou joindre un groupe de sockets en affectant une valeur appropriée au paramètre de résultat g de cette fonction. Si ce paramètre est NULL, aucune fonction de condition n’est appelée.
[in] dwCallbackData
Les données de rappel transmises à la fonction de condition spécifiée par l’application comme valeur du paramètre dwCallbackData passé à la fonction de condition. Ce paramètre s’applique uniquement si le paramètre lpfnCondition n’est pas NULL. Ce paramètre n’est pas interprété par Windows Sockets.
Valeur de retour
Si aucune erreur ne se produit, WSAAccept retourne une valeur de type SOCKET qui est un descripteur pour le socket accepté. Sinon, une valeur de INVALID_SOCKET est retournée et un code d’erreur spécifique peut être récupéré en appelant WSAGetLastError.
L’entier référencé par addrlen contient initialement la quantité d’espace pointée par addr. Lors du retour, elle contiendra la longueur réelle en octets de l’adresse retournée.
Code d’erreur | Signification |
---|---|
Une tentative a été effectuée pour accéder à un socket d’une manière interdite par ses autorisations d’accès. Cette erreur est retournée si la demande de connexion qui a été proposée a expiré ou a été retirée. | |
Aucune connexion n’a pu être établie, car l’ordinateur cible l’a activement refusé. Cette erreur est retournée si la demande de connexion a été rejetée avec force, comme indiqué dans la valeur de retour de la fonction de condition (CF_REJECT). | |
Une connexion existante a été fermée de force par l’hôte distant. Cette erreur est retournée d’une connexion entrante a été indiquée, mais a été arrêtée par l’homologue distant avant d’accepter l’appel. | |
Le système a détecté une adresse de pointeur non valide lors de la tentative d’utilisation d’un argument de pointeur dans un appel. Cette erreur est retournée du paramètre addrlen |
|
Une opération de blocage a été interrompue par un appel à WSACancelBlockingCall. Cette erreur est retournée si un appel Windows Sockets 1.1 bloquant a été annulé via WSACancelBlockingCall. | |
Une opération de blocage est en cours d’exécution. Cette erreur est retournée si un appel Windows Sockets 1.1 bloquant est en cours. | |
Un argument non valide a été fourni. Cette erreur est retournée si écouter n’a pas été appelée avant WSAAccept , la valeur de retour de la fonction de condition n’est pas valide ou si le socket spécifié est dans un état non valide. | |
Trop de sockets ouverts. Cette erreur est retournée si la file d’attente n’est pas vide lors de l’entrée à WSAAccept et qu’aucun descripteur de socket n’est disponible. | |
Une opération de socket a rencontré un réseau mort. Cette erreur est retournée si le sous-système réseau a échoué. | |
Une opération sur un socket n’a pas pu être effectuée, car le système n’a pas suffisamment d’espace tampon ou parce qu’une file d’attente était pleine. Cette erreur est retournée si aucun espace tampon n’est disponible. | |
Une opération a été tentée sur quelque chose qui n’est pas un socket. Cette erreur est retournée si le descripteur de socket passé dans le paramètre de |
|
La famille de protocoles n’a pas été configurée dans le système ou aucune implémentation n’existe. Cette erreur est retournée si le socket référencé n’est pas un type qui prend en charge le service orienté connexion. | |
Une opération de socket non bloquante n’a pas pu être effectuée immédiatement. Cette erreur est retournée si le socket est marqué comme non bloquant et qu’aucune connexion n’est présente pour être acceptée. | |
L’application n’a pas appelé WSAStartup, ou WSAStartup a échoué. Cette erreur est renvoyée d’un appel réussi à la fonction WSAStartup ne se produit pas avant d’utiliser cette fonction. | |
Il s’agit généralement d’une erreur temporaire lors de la résolution du nom d’hôte et signifie que le serveur local n’a pas reçu de réponse d’un serveur faisant autorité. Cette erreur est retournée si l’acceptation de la demande de connexion a été différée, comme indiqué dans la valeur de retour de la fonction de condition (CF_DEFER). |
Remarques
La fonction
Un socket en mode par défaut (blocage) se bloque jusqu’à ce qu’une connexion soit présente lorsqu’une application appelle WSAAccept et aucune connexion n’est en attente dans la file d’attente.
Un socket en mode non bloquant (blocage) échoue avec l’erreur WSAEWOULDBLOCK lorsqu’une application appelle WSAAccept et aucune connexion n’est en attente dans la file d’attente. Une fois WSAAccept réussit et retourne un nouveau handle de socket, le socket accepté ne peut pas être utilisé pour accepter plus de connexions. Le socket d’origine reste ouvert et écoute les nouvelles demandes de connexion.
Le paramètre addr est un paramètre de résultat qui est rempli avec l’adresse de l’entité de connexion, tel qu’appelé couche de communications. Le format exact du paramètre addr est déterminé par la famille d’adresses dans laquelle la communication se produit. Le addrlen
Un prototype de la fonction de condition est défini dans le fichier d’en-tête Winsock2.h
comme LPCONDITIONPROC, comme suit.
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
);
Le ConditionFunc
Le paramètre lpCallerId pointe vers une structure WSABUF qui contient l’adresse de l’entité de connexion, où son paramètre len est la longueur de la mémoire tampon en octets, et son paramètre de buf est un pointeur vers la mémoire tampon. L'lpCallerData est un paramètre de valeur qui contient toutes les données utilisateur. Les informations contenues dans ces paramètres sont envoyées avec la demande de connexion. Si aucune donnée d’identification ou d’appelant n’est disponible, les paramètres correspondants sont NULL. De nombreux protocoles réseau ne prennent pas en charge les données d’appelant au moment de la connexion. La plupart des protocoles réseau conventionnels peuvent être censés prendre en charge les informations d’identificateur de l’appelant au moment de la demande de connexion. La partie buf de la WSABUF pointée par lpCallerId pointe vers une sockaddr. La structure sockaddr est interprétée en fonction de sa famille d’adresses (généralement en faisant passer le sockaddr à un type spécifique à la famille d’adresses).
Le paramètre
Le paramètre
L'lpCalleeId est un paramètre qui contient l’adresse locale de l’entité connectée. La partie
L'lpCalleeData est un paramètre de résultat utilisé par la fonction condition pour fournir des données utilisateur à l’entité de connexion. La lpCalleeData->len contient initialement la longueur de la mémoire tampon allouée par le fournisseur de services et pointée par lpCalleeData->buf. La valeur zéro signifie que le passage de données utilisateur à l’appelant n’est pas pris en charge. La fonction de condition doit copier jusqu’à lpCalleeData->len octets de données dans lpCalleeData->buf, puis mettre à jour lpCalleeData->len pour indiquer le nombre réel d’octets transférés. Si aucune donnée utilisateur ne doit être renvoyée à l’appelant, la fonction de condition doit définir lpCalleeData->len sur zéro. Le format de toutes les données d’adresse et d’utilisateur est spécifique à la famille d’adresses à laquelle appartient le socket.
Le paramètre g est affecté dans la fonction de condition pour indiquer l’une des actions suivantes :
- Si g est un identificateur de groupe de sockets existant, ajoutez à ce groupe, à condition que toutes les exigences définies par ce groupe soient remplies.
- Si g = SG_UNCONSTRAINED_GROUP, créez un groupe de sockets non contraints et avez en tant que premier membre.
- Si g = SG_CONSTRAINED_GROUP, créez un groupe de sockets contraints et avez s en tant que premier membre.
- Si g = zéro, aucune opération de groupe n’est effectuée.
La valeur du paramètre dwCallbackData passée à la fonction de condition est la valeur passée en tant que paramètre dwCallbackData dans l’appel WSAAccept d’origine. Cette valeur est interprétée uniquement par le client Windows Socket version 2. Cela permet à un client de transmettre des informations de contexte à partir de la WSAAccept appeler le site à l’aide de la fonction de condition. Cela fournit également à la fonction de condition toutes les informations supplémentaires requises pour déterminer s’il faut accepter la connexion ou non. Une utilisation classique consiste à passer un pointeur (casté de manière appropriée) à une structure de données contenant des références à des objets définis par l’application avec lesquels ce socket est associé.
exemple de code
L’exemple suivant illustre l’utilisation de la fonction WSAAccept.#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 : Cette fonction est prise en charge pour les applications du Windows Phone Store sur Windows Phone 8 et versions ultérieures.
windows 8.1 et Windows Server 2012 R2: cette fonction est prise en charge pour les applications du Windows Store sur Windows 8.1, Windows Server 2012 R2 et versions ultérieures.
Exigences
Exigence | Valeur |
---|---|
client minimum pris en charge | Windows 8.1, Windows Vista [applications de bureau | Applications UWP] |
serveur minimum pris en charge | Windows Server 2003 [applications de bureau | Applications UWP] |
plateforme cible | Windows |
d’en-tête | winsock2.h |
bibliothèque | Ws2_32.lib |
DLL | Ws2_32.dll |