0

我的代码在从 XP 到 10 的任何 Windows 上都能完美运行。现在我在 Win11 中首次测试了我的代码,connect() 函数失败并出现错误 10014 WSAEFAULT:

地址不好。系统在尝试使用调用的指针参数时检测到无效的指针地址。如果应用程序传递了无效的指针值,或者缓冲区的长度太小,则会发生此错误。例如,如果作为 sockaddr 结构的参数的长度小于 sizeof(sockaddr)。

但是,当我使用调试器检查时, sockaddr_in 结构似乎已正确传递:

connect(hSocket, (sockaddr*)(&InSockAddr), sizeof(InSockAddr))

在此处输入图像描述

我正在使用 Visual C++ 2015 编译器。

以下是相关代码的片段:

#include <WinSock2.h>

class CConnection
{
   public:
    static bool         bWinsockInitialized;
    SOCKET              hSocket = INVALID_SOCKET;
    sockaddr_in         sockAddr;
         
    bool                Create();
    bool                InitializeWinsock();
    bool                Connect(sockaddr_in &InSockAddr);
};   

CConnection sckt_Main;
sockaddr_in g_sockAddr;


void main()
{
    if (!sckt_Main.Create())
    {
        // Error: Unable to create connection socket
        return;
    }

    g_sockAddr.sin_family = AF_INET;

    // Get IP address from string. 
    // If address is a DNS, HostInfo->h_addr will contain resolved IP address.
    // Save host information into HostInfo struct:
    hostent* HostInfo = gethostbyname("127.0.0.1");

    //Error checking:
    if (!HostInfo) {
        return;
    }

    assert((sizeof(g_sockAddr.sin_addr)) >= HostInfo->h_length);

    //Copy the resolved IP address into our sockAddr structure: 
    memcpy(&g_sockAddr.sin_addr, HostInfo->h_addr, HostInfo->h_length);

    //Saves connection port
    g_sockAddr.sin_port = htons(atoi("2405"));
    
    sckt_Main.Connect(g_sockAddr);
}


bool CConnection::Create()
{
    if (!InitializeWinsock()) {
        return false;
    }
        
    hSocket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
        
    if (this->hSocket == INVALID_SOCKET) 
        return false;
        
    return true;
}


bool CConnection::InitializeWinsock()
{
    WSADATA wsaData;
    if (!WSAStartup(MAKEWORD(2, 2), &wsaData)) {
       bWinsockInitialized = true;
    } 
    else bWinsockInitialized = false;
        
    return bWinsockInitialized;
}


bool CConnection::Connect(sockaddr_in &InSockAddr)
{

    // If no error occurs, connect returns zero. 
    // Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
    if (connect(hSocket, (sockaddr*)(&InSockAddr), sizeof(InSockAddr)) == 0)
    {
       // Connect SUCCESS
       return true;
    }
    else 
    {   
       // !!! connect error !!!
       int err = WSAGetLastError();
       return false;
    }
}
4

1 回答 1

1

如评论中所述,您的代码不支持 IPv6。Windows 11 默认启用 IPv6。

您应该将您的代码更新为与 IPv4 与 IPv6 无关。

请参阅Microsoft 文档

注意微软checkv4.exe很久以前就停止发货了,但是如果我根据你的代码运行它,我会得到:

sockaddr_in : use sockaddr_storage instead, or use sockaddr_in6 in addition for IPv6 support

AF_INET : use AF_INET6 in addition for IPv6 support

gethostbyname : use getaddrinfo instead

hostent : use addrinfo instead
于 2021-11-05T21:52:18.963 回答