gpt4 book ai didi

c++ - 调用 accept() 导致 WSAEFAULT 10014 Bad address

转载 作者:可可西里 更新时间:2023-11-01 02:51:35 25 4
gpt4 key购买 nike

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

我有这段代码:

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:

WSAEFAULT 10014 Bad address. The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).

我不明白,这些指针有什么坏处,它们都直接指向局部变量。 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 Bad address,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31658944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com