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

C sendto()对IPv4有不同的行为&;IPv6将数据报发送到无法到达的目标时,c,sockets,network-programming,udp,C,Sockets,Network Programming,Udp,当我使用sendto()将数据报发送到不存在的目标时,我发现IPv4和IPv6的结果不同 IPv4: 它只返回一个正值 IPv6: 它返回-1,并将errno设置为eneturech 有人知道为什么会这样吗 这是我的密码: 令人惊讶的是IPv6会给你一个错误,而不是IPv4不能。IPv4通常只向连接的UDP套接字发送错误。当srv\u addr.sin6\u scope值不正确时,我就发生了这种情况 有关在其他问题中使用sin6_范围ID的更多信息: 您是否正在发送到您的邮箱中有路由的IPv

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

  • IPv4: 它只返回一个正值

  • IPv6: 它返回
    -1
    ,并将
    errno
    设置为
    eneturech

有人知道为什么会这样吗

这是我的密码:
令人惊讶的是IPv6会给你一个错误,而不是IPv4不能。IPv4通常只向连接的UDP套接字发送错误。

srv\u addr.sin6\u scope
值不正确时,我就发生了这种情况

有关在其他问题中使用sin6_范围ID的更多信息:

您是否正在发送到您的邮箱中有路由的IPv6地址?您可能有IPv4的所有路由(因为您有一个默认路由),但您有IPv6地址吗?您是否至少有一个绑定了IPv6的接口?您的套接字是使用AF_INET6创建的,但您使用相同的套接字发送到IPv4地址(sockaddr_in)。在IPv6套接字中允许这样做吗?我怀疑地址被翻译了,但我不知道这是可能的。我怀疑如果本地路由表中没有目标主机的路由,可能会导致早期故障。
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;
}