2

以前、存在しない宛先にデータグラムを送信したときにsendto()、IPv4 と IPv6 で結果が異なることがわかりました。

  • IPv4: 正の値を返すだけです。

  • IPv6: に-1設定errnoして返す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;
}
4

2 に答える 2

1

これは、srv_addr.sin6_scope値が正しくないときに発生しました。

他の質問での sin6_scope ID の使用に関する詳細情報: IPv4 クライアント/サーバー アプリでの IPv6 のサポートの追加 - sin6_flowinfo および sin6_scope_id フィールド?

于 2014-02-28T21:01:07.917 に答える
1

IPv4 ではエラーが発生しないのではなく、IPv6 ではエラーが発生する可能性があるというのは驚くべきことです。IPv4 は通常、接続されたUDP ソケットにのみエラーを配信します。

于 2013-01-17T07:13:01.737 に答える