スティーヴォーの答えをフォローアップするために、それもシステムの場合はC#でのIPv6のソースフィルタリングを行うことも可能です。 Net.Sockets.SocketOptionName列挙では、数値を直接キャストして必要なオプションを定義していません。
(SocketOptionName) 45; //MCAST_JOIN_SOURCE_GROUP
ソケットの関数SetSocketOptionは、コールオプションが認識されない場合でも、「Windowsソケット」に行かせます。実際の闘争は、そのオプションと共に送信される必要があるデータ構造そのものになります。 ソースフィルタを設定するには、データ構造は次のようにする必要があります。group_source_req。以前の構造体は通常sockaddr_inとsockaddr_in6のユニオン内にあるsockaddr_storageを使用しています。
sockaddr_in6 sockIn = new sockaddr_in6
{
sin6_family = (ushort) endPoint.AddressFamily,
sin6_port = (ushort)endPoint.Port,
sin6_scope_id = 0
};
for (int i = 0; i < endPoint.Address.GetAddressBytes().Length; i++)
{
sockIn.sin6_addr[i] = endPoint.Address.GetAddressBytes()[i];
}
SOCKADDR_IN6のバイトは今溶液を用いて抽出することができます:あなたは今、これを行うことにより、SOCKADDR_IN6を作成することができます
private unsafe struct sockaddr_storage
{
public short ss_family; //2
private fixed byte __ss_pad1[6]; //6
private Int64 __ss_align; //8
private fixed byte __ss_pad2[112]; //112
}
private unsafe struct sockaddr_in
{
public ushort sin_family; //2
public ushort sin_port; //2
public fixed byte sin_addr[4]; //4
private fixed byte sub_zero[8]; //8
}
private unsafe struct sockaddr_in6
{
public ushort sin6_family; //2
public ushort sin6_port; //2
public int sin6_flowinfo; //4
public fixed byte sin6_addr[16]; //16
public uint sin6_scope_id; //4
}
private struct group_source_req
{
public uint gr_interface; //4
//Compiler add a padding here: //4
public sockaddr_storage gr_group; //128
public sockaddr_storage gr_source; //128
}
:この動作を再現するために、我々はこのように同じ構造体を定義することができますhereを提供し、以前に作成したSOCKADDR_STORAGEに直接コピー:
sockaddr_storage sock = new sockaddr_storage
{
ss_family = (short)endPoint.AddressFamily
};
//[...]
byte[] sockInData = getBytes(sockIn);
byte* sockData = (byte*) &sock;
for (int i = 0; i < sockInData.Length; i++)
{
sockData [i] = sockInData[i];
}
今、あなたがSOCKADDR_STORAGEを持っていることをあなたはgroup_sに割り当てることができますource_reqを実行し、以前に行ったようにgroup_source_reqのデータを抽出し、オプションを設定するときにこれを値として使用します。
socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName) 45, /*data extracted from group_source_req*/);
ご回答ありがとうございます。特定のソースを持たないIPv6マルチキャストでは、ソケットオプションを設定するときにGROUP_REQ構造と一致するAddMembership(別のオプションはIPv6MulticastOptionを使用する)を使用できましたが、GROUP_SOURCE_REQとAddSourceMembershipで同じことを行うだけで例外が送出されます。 – Absolom