2012-05-13 51 views
0

好吧,所以我開始做一些套接字編程,我試圖同時學習如何使用標準的BSD實現來做事情,以及如何轉換成Windows上的Winsock API。我正在設置自己的Winsock實用程序庫標題,該標題可以包含在將來包含網絡的項目中。我希望我的庫是IPv4/6不可知論者,因爲它具有兼容IPv4和IPv6的功能。沒有IPv6的IPv6網絡編程?

我遇到的問題是,我無法在任何地方訪問Internet服務,顯然無法連接到任何IPv6 Internet。我知道世界IPv6的一天即將在六月份發佈,所以這可能會改變。儘管如此,我懷疑它。無論如何,我無法測試我編寫的那些功能,特別是IPv6地址或主機上的功能。

下面是一個例子:

我有這個功能是應該採取一個主機名作爲字符串,解決它,然後返回一個像樣的IP地址爲一個字符串。我有一個版本[ip_string()],它返回它可以在地址族AF_INET或AF_INET6中獲得的第一個良好IP地址。第二個版本[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主機上的功能似乎根本不會返回。

這是正常的嗎?無論如何檢查連接,看看是否通過Winsock API啓用了ipv6?有沒有什麼好的方法來測試非ipv6連接上啓用ipv6的代碼?

+1

只是一個旁註,但有一個雙'i ++'。 「任何時候,任何這些函數都會調用ipv6主機上的getaddrinfo()函數似乎根本不會返回」你的意思是什麼「似乎」? –

+0

我有一個類似於這個稱爲ip6_string()的函數,只有在家庭AF_INET6中的地址。當我根據啓用了IPv6的站點列表的主機名稱「Zabec.net」調用它時,應該返回一個有效的IPv6地址([link](http://www.sixxs.net/wiki/IPv6_Enabled_Websites))。哦,是的,我打算拿出其他的i ++。謝謝你,雖然沒有影響到任何重要,但在這方面它仍然運行良好。 –

回答

4

您可以設置自己的小型IPv6互聯網絡來測試這一點,但僅僅讓自己的IPv6隧道更容易。

即使你的提供者沒有提供IPv6訪問(你應該對他們大喊大叫!),你仍然可以獲得可用的IPv6連接。例如,看看Hurricane Electric

您的直接問題可能與Karoly所說的一樣簡單。只需擺脫for循環中的第一個if()語句即可。無論如何,這是多餘的(除此之外,額外的i ++會破壞一切!)。

+0

是的,它是多餘的,我編輯它只有一個i ++並檢查MAX_ATTEMPTS。然而,這不會破壞函數,它只是意味着只有7或8次嘗試而不是15次。即使使用額外的i ++,原始運行也很好。然而,這些隧道服務似乎正是我所期待的。非常感謝。 –

0

要回答您關於檢查IPv6可用性的問題,可以使用WSAEnumProtocols()來查看操作系統是否安裝了IPv6,但只會告訴您是否可以在代碼中使用IPv6套接字和函數,而不是您是否可以通過網絡建立IPv6連接。如果你的網絡不支持IPv6,那麼你可以做的不多。我建議你讓自己的IPv6路由器,並創建一個專用局域網進行測試。