2016-06-13 43 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)上支持連接數據。

相關問題