Есть ли разница между IPv4 и IPv6 на уровне сокетов? - PullRequest
9 голосов
/ 01 марта 2010

Мне нужно добавить поддержку IPv6 в существующее приложение на основе сокетов, которое в настоящее время поддерживает только IPv4. Чтобы охватить наступающую эру IPv6, кто-то приказал мне добавить интерфейс IPv6 для приложения и позволить внешнему миру выбирать либо интерфейс IPv4, либо интерфейс IPv6 при попытке связи с приложением.

Мой вопрос: правда ли, что для уровня API обработки сокетов в Linux нет никакой разницы между обработкой сокетов на основе IPv4 и сокетов на основе IPv6?

Более того, возможно ли позволить сокету прослушивать два IP-адреса с одинаковым портом? Если это правда, то реализовать требование - тривиальная работа, наверное.

Ответы [ 5 ]

6 голосов
/ 01 марта 2010

Невозможно прослушивать 2 разных IP-адреса с 1 сокетом TCP, однако, если вы прослушиваете все интерфейсы, используя адрес in6addr_any , который также будет включать все адреса IPv4 (хотя я считаю, что, например, У linux есть опция ядра, чтобы отключить это отображение).

API-интерфейс сокетов (более новая версия) достаточно прозрачен в отношении того, используете ли вы IPv4 или IPv6, но следует тщательно следить за тем, как обычно кодируется приложение IPv4.

например. этот код IPv4, который принимает соединение и распечатывает адрес удаленного хоста:

 struct sockaddr_in client_addr;
 socklen_t addr_len = sizeof(client_addr);
 client_data->fd = accept(server_fd,(struct sockaddr*)&client_addr,&addr_len);
 log_printf("New client from %s\n",inet_ntoa(client_addr.sin_addr.s_addr));

Должен быть преобразован в следующее, которое обрабатывает как IPv4, так и IPv6

 struct sockaddr_storage client_addr;
 char numeric_addr[INET6_ADDRSTRLEN];
 socklen_t addr_len = sizeof(client_addr);
 client_data->fd = accept(server_fd,(struct sockaddr*)&client_addr,&addr_len);
 if(client_addr.ss_family == AF_INET)
    log_printf("New client from %s\n",inet_ntop(client_addr.ss_family,((struct sockaddr_in*)&client_addr)->sin_addr.s_addr ,numeric_addr,sizeof numeric_addr));
 else if(client_addr.ss_family == AF_INET6)
    log_printf("New client from %s\n",inet_ntop(client_addr.ss_family,((struct sockaddr_in6*)&client_addr)->sin6_addr ,numeric_addr,sizeof numeric_addr));

Хотя я считаю, что вы могли бы сделать это еще более элегантно и прозрачно с помощью getaddrinfo ()

Вот дополнительные примечания о независимости уровня IP: http://uw714doc.sco.com/en/SDK_netapi/sockC.PortIPv4appIPv6.html http://www.kame.net/newsletter/19980604/

4 голосов
/ 01 марта 2010

Большая часть обработки сокетов одинакова для IPv4 и IPv6. На сервере, после того как вы связали свой адрес, вызовы listen, accept, recv и send будут работать одинаково для подключений IPv4 и IPv6.

Но любые функции, которые работают с адресами, такими как connect, bind, getsockname, getpeername, необходимо будет изменить, так как вам нужно использовать sockaddr_in6. Также вам нужно изменить функции, которые работают с адресом (например, вызовы inet_addr должны быть изменены на inet_pton).

В Linux, если вы связываетесь с in6addr_any, будут работать подключения как IPv4, так и IPv6 к этому порту (хотя при этом может прослушиваться более 2 адресов, поскольку он также будет прослушивать петлю IPv4 127.0.0.1 и IPv6. loopback ::1). Но в Windows мне никогда не удавалось заставить это работать, и мне нужно слушать один сокет для IPv4 и другой сокет для IPv6.

2 голосов
/ 06 марта 2010

Руководство Beej по сетевому программированию рассматривает различия в кодировании для IPv4 и IPv6.http://beej.us/guide/bgnet/

Он выделил один раздел для изменения существующего кода IPv4 для обработки IPv6.

Он также объясняет, как абстрактно кодировать на уровне сокетов, чтобы вам не нужно было знатьили вы не имеете дело с IPv4-адресом или IPv6.

0 голосов
/ 01 марта 2010

IPv6 - это 128-битное адресное пространство и предлагает больше функций (без учета состояния, многоадресная рассылка, более простая обработка для маршрутизаторов, и многие другие) по сравнению с IPv4 (32-битная) адресное пространство для IPv4 заканчивается, но с помощью NAT / SNAT это может увеличить срок службы протокола IPv4. Использование IPv6 зависит от того, может ли ОС поддерживать новый протокол. Он, безусловно, доступен в Windows 7, Linux ... Главное, что IPv6 обратно совместим с IPv4 ...

Чтобы ответить на ваш вопрос, это зависит от уровня API, при условии, что ОС может поддерживать сетевой стек IPv6. Вот пример примера сокетов IPv6, который можно найти в MSDN , для Linux , использование сокетов в основном такое же, за исключением того, что вы будете использовать sockaddr_in6 ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

0 голосов
/ 01 марта 2010

Я считаю, что есть разница, в основном в том, как назначаются / отображаются IP-адреса и маски подсетей.

Методы, которые принимают входящий адрес IPv4, не будут работать и выдают исключение, если им дается чистый IPv6, поэтому ваши методы должны будут проверить, какое соединение было инициировано, кроме того, что я так не думаю .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...