尝试检索指针内容时程序崩溃

时间:2016-06-13 22:15:38

标签: c++ pointers winapi winsock winsock2

我正在使用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
);

但是,当尝试访问lpCallerIdConditionalFunction的内容时,WSABUF buffer = *lpCallerData我的程序崩溃了。我知道这是问题的根源,因为当我评论该行时,我的程序不会崩溃。我不认为我的所有代码都是必要的。任何帮助都很可爱。

编辑:

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

1 个答案:

答案 0 :(得分:3)

正如Luke所说,在解除引用之前,你没有检查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)上支持连接数据。