1

IPv4からIPv4、IPv4からIPv6、IPv6からIPv4、およびIPv6からIPv6のアドレス接続を可能にするソケットを作成しようとしています。

1.)プロトコルの組み合わせ(IPv4からIPv6、IPv6からIPv4など)は許可されていますか?

2.)その場合、ソケットの作成に送信元アドレスまたは宛先アドレスのファミリーを使用しますか?

現在、送信元アドレスを使用していますが、IPv6送信元アドレスとIPv4宛先アドレスを使用するとソケットエラー10014WSAEFAULTが発生します。

コードの関連部分:

if ( !strchr( srcAddr, '[' ) )
    sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
else
    sock = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP );

if ( !strchr( srcAddr, '[' ) )
{
    rc = bind( sock, ( struct sockaddr * ) &sAddrSrc, 
        sizeof( sAddrSrc ) );
}
else
{
    rc = bind( sock, ( struct sockaddr * ) &sAddrSrc6, 
        sizeof( sAddrSrc6 ) );
}

if ( !strchr( destAddr, '[' ) )
{
    rc = connect( sock, (struct sockaddr *) &sAddrDest, 
        sizeof(sAddrDest) );
}
else
{
    rc = connect( sock, ( struct sockaddr * ) &sAddrDest6, 
        sizeof( sAddrDest6 ) );
}
4

2 に答える 2

2

IPv6ソケットを使用して、IPv4アドレスまたはIPv6アドレスのいずれかに接続できます。IPv4ソケットは、IPv4宛先にのみ接続できます。サーバー側では、IPv6ソケットはIPv6またはIPv4からの接続を受け入れることができ、IPv4ソケットはIPv4接続のみを受け入れることができます。

自分でアドレスを解析することは避けてください。を使用してくださいgetaddrinfo。ただし、解析されない[]ため、最初にパーツを抽出する必要があります。getaddrinfoIPv4ソケットとIPv6ソケットのどちらを使用する必要があるかを示しますが、常にIPv6を使用する場合は、に設定ai_familyしてAF_INET6からに追加できAI_V4MAPPEDますai_flags。その場合、返されるアドレスは::ffff:IPv4、必要に応じて、IPv6ソケットがIPv4宛先に接続するために必要なものになります。

サーバー側では、IPv6ソケットを使用してから、必ず呼び出しsetsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof(int))て、IPv6接続とIPv4接続の両方を受け入れるようにします。(MSVCはこのC99構文を受け入れない場合があることに注意してください。)

そうは言っても、IPv4ソースでbindをすでに呼び出している場合は、IPv6宛先に接続できません。また、その逆も同様ですが、接続側でbindを呼び出さない場合、または選択するのを待つ場合は、答えが適用されます。 getaddrinfoを呼び出した後までバインドするアドレス。

于 2012-07-05T22:06:32.137 に答える
2

いいえ、ソケットが構成されているアドレスファミリとは異なるアドレスファミリに接続することはできません。IPv6とIPv4は異なるネットワークスタックを使用するため、IPv6エンドポイントに接続しようとしている場合は、送信元アドレスとしてIPv6も使用する必要があります。

あなたの場合、1つのIPv4アドレスとIPv6アドレス用に別の1つに接続する場合は、2つのソケットが必要になります。

サーバー側では、IPv4とIPv6をリッスンするために2つのソケットも必要です。両方のソケットは同じポート番号にバインドできますが(両方が異なるネットワークスタックであるため)、異なるIPアドレスでリッスンします。

このEBookは、IPv4とIPv6の両方のルーティングに関する非常に優れたリファレンスです。MicrosoftWindowsのTcp/IPの基礎

于 2012-07-05T22:07:26.483 に答える