我的程序是客户端服务器IPv6。客户端无法建立与服务器的连接?客户端和服务器必须使用回送地址此代码中的问题,它无法连接到服务器
SOCKET sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
sockaddr_in6 hint;
hint.sin6_family = AF_INET6;
hint.sin6_port = htons(port);
hint.sin6_addr = in6addr_any;
// Connect to server
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server, Err #" << WSAGetLastError()
<< endl;
closesocket(sock);
WSACleanup();
return;
}
客户端TCP套接字不能connect()
至in6addr_any
。 TCP服务器可以从bind()
到in6addr_any
,因此可以通过单个listen()
在所有可用的本地IPv6网络接口上进行SOCKET
。但是客户端必须connect()
到服务器实际监听的真实IPv6地址(例如,如果客户端与服务器在同一台计算机上运行,则为in6addr_loopback
。服务器可以使用GetAdaptersInfo()
或GetAdaptersAddresses()
发现对客户端connect()
而言有效的本地IP地址实际是什么。
此外,您需要将sockaddr_in6
结构完全归零。 sockaddr_in6
具有未填充的sin6_flowinfo
和sin6_scope_id
字段,因此它们将具有来自堆栈的随机值。 sin6_scope_id
特别会影响connect()
使用正确的网络接口连接到服务器的能力。
SOCKET sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
sockaddr_in6 hint = {};
hint.sin6_family = AF_INET6;
hint.sin6_port = htons(port);
inet_pton(AF_INET6, "server IPv6 address here", &(hint.sin6_addr));
// Connect to server
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
...
考虑改为使用getaddrinfo()
。让操作系统为您分配一个适当填充的sockaddr_in6
,然后您可以按原样将其传递给connect()
(类似于我在previous question中为bind()
向您解释的方式)。
addrinfo hint = {};
hint.ai_family = AF_INET6;
hint.ai.socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
addrinfo *res;
err = getaddrinfo("server hostname or IPv6 address here", "server port here", &hint, &res);
if (err != 0)
{
cerr << "Can't get address to connect, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
SOCKET sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
freeaddrinfo(res);
WSACleanup();
return;
}
// Connect to server
int connResult = connect(sock, res->ai_addr, res->ai_addrlen);
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
closesocket(sock);
freeaddrinfo(res);
WSACleanup();
return;
}
freeaddrinfo(res);
...