【问题标题】:Program crashes when trying to retrieve contents of pointer尝试检索指针内容时程序崩溃
【发布时间】:2016-06-13 22:15:37
【问题描述】:

我正在使用 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 中的lpCallerId 的内容时,就像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);

【问题讨论】:

  • 请尝试创建一个Minimal, Complete, and Verifiable Example,您可以向我们展示。
  • 什么是lpCallerData
  • 如果您可以阅读有关此参数的 MSDN 文档:这些参数中的信息与连接请求一起发送。 如果没有来电者标识或来电者数据,则对应参数为NULL
  • @LukeLee 我不明白为什么尝试检索NULL 变量的内容会使我的程序崩溃。
  • @immibis lpCallerData 是,如MSDN 所述“lpCallerData 是一个包含任何用户数据的值参数。”

标签: c++ pointers winapi winsock winsock2


【解决方案1】:

正如 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) 上通过原始套接字支持连接数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    相关资源
    最近更新 更多