我正在使用MinGW编译器和winsock2 API编写用于Windows的自定义TCP服务器。

我有这段代码:

TCPSocket TCPSocket::accept() {

    TCPSocket clSocket;
    struct sockaddr_in clAddr;
    socklen_t clAddrSize;

    clAddrSize = sizeof(clAddr);

    clSocket.shared->sockFd = ::accept(shared->sockFd, (struct sockaddr *)&clAddr, &clAddrSize);
    if (clSocket.shared->sockFd < 0) {
        printf("failed to accept incoming connection (code: %d)\n", WSAGetLastError());
        throw SocketException(6, "failed to accept incoming connection");
    }

    clSocket.shared->buffer = new byte [BUFFER_SIZE];
    clSocket.shared->curPos = clSocket.shared->endPos = clSocket.shared->buffer;

    return clSocket;

}

但是在调用accept()之后
failed to accept incoming connection (code: 10014)

根据MSDN:



我不明白,这些指针怎么可能不好,它们都直接寻址局部变量。在另一个函数中,clAddrSize初始化并且shared->sockFd初始化
void TCPSocket::listen(uint16_t port, int backlog) {

    struct addrinfo * ainfo;
    char portStr[8];
    int res;

    if (shared->sockFd != -1)
        logicError(1, "socket already initialized, need to close first");

    snprintf(portStr, sizeof(portStr), "%hu", (ushort)port);
    if (getaddrinfo("localhost", portStr, NULL, &ainfo) != 0)
        systemError(2, "failed to retrieve info about localhost", false);

    shared->sockFd = socket(ainfo->ai_family, SOCK_STREAM, IPPROTO_TCP);
    if (shared->sockFd < 0)
        systemError(3, "failed to create a TCP socket", false);

    res = bind(shared->sockFd, ainfo->ai_addr, ainfo->ai_addrlen);
    if (res != 0)
        systemError(5, "failed to bind socket to local port", true);

    res = ::listen(shared->sockFd, backlog);
    if (res != 0)
        systemError(6, "failed to set socket to listen state", true);

    freeaddrinfo(ainfo);

}

你看到我忽略的东西了吗?

最佳答案

好的,感谢CristiFati,我找到了问题。
函数getaddrinfo(“localhost”,portStr,NULL,&ainfo)使用的方式是返回IPv6地址。当accept接收到sockaddr_in时,这是IPv4地址的结构。

例如,可能可以通过更多方法解决

  • 使用sockaddr_in6进行IPv6通信
  • 告诉getaddrinfo仅搜索带有第三个参数
  • 的IPv4结果
  • 在getaddrinfo
  • 返回的链接列表中获取下一个结果

    但是我选择以这种方式手动初始化用于IPv4协议(protocol)的套接字:
        struct sockaddr_in myAddr;
    
        memset(&myAddr, 0, sizeof(myAddr));
        myAddr.sin_family = AF_INET;
        myAddr.sin_port   = htons((ushort)port);
    
        shared->sockFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (shared->sockFd < 0)
            systemError(3, "failed to create a TCP socket", false);
    
        res = bind(shared->sockFd, (struct sockaddr *)&myAddr, sizeof(myAddr));
        if (res != 0)
            systemError(5, "failed to bind socket to local port", true);
    

    从那以后,一切正常。

    关于c++ - 调用accept()导致WSAEFAULT 10014错误的地址,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31658944/

    10-12 18:11