스티브 - 오의 대답에 후속하기 위해서는 C 번호도 시스템의 경우에서 IPv6에 소스 필터링을 수행하는 것은 여전히 가능하다. Net.Sockets.SocketOptionName 열거는 숫자를 직접 형변환하여 필수 옵션을 정의하지 않습니다.
(SocketOptionName) 45; //MCAST_JOIN_SOURCE_GROUP
소켓의 SetSocketOption 함수는 옵션을 인식하지 못하는 경우에도 호출을 "Windows 소켓"으로 이동합니다. 진정한 투쟁은 옵션과 함께 전송되어야하는 데이터 구조 자체가됩니다. 소스 필터링을 설정하려면 데이터 구조가 다음과 같아야합니다 : 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의 바이트는 이제 솔루션을 사용하여 추출 할 수
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_storage에 here 제공 및 직접 복사 : 이제
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을 사용하여 동일한 작업을 수행하면 예외가 계속 throw됩니다. – Absolom