要在史蒂夫 - O的答案跟进,它仍然是可以做到的源过滤在IPv6中在C#中,即使系统。 Net.Sockets.SocketOptionName枚举不通过直接转换数字来定义所需的选项。
(SocketOptionName) 45; //MCAST_JOIN_SOURCE_GROUP
即使该选项未被识别,套接字的函数SetSocketOption也会让调用进入“窗口套接字”。真正的斗争成为需要随选项一起发送的数据结构本身。 要设置源过滤,数据结构必须如下所示:group_source_req。前面的结构使用通常在sockaddr_in和sockaddr_in6的联合中的sockaddr_storage。要复制这种行为,我们可以定义相同的结构是这样的:
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
}
您可以通过这样做,现在创建一个sockaddr_in6的:
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的的字节现在可以通过使用该解决方案中提取提供here和直接复制到以前创建的struct 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];
}
现在,你有一个struct 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