2012-05-13 6 views
0

ОК, поэтому я начал программирование сокетов, я пытаюсь одновременно научиться делать что-то, используя стандартную реализацию BSD, а также как это переводится в Winsock API в Windows. Я настраиваю свой собственный заголовок библиотеки утилиты Winsock, который может быть включен в будущие проекты, которые включают в себя сетевое взаимодействие. Я хочу, чтобы моя библиотека была агностикой IPv4/6, поскольку она имеет функции, которые работают как с IPv4, так и с IPv6.Сетевое программирование IPv6 без IPv6?

Проблема, с которой я сталкиваюсь, заключается в том, что у меня нет доступа к интернет-сервису, где, по-видимому, невозможно подключиться к любому интернет-протоколу IPv6. Я знаю, что в июне ожидается Всемирный день IPv6, так что, возможно, это изменится. Я в этом сомневаюсь. Во всяком случае, я не могу проверить какие-либо функции, которые я пишу, особенно на IPv6-адресах или хостах.

Вот пример:

У меня есть эта функция, которая должна взять имя хоста в виде строки, решить ее, а затем вернуть презентабельный IP-адрес в виде строки. У меня есть версия [ip_string()], которая возвращает первый хороший IP-адрес, который он может получить в семействе адресов AF_INET или AF_INET6. Вторая версия [ip4_string()] будет возвращать только IPv6-адрес и то же самое с [ip6_string()], возвращающим адрес IPv6.

char *ip_string(const char hostname[]) 
{ 
    char *buffer = new char[INET6_ADDRSTRLEN]; 
    struct addrinfo hints, *res, *ptr; 
    void *addr = NULL; // void pointer to be set to sin_addr or sin6_addr 

    /** Initialize hints structure */ 
    ZeroMemory(&hints, sizeof(hints)); 
    hints.ai_family = AF_UNSPEC; // ipv4 or ipv6 address family 
    hints.ai_socktype = SOCK_STREAM; 

    /** Function getaddrinfo returns non-zero if there's a problem */ 
    if (getaddrinfo(hostname, "http", &hints, &res) != 0) 
     throw WinsockException("getaddrinfo()"); 

    /** Loop through list of address structures till we find a valid IP */ 
    const int MAX_ATTEMPTS = 15; 
    int i = 0; 
    for (ptr = res; (ptr != NULL); ptr = ptr->ai_next) 
    { 
     if (i++ <= MAX_ATTEMPTS) 
     { 
      if (ptr->ai_family == AF_INET) 
      {  // Cast appropriately for ipv4 
       addr = &(((struct sockaddr_in *)ptr->ai_addr)->sin_addr); 
       inet_ntop(ptr->ai_family, (in_addr*) addr, buffer, INET_ADDRSTRLEN); 
      } 
      else if (ptr->ai_family == AF_INET6) 
      {  // Cast appropraitely for ipv6 
       addr = &(((struct sockaddr_in6 *)ptr->ai_addr)->sin6_addr); 
       inet_ntop(ptr->ai_family, (in6_addr*) addr, buffer, INET6_ADDRSTRLEN); 
      } 
     } 
    } 

    freeaddrinfo(res); // free list of address structures 
    if (addr == NULL) 
    { 
     delete [] buffer; 
     return NULL; 
    } 

    return buffer; 
} 

Проблема у меня в том, что (я предполагаю), потому что я не на связи, что может достичь адресного пространства IPv6 (который я подтвердил test-ipv6.com), в любое время любой из этих функций вызывает getaddrinfo() на хосте ipv6, функция, похоже, вообще не возвращается.

Это нормально? В любом случае, проверьте соединение, чтобы узнать, включен ли ipv6 через Winsock API? Есть ли какой-либо хороший способ для проверки IPv6-кода на не-ipv6-соединении?

+1

просто боковое поле, но есть двойной 'i ++'. «в любое время, когда любая из этих функций вызывает getaddrinfo() на хосте ipv6, функция, кажется, вообще не возвращается», что вы имеете в виду «кажется»? –

+0

У меня есть функция, аналогичная функции ip6_string(), которая будет принимать адрес только в семействе AF_INET6. Когда я вызываю его на имя хоста «Zabec.net», которое согласно этому списку сайтов с поддержкой IPv6 должно возвращать действительный адрес IPv6 ([ссылка] (http://www.sixxs.net/wiki/IPv6_Enabled_Websites)). О да, я хотел вытащить другого i ++. Спасибо за это, не влияет на что-то важное, хотя и в этом отношении все еще отлично. –

ответ

4

Чтобы проверить это, вы можете настроить собственную небольшую внутреннюю сеть IPv6, но вам будет намного проще получить туннель IPv6.

Даже если ваш провайдер не предлагает доступ к IPv6 (вы должны кричать на них за это!), Вы все равно можете получить доступное IPv6-соединение. Например, посмотрите на Hurricane Electric.

Ваша непосредственная проблема может быть такой же простой, как и Кароли. Просто избавитесь от первого оператора if() только внутри цикла for. В любом случае это избыточно (другое, что лишний i ++ ломает вещи!).

+0

Да, это избыточно, я отредактировал его, чтобы иметь только один i ++ и проверить его с помощью MAX_ATTEMPTS. Тем не менее, это не нарушит функцию, это просто означает, что вместо 15 или 8 попыток вместо 15. Исходный код был просто отлично, даже с дополнительным i ++.Однако эти туннельные службы, похоже, именно то, что я искал. Спасибо много. –

0

Чтобы ответить на вопрос о проверке доступности IPv6, вы можете использовать WSAEnumProtocols(), чтобы узнать, установлена ​​ли ОС IPv6, но это только скажет вам, можете ли вы использовать сокеты и функции IPv6 в коде, а не сможете ли вы для установления соединений IPv6 по сети. Если ваша сеть не поддерживает IPv6, вы не можете многое сделать. Я бы предложил вам получить маршрутизатор с поддержкой IPv6 и создать частную локальную сеть для тестирования.

Смежные вопросы