[英]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
,因此它可以使用單個SOCKET
在所有可用的本地 IPv6 網絡接口上進行listen()
。 但是客戶端必須connect()
到服務器實際監聽的真實 IPv6 地址(例如,如果客戶端與服務器在同一台機器上運行,則為in6addr_loopback
。您的服務器可以使用GetAdaptersInfo()
或GetAdaptersAddresses()
來發現什么它的本地 IP 地址實際上對客戶端connect()
有效)。
此外,您需要將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()
(類似於我在上一個問題中對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);
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.