My program is client server IPv6. the client can't make connection to the server? The client and server must use loop-back address the problem in this code its can't connect to the server
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;
}
A client TCP socket cannot connect()
to in6addr_any
. A TCP server can bind()
to in6addr_any
so it can then listen()
on all available local IPv6 network interfaces with a single SOCKET
. But the client must connect()
to a real IPv6 address that the server is actually listening on (such as in6addr_loopback
if the client is running on the same machine as the server. Your server can use GetAdaptersInfo()
or GetAdaptersAddresses()
to discover what its local IP addresses actually are that are valid for the client to connect()
to).
Also, you need to zero out the sockaddr_in6
struct completely. sockaddr_in6
has sin6_flowinfo
and sin6_scope_id
fields that you are not populating, so they will have random values from the stack. sin6_scope_id
in particular will affect connect()
's ability to use the correct network interface to connect to the server.
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));
...
Consider using getaddrinfo()
instead. Let the OS allocate a properly-populated sockaddr_in6
for you, which you can then pass as-is to connect()
(similarly to how I explained to you in your previous question for 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);
...