要在史蒂夫 - 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