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.

Если что-то непонятно спрашивайте.