public async Task <TransmissionResult> SendAsync(Transmission msg, IPAddress groupIp, int port, EMulticastInterface iface, IPAddress specificIface = null, int ttl = 1) { Validate(groupIp, port); if (_sendUdpClient == null || _sendUdpClient.Client.AddressFamily != groupIp.AddressFamily) { if (_sendUdpClient != null) { _sendUdpClient.Close(); } _sendUdpClient = new UdpClient(groupIp.AddressFamily); _sendUdpClient.Client.Bind(new IPEndPoint( _sendUdpClient.Client.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, 0)); } SetSendTTL(_sendUdpClient, ttl); IPEndPoint from = _sendUdpClient.Client.LocalEndPoint as IPEndPoint; IPEndPoint to = new IPEndPoint(groupIp, port); var sendInterfaces = new List <int>(); if (iface == EMulticastInterface.All) { foreach (var ni in NetworkUtils.GetActiveInterfaces()) { sendInterfaces.Add(_sendUdpClient.Client.AddressFamily == AddressFamily.InterNetworkV6 ? ni.IPv6.Index : ni.IPv4.Index); } } else if (iface == EMulticastInterface.Specific) { int idx = NetworkUtils.GetBestMulticastInterfaceIndex(specificIface); if (idx == -1) { idx = 0; // fall back default to default if not found. } sendInterfaces.Add(idx); } else { sendInterfaces.Add(0); // use default interface. } foreach (var ifaceIndex in sendInterfaces) { SetSendInterface(_sendUdpClient, ifaceIndex); await _sendUdpClient.SendAsync(msg.Data, msg.Data.Length, to); } return(new TransmissionResult { From = from, To = to }); }
public void JoinASM(IPAddress groupIp, int port, EMulticastInterface iface, IPAddress specificIface = null) { Validate(groupIp, port); if (_udpClient != null) { return; // already started. } _udpClient = new UdpClient(groupIp.AddressFamily); Socket socket = _udpClient.Client; socket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true ); var bindInterface = specificIface; if (iface != EMulticastInterface.Specific) { bindInterface = (socket.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any); } socket.Bind(new IPEndPoint(bindInterface, port)); var joinInterfaces = new List <int>(); if (iface == EMulticastInterface.All) { foreach (var ni in NetworkUtils.GetActiveInterfaces()) { joinInterfaces.Add(socket.AddressFamily == AddressFamily.InterNetworkV6 ? ni.IPv6.Index : ni.IPv4.Index); } } else if (iface == EMulticastInterface.Specific) { int best = NetworkUtils.GetBestMulticastInterfaceIndex(specificIface); if (best == -1) { best = 0; } joinInterfaces.Add(best); } else if (iface == EMulticastInterface.Default) { joinInterfaces.Add(0); // 0 = default. } foreach (int ifaceIndex in joinInterfaces) { if (socket.AddressFamily == AddressFamily.InterNetwork) { MulticastOption opt = new MulticastOption( groupIp, ifaceIndex); socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, opt); } else if (socket.AddressFamily == AddressFamily.InterNetworkV6) { IPv6MulticastOption optv6 = new IPv6MulticastOption( groupIp, ifaceIndex); socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, optv6); } } StatusChanged?.Invoke(this, new UdpMulticastClientStatusEventArgs(true) { MulticastGroup = new IPEndPoint(groupIp, port), MulticastInterface = iface, SpecificInterface = specificIface } ); StartReceive(); }
public void JoinSSM(IPAddress groupIp, IPAddress sourceIp, int port, EMulticastInterface iface, IPAddress specificIface = null) { Validate(groupIp, port); if (_udpClient != null) { return; // already started. } _udpClient = new UdpClient(groupIp.AddressFamily); Socket socket = _udpClient.Client; socket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true ); var bindInterface = specificIface; if (iface != EMulticastInterface.Specific) { bindInterface = (socket.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any); } socket.Bind(new IPEndPoint(bindInterface, port)); var joinInterfaces = new List <int>(); if (iface == EMulticastInterface.All) { foreach (var ni in NetworkUtils.GetActiveInterfaces()) { joinInterfaces.Add(socket.AddressFamily == AddressFamily.InterNetworkV6 ? ni.IPv6.Index : ni.IPv4.Index); } } else if (iface == EMulticastInterface.Specific) { int best = NetworkUtils.GetBestMulticastInterfaceIndex(specificIface); if (best == -1) { best = 0; } joinInterfaces.Add(best); } else if (iface == EMulticastInterface.Default) { joinInterfaces.Add(0); // 0 = default. } foreach (int ifaceIndex in joinInterfaces) { if (socket.AddressFamily == AddressFamily.InterNetwork) { var bin = new byte[12]; Buffer.BlockCopy(groupIp.GetAddressBytes(), 0, bin, 0, 4); Buffer.BlockCopy(sourceIp.GetAddressBytes(), 0, bin, 4, 4); Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(ifaceIndex)), 0, bin, 8, 4); socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddSourceMembership, bin); } else if (socket.AddressFamily == AddressFamily.InterNetworkV6) { // fill data as in GROUP_SOURCE_REQ struct var bin = CreateGroupSourceReg(sourceIp, groupIp, ifaceIndex); socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)45, bin); } } StatusChanged?.Invoke(this, new UdpMulticastClientStatusEventArgs(true) { MulticastGroup = new IPEndPoint(groupIp, port), MulticastInterface = iface, SpecificInterface = specificIface } ); StartReceive(); }