IPv6 客户端无法连接到 IPv6 服务器

IPv6 client can't connect to IPv6 server

我的程序是客户端服务器 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() 以发现其本地 IP 地址实际上是对客户端有效的 connect() 到)。

此外,您需要将 sockaddr_in6 结构完全清零。 sockaddr_in6 具有您未填充的 sin6_flowinfosin6_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()。让 OS 为您分配一个正确填充的 sockaddr_in6,然后您可以按原样将其传递给 connect()(类似于我在您的 中向您解释的方式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);
...