我正在使用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
);
但是,当尝试访问lpCallerId
中ConditionalFunction
的内容时,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);
答案 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)上支持连接数据。