0

好的,所以我已经开始做一些套接字编程,我正在尝试同时学习如何使用标准 BSD 实现以及如何将其转换为 Windows 上的 Winsock API。我正在为自己设置一个 Winsock 实用程序库头文件,它可以包含在未来的包含网络的项目中。我希望我的库与 IPv4/6 无关,因为它具有适用于 IPv4 和 IPv6 的功能。

我遇到的问题是我无法在任何地方访问互联网服务,显然无法连接到任何 IPv6 互联网。我知道世界 IPv6 日将在 6 月到来,所以也许这会改变。不过我对此表示怀疑。无论如何,我无法测试我编写的任何功能,特别是在 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确认),任何时候这些函数中的任何一个在 ipv6 主机上调用 getaddrinfo()函数似乎根本不返回。

这是正常的吗?无论如何检查连接以查看是否通过 Winsock API 启用了 ipv6?我有什么好方法可以在非 ipv6 连接上测试启用 ipv6 的代码吗?

4

2 回答 2

4

您可以设置自己的小型 IPv6 互联网来测试它,但让自己获得 IPv6 隧道会容易得多。

即使您的提供商不提供 IPv6 访问(您应该为此大喊大叫!),您仍然可以获得可用的 IPv6 连接。以飓风电气为例。

你眼前的问题可能就像卡罗利所说的那样简单。只需去掉 for 循环内的第一个 if() 语句。无论如何它都是多余的(除了额外的 i++ 会破坏事情!)。

于 2012-05-13T21:13:26.783 回答
0

要回答有关检查 IPv6 可用性的问题,您可以使用WSAEnumProtocols()查看操作系统是否安装了 IPv6,但这只会告诉您是否可以在代码中使用 IPv6 套接字和函数,而不是您是否能够建立 IPv6 连接网络。如果您的网络不支持 IPv6,那么您无能为力。我建议您为自己准备一个支持 IPv6 的路由器并创建一个专用 LAN 进行测试。

于 2012-05-14T03:43:43.983 回答