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 対応コードをテストする良い方法はありますか?