在Windows的C++中使用recvfrom()的WSAEFAULT错误

问题描述:

我正在编写一个UDP服务器作为应用程序的一部分。在以下代码片段中:在Windows的C++中使用recvfrom()的WSAEFAULT错误

int ServerManager::onListen(void * data) 
{ 
    int numbytes; 
    char buf[512]; 
    socklen_t addrlen = sizeof(sockaddr_in); 
    struct sockaddr_in addr; 
    if((numbytes = recvfrom(listenSocket,buf, sizeof(buf),0,(SOCKADDR*) &addr, &addrlen) 
    == -1)) 
    { 
     std::cout << "recv error:" << WSAGetLastError(); 
     return -1; 
    } 
    std::cout << "done"; 
    return 0; 
} 

我收到错误代码10014“WSAEFAULT”,并且从未达到“完成”。我使用C++和winsock2。如果我用NULL替换最后两个参数,recvfrom()调用可以正常工作。根据我在其他地方看到的这个问题,我期望正确设置addrlen和缓冲区来解决问题,但是现在代码很简单,我正在努力寻找失败的原因。我觉得它一定是我忽略了的简单东西,任何帮助将不胜感激。

+0

是你的实际代码? – kfsone

+0

是的。 listenSocket等的绑定在一个单独的类函数中。如果这是相关的,我可以发布它(但它相当长,运行良好)。 –

+0

发生WSAEFAULT是因为buf无效或太小,或者因为fromLen太小。由于from是可选的,因此从头开始尝试,看看是否仍然出现错误。 – kfsone

该错误是由套接字的设置引起的。 在这种情况下,将ai_family从“AF_UNSPEC”更改为“AF_INET”解决了问题,但为了保留ipv6兼容性,代码被修改如下。

int ServerManager::onListen(void * data) 
{ 
    int numbytes; 
    char buf[MAXBUFLEN]; 
    SOCKADDR_STORAGE addr; 
    socklen_t addrlen = sizeof(addr); 
    if((numbytes = recvfrom(listenSocket,buf, sizeof(buf),0,(LPSOCKADDR) &addr, &addrlen) 
    == -1)) 
    { 
     std::cout << "recv error:" << WSAGetLastError(); 
     return -1; 
    } 
    std::cout << "done"; 
    return 0; 
}