我正在使用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地址的结构。
例如,可能可以通过更多方法解决
但是我选择以这种方式手动初始化用于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/