gpt4 book ai didi

c++ - IPv6 连接错误 WSAEAFNOSUPPORT

转载 作者:行者123 更新时间:2023-11-28 01:34:56 29 4
gpt4 key购买 nike

我使用主机名解析器为 IPv4/IPv6 编写了一个小型客户端。对于 IPv4 和解析器,它很好,但在 connect() 时不适用于 IPv6 我有一个问题 WSAGetLastError() 说 WSAEAFNOSUPPORT。

我将所有结构(AF_INET -> AF_INET6、SOCKADDR_IN -> SOCKADDR_IN6)切换到 IPv6 版本。

#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

int main()
{
printf("Simple_Client IPv4 & IPv6\n\n");

// Initiates Winsock
WSADATA WSAData;
WSAStartup(MAKEWORD(2, 0), &WSAData);

// Get Parameters IP/PORT and request
std::string str_HOSTNAME = "mirror.neostrada.nl";
int PORT = 21;

// RESOLVE IP
BOOL is_IPv6 = FALSE;
std::string str_dest_ip = "";

addrinfo hints = { 0 };
hints.ai_flags = AI_ALL;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

addrinfo * pResult;
getaddrinfo(str_HOSTNAME.c_str(), NULL, &hints, &pResult);

if (pResult == NULL)
{
printf("pResult error\n");
return -1;
}

if (pResult->ai_family == AF_INET)
{
printf("getaddrinfo = AF_INET (IPv4)\n");
is_IPv6 = FALSE;
}

if (pResult->ai_family == AF_INET6)
{
printf("getaddrinfo = AF_INET6 (IPv6)\n");
is_IPv6 = TRUE;
}

char str[128];
memset(str, 0, sizeof(str));

if (is_IPv6 == FALSE) // IPv4
{
if (inet_ntop(AF_INET, &(*((ULONG*)&(((sockaddr_in*)pResult->ai_addr)->sin_addr))), str, INET_ADDRSTRLEN))
str_dest_ip = char_to_string(str, strlen(str)); // Copy char in std::string
else
printf("inet_ntop error\n");
}

if (is_IPv6 == TRUE) // IPv6
{
if (inet_ntop(AF_INET6, &(*((ULONG*)&(((sockaddr_in6 *)pResult->ai_addr)->sin6_addr))), str, INET6_ADDRSTRLEN))
str_dest_ip = char_to_string(str, strlen(str)); // Copy char in std::string
}

printf("%s : %s | Port : %i\n", is_IPv6 ? "IPv6" : "IPv4", str_dest_ip.c_str(), PORT);

// Connect to the HOSTNAME
SOCKET sock;

if (is_IPv6 == TRUE)
{
SOCKADDR_IN6 sin;
sin.sin6_family = AF_INET6;

if(inet_pton(sin.sin6_family, str_dest_ip.c_str(), &sin) != 1)
printf("ERROR inet_pton %i\n", WSAGetLastError());

sin.sin6_port = htons(PORT);
sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
return -2;

if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) != SOCKET_ERROR)
{
printf("Connect Success to %s | PORT : %i\n", str_dest_ip.c_str(), PORT);
}
else
{
printf("ERROR connect to %s | PORT : %i : %i\n", str_dest_ip.c_str(), PORT, WSAGetLastError());
Sleep(10000);
return -2;
}
}

char buf[1024] = { 0 };

int size_recv = recv(sock, buf, sizeof(buf), 0);

printf("SIZE RECV = %i | DATA RECV = %s\n", size_recv, char_to_string(buf, size_recv).c_str());

WSACleanup();
getchar();
return 0;
}

如果有人有想法,感谢阅读。

最佳答案

问题出在这里:

inet_pton(sin.sin6_family, str_dest_ip.c_str(), &sin)

这会将 IPv6 地址写入 sin6_family 字段之上,破坏了整个结构。

应该是:

inet_pton(sin.sin6_family, str_dest_ip.c_str(), &sin.sin6_addr)

在开始时将整个 sin 结构零初始化也是一个好主意,因为它的字段比您填写的要多。

关于c++ - IPv6 连接错误 WSAEAFNOSUPPORT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49700784/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com