connect () возвращает "недопустимый аргумент" с IPv6-адресом
У меня есть эта простая пара клиент-серверных приложений. Код довольно прост, я использую только новые, рекомендуемые методы, такие как getaddinfo и т. д., И все работает отлично для ipv4. Даже для loopback ipv6 (:: 1) он работает. Проблемы начинаются, когда дело доходит до некоторых других адресов IPv6... У меня есть две машины в сети, все работает нормально, когда я передаю их IPv4-адреса, но когда я даю своему клиенту ipv6-адрес, я получаю ошибку при подключении функции: недопустимый аргумент. Эй, разве я уже не знаю? это? Я знаю! Когда я пытаюсь ping6 этот адрес IPv6, я получаю ту же ошибку:
connect: недопустимый аргумент
но есть способ преодолеть этот блок - нужно выбрать интерфейс с переключателем - I, и с тех пор все работает гладко. Но как я могу добиться того же в своем клиентском приложении? Что мне делать? Мой клиентский код выглядит так:
struct addrinfo hints;
struct addrinfo *server;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int status;
if((status = getaddrinfo(argv[1], argv[2], &hints, &server) != 0))
{
perror("getaddrinfo error");
return 1;
}
int sock_fd;
struct addrinfo *ptr;
for(ptr=server;ptr!=NULL;ptr=ptr->ai_next)
{
if( (sock_fd = socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol)) == -1)
{
perror("socket error");
continue;
}
if( connect(sock_fd, ptr->ai_addr,ptr->ai_addrlen) == -1 )
{
perror("connect error");
continue;
}
break;
}
3 ответов
адреса, которые начинаются с ff...
несколько групповых адресов. Подключение потока к многоадресному адресу не работает.
адреса, которые начинаются с fe80...
являются локальными адресами ссылок, с которыми связан идентификатор интерфейса. Попробуйте посмотреть на sockaddr
вернулся из getaddrinfo
, это
вам нужно указать интерфейс для IPv6 ping (т. е.-i eth0):
ping6 -I eth0 fe80::208:54ff:fe34:22ae
использование link-local адресов для IPv6 ping, требуется определить, какое устройство он должен отправить / получить пакет-каждое устройство имеет link-local адрес.
попытка без этого приведет к сообщению об ошибке, например:
--> # ping6 fe80::208:54ff:fe34:22ae
connect: Invalid argument
В этом случае вы должны указать интерфейс, кроме того, как показано здесь:
--> # ping6 -I eth0 fe80::208:54ff:fe34:22ae
PING fe80::208:54ff:fe34:22ae(fe80::208:54ff:fe34:22ae) from fe80::208:54ff:fe34:22ae eth0: 56 data bytes
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=0 ttl=64 time=0.027 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from fe80::208:54ff:fe34:22ae: icmp_seq=2 ttl=64 time=0.036 ms
один подобный подход, вы должны следовать в ваше клиентское приложение..
моя рекомендация заключается в том, что вы включаете протокол IP6 в интерфейсе/сетевом подключении, кроме того, выбросьте протокол ip4, если у вас все еще есть ошибка.
на моем Linux Box это тоже произошло, когда у меня был ip4-интерфейс активен, и мое приложение пыталось использовать ip4-интерфейс с настройками ip6. То же самое должно быть справедливо и для windows.
Если что-то непонятно спрашивайте.