sendto()对IPv4&具有不同的行为将数据报发送到无法到达目的地时的IPv6

时间:2013-01-17 07:08:42

标签: c sockets network-programming udp

当我使用sendto()将数据报发送到不存在的目的地时,我发现IPv4和IPv6的结果不同。

  • 的IPv4: 它只返回一个正值。

  • 的IPv6: 它返回-1errno设置为ENETUNREACH

有谁知道为什么会这样?

这是我的代码:

int main (int argc, char *argv[])
{
    // Usage: program [version]
    int version = argc == 1 ? 4 : atoi(argv[1]);

    int fd = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
    if (fd == -1)
        ErrAndExit ("socket");

    if (version == 4) // use ipv4
    {
        struct sockaddr_in srv_addr;
        memset (&srv_addr, 0, sizeof(srv_addr));
        srv_addr.sin_family = AF_INET;
        srv_addr.sin_port = htons (11111);
        if (inet_pton (AF_INET, "192.168.0.200", &srv_addr.sin_addr) != 1)
            ErrAndExit ("inet_pton");

        socklen_t len = sizeof(srv_addr);
        puts("going to sendto...");
        ssize_t res = sendto (fd, "hello", 6, 0, (struct sockaddr*) &srv_addr, len);
        if (res == -1)
            ErrAndExit("sendto");

        printf ("done with res: %ld\n", res);
    }
    else // use ipv6
    {
        struct sockaddr_in6 srv_addr;
        memset (&srv_addr, 0, sizeof(srv_addr));
        srv_addr.sin6_family = AF_INET6;
        srv_addr.sin6_port = htons (11111);
        if (inet_pton (AF_INET6, "2002::148:249", &srv_addr.sin6_addr) != 1)
            ErrAndExit ("inet_pton");

        socklen_t len = sizeof(srv_addr);
        puts("going to sendto...");
        ssize_t res = sendto (fd, "hello", 6, 0, (struct sockaddr*) &srv_addr, len);
        if (res == -1)
            ErrAndExit("sendto");

        printf ("done with res: %ld\n", res);
    }
    return 0;
}

2 个答案:

答案 0 :(得分:1)

令人惊讶的是IPv6可以给你一个错误,而不是IPv4不能。 IPv4通常只向连接的 UDP套接字提供错误。

答案 1 :(得分:1)

srv_addr.sin6_scope值不正确时,我发生了这种情况。

有关在其他问题中使用sin6_scope ID的更多信息: Adding support for IPv6 in IPv4 client/server apps - sin6_flowinfo and sin6_scope_id fields?