0

OK、ソケットプログラミングを始めたので、標準の BSD 実装を使用して物事を行う方法と、それを Windows の Winsock API に変換する方法を同時に学習しようとしています。ネットワークを組み込む将来のプロジェクトに含めることができる Winsock ユーティリティ ライブラリ ヘッダーを自分で設定しています。私のライブラリは、IPv4 と IPv6 の両方で動作する機能を備えているという点で、IPv4/6 にとらわれないようにしたいと考えています。

私が抱えている問題は、明らかにIPv6インターネットのいずれにも接続できないインターネットサービスにアクセスできないことです。World IPv6 day が 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;
}

私が抱えている問題 (私は推測しています) は、これらの関数のいずれかが ipv6 ホストで getaddrinfo() を呼び出すたびに、使用可能な IPv6 接続がないためです (これはtest-ipv6.comを使用して確認しました)。関数はまったく返されないようです。

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

4

2 に答える 2

4

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

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

あなたの差し迫った問題は、カロリーが言ったことと同じくらい単純かもしれません. for ループのすぐ内側にある最初の if() ステートメントを取り除くだけです。とにかく冗長です(余分なi ++が物事を壊すことを除いて!)。

于 2012-05-13T21:13:26.783 に答える
0

IPv6 の可用性の確認に関する質問に答えるにWSAEnumProtocols()は、OS に IPv6 がインストールされているかどうかを確認するために使用できますが、IPv6 ソケットと関数をコードで使用できるかどうかのみがわかり、IPv6 接続を確立できるかどうかはわかりません。ネットワーク。ネットワークが IPv6 をサポートしていない場合、できることはあまりありません。IPv6 対応のルーターを用意して、テスト用のプライベート LAN を作成することをお勧めします。

于 2012-05-14T03:43:43.983 に答える