2016-06-13 20 views
-2

Ich mache ein Socket-Programm in C++ mit winsock2 und ich versuche, WSAAccept zu verwenden, um Verbindungen zu akzeptieren. Ich kopierte das Beispiel ConditionalFunction von MSDN für das lpfnCondition Argument in WSAAcept, wie unten zu sehen.Programm stürzt ab, wenn Inhalt des Zeigers abgerufen werden soll

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

jedoch, wenn der Inhalt von lpCallerId in der ConditionalFunction wie so WSABUF buffer = *lpCallerData mein Programm stürzt ab, zuzugreifen versuchen. Ich weiß, dass dies die Ursache des Problems ist, denn wenn ich diese Zeile kommentiere, stürzt mein Programm nicht ab. Ich glaube nicht, dass mein gesamter Code notwendig wäre. Jede Hilfe wäre schön.

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

Bitte versuchen Sie, ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve) zu erstellen, das Sie uns zeigen können. –

+0

Was ist 'lpCallerData'? – immibis

+2

Wenn Sie das MSDN-Dokument zu diesem Parameter lesen können: Die Informationen in diesen Parametern werden zusammen mit der Verbindungsanforderung gesendet. * Wenn keine Anruferkennung oder Anruferdaten verfügbar sind, sind die entsprechenden Parameter NULL *. –

Antwort

3

Als Luke angegeben, Sie sind nicht lpCallerData für NULL überprüft, bevor es zu dereferenzieren. Deshalb stürzt dein Code ab.

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; 
} 

jedoch lpCallerData ist in TCP/IP bedeutungslos und wird immer NULL sein. TCP/IP unterstützt den Austausch von Anrufer-/Anforderungsdaten während des Verbindungsaufbaus nicht. Dies wird deutlich in der WSAConnect() Dokumentation angegeben:

Der lpCallerData Parameter enthält einen Zeiger auf jede Benutzerdaten, die zusammen mit der Verbindungsanfrage (so genannte Verbindungsdaten) gesendet werden soll. Dies sind zusätzliche Daten, die nicht im normalen Netzwerkdatenstrom enthalten sind und mit Netzwerkanforderungen gesendet werden, um eine Verbindung herzustellen. Diese Option wird von älteren Protokollen wie DECNet, OSI TP4 und anderen verwendet.

Hinweis Verbindungsdaten werden vom TCP/IP-Protokoll in Windows nicht unterstützt. Verbindungsdaten werden nur auf ATM (RAWWAN) über einen Raw-Socket unterstützt.