2016-06-13 2 views
-2

Je crée un programme de socket en C++ en utilisant winsock2 et j'essaie d'utiliser WSAAccept pour accepter les connexions de manière conditionnelle. J'ai copié l'exemple ConditionalFunction à partir de MSDN pour l'argument lpfnCondition dans WSAAccept comme indiqué ci-dessous.Le programme se bloque lors de la tentative de récupération du contenu du pointeur

SOCKET WSAAccept(
    _In_ SOCKET   s, 
    _Out_ struct sockaddr *addr, 
    _Inout_ LPINT   addrlen, 
    _In_ LPCONDITIONPROC lpfnCondition, //<--------- 
    _In_ DWORD_PTR  dwCallbackData 
); 

Cependant lorsque vous essayez d'accéder au contenu de lpCallerId dans le ConditionalFunction comme si WSABUF buffer = *lpCallerData plantage de mon programme. Je sais que c'est la source du problème parce que quand je commente cette ligne mon programme ne plante pas. Je ne pense pas que tout mon code serait nécessaire. Toute aide serait belle.

EDIT:

CALLBACK ConditionalAccept(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS, 
          LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData, 
          GROUP *g,DWORD_PTR dwCallbackData) 
{ 
    WSABUF buffer = *lpCallerData; 

    if (lpSQOS != NULL) { 
     RtlZeroMemory(lpSQOS, sizeof(QOS)); 
     return CF_ACCEPT; 
    } else 
     return CF_REJECT; 
} 

...

WSAAccept(slisten, (SOCKADDR*)&acceptSock, &Size, &ConditionalAccept, NULL); 
+3

Veuillez essayer de créer un [Exemple minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve) que vous pouvez nous montrer. –

+0

Qu'est-ce que 'lpCallerData'? – immibis

+2

Si vous pouvez lire le document MSDN concernant ce paramètre: Les informations contenues dans ces paramètres sont envoyées avec la demande de connexion. * Si aucune identification d'appelant ou données d'appelant n'est disponible, les paramètres correspondants seront NULL *. –

Répondre

3

Comme Luc dit, vous ne vérifiez pas lpCallerData pour NULL avant déréférencement il. C'est pourquoi votre code plante.

int CALLBACK ConditionalAccept(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS, 
          LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData, 
          GROUP *g,DWORD_PTR dwCallbackData) 
{ 
    WSABUF buffer = {0}; 

    if (lpCallerData != NULL) { // <-- add this check! 
     buffer = *lpCallerData; 
    } 

    if (lpSQOS != NULL) { 
     RtlZeroMemory(lpSQOS, sizeof(QOS)); 
     return CF_ACCEPT; 
    } else 
     return CF_REJECT; 
} 

Cependant, lpCallerData n'a pas de sens dans le protocole TCP/IP et sera toujours être NULL. TCP/IP ne prend pas en charge l'échange de données appelant/appelé pendant l'établissement de la connexion. Ceci est clairement indiqué dans la documentation WSAConnect():

Le paramètre lpCallerData contient un pointeur vers les données de l'utilisateur qui doit être envoyé en même temps que la demande de connexion (appelée connexion de données). Ce sont des données supplémentaires, pas dans le flux de données réseau normal, qui sont envoyées avec les demandes réseau pour établir une connexion. Cette option est utilisée par les protocoles hérités tels que DECNet, OSI TP4 et autres.

Remarque Les données de connexion ne sont pas prises en charge par le protocole TCP/IP sous Windows. Les données de connexion sont prises en charge uniquement sur ATM (RAWWAN) sur un socket brut.