2012-05-13 9 views
0

私はいくつかのソケットプログラミングを始めました。標準のBSD実装を使用する方法と、Windows上のWinsock APIへの変換方法を同時に学習することを試みています。私は、ネットワーキングを組み込んだ将来のプロジェクトに含めることができるWinsockユーティリティライブラリヘッダーを自分自身に設定しています。私は、IPv4とIPv6の両方で動作する機能を備えているので、私のライブラリをIPv4/6に無関係にしたい。IPv6を使用しないIPv6ネットワークプログラミング

私が抱えている問題は、明らかにIPv6インターネットに接続できないインターネットサービスにアクセスできないということです。私は世界IPv6の日が6月に登場することを知っています。多分これは変わるでしょう。しかし、私はそれを疑う。とにかく、私は特にIPv6アドレスやホスト上でその作業を書いている関数をテストすることができない。ここで

は一例です:

私は、文字列としてホスト名を取り、それを解決して、文字列として提示可能IPアドレスを返すことになっているこの機能を持っています。私はそれがアドレスファミリAF_INETまたはAF_INET6で得ることができる最初の良いIPアドレスを返すバージョン[ip_string()]を持っています。 2番目のバージョン[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; 
} 

私は(私はtest-ipv6.comを確認した)IPv6アドレス空間に達することができる接続ではないだから私がいる問題は(私は仮定している)ということで、いつでもこれらの関数のいずれかがgetaddrinfoはを呼び出します()はipv6ホストでは、関数はまったく返されないようです。

これは正常ですか? Winsock APIを通じてipv6が有効になっているかどうかを確認するために接続を確認する方法はありますか? ipv6以外の接続でipv6対応のコードをテストする良い方法はありますか?

+1

ちょうど脇の下ですが、二重 'i ++'があります。 "これらの関数のいずれかがipv6ホスト上でgetaddrinfo()を呼び出すと、関数はまったく返されないように見えます。"あなたはどういう意味ですか? " –

+0

私はこれに似たip6_string()という関数を持っています。この関数は、AF_INET6ファミリのアドレスだけを受け取ります。私がhostname "Zabec.net"で呼び出すと、このIPv6対応サイトのリストによると、有効なIPv6アドレス([link](http://www.sixxs.net/wiki/IPv6_Enabled_Websites))が返されます。ああ、私は他の人を取り除くことを意味した++。ありがとう、重要なことは何も影響しないし、それはまだその点でうまくいく。 –

答えて

4

これをテストするために独自の小さなIPv6インターネットワークを設定することもできますが、IPv6トンネルを取得するほうがはるかに簡単です。

プロバイダがIPv6アクセスを提供していない場合でも、あなたはそれでも使用可能なIPv6接続を得ることができます。たとえば、Hurricane Electricを見てください。

あなたの直面する問題は、Karolyが言ったように簡単かもしれません。 forループの中で最初のif()文を取り除くだけです。それはとにかく余分なものです(それ以外のi ++は物事を壊します!)。

+0

はい、それは冗長です。私はそれを編集して、ただ1つの++を持っていて、MAX_ATTEMPTSと照合します。しかし、これは機能を壊すことはありません、それは単に15の代わりに7または8の試行があることを意味するでしょう。オリジナルは余分なi + +でもうまくいった。しかし、これらのトンネルサービスは、私が探していたものであるようです。ありがとうございました。 –

0

WSAEnumProtocols()を使用すると、OSにIPv6がインストールされているかどうかを確認することができますが、IPv6ソケットと機能をコードで使用できるかどうかだけがわかります。ネットワーク上でIPv6接続を確立します。あなたのネットワークがIPv6をサポートしていないなら、できることはあまりありません。私は、IPv6対応のルータを手に入れて、テスト用のプライベートLANを作成することをお勧めします。