2016-06-13 60 views
-2

我正在使用winsock2在C++中编写套接字程序,我试图使用WSAAccept来有条件地接受连接。我复制了来自MSDN的示例ConditionalFunction,以获取WSAAccept中的lpfnCondition参数,如下所示。尝试检索指针的内容时程序崩溃

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

试图访问在ConditionalFunction像这样WSABUF buffer = *lpCallerData我的程序崩溃的lpCallerId内容然而,当。我知道这是问题的根源,因为当我发表评论时,我的程序不会崩溃。我不认为我的所有代码都是必需的。任何帮助将是可爱的。

编辑:

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

请尝试创建一个[最小化,完整和可验证示例](http://stackoverflow.com/help/mcve),您可以向我们显示。 –

+0

什么是'lpCallerData'? – immibis

+2

如果您可以阅读有关此参数的MSDN文档:这些参数中的信息与连接请求一起发送。 *如果没有主叫方标识或主叫方数据可用,则相应的参数将为NULL *。 –

回答

3

由于卢克说,你是不是检查lpCallerData为NULL提领前。这就是为什么你的代码崩溃。

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

然而,lpCallerData是在TCP/IP毫无意义的,将永远 NULL。在连接建立期间,TCP/IP不支持交换主叫方/被叫方数据。这在WSAConnect()文档中明确提出:

lpCallerData参数包含一个指针,指向要与该连接请求(称为连接数据)一起发送任何用户数据。这是附加数据,不在正常网络数据流中,与网络请求一起发送以建立连接。此选项由传统协议(如DECNet,OSI TP4等)使用。

注意在Windows中TCP/IP协议不支持连接数据。通过原始套接字仅在ATM(RAWWAN)上支持连接数据。

相关问题