static void StartMulticastAcceptor() { IPAddress localIPAddr = IPAddress.Any; AsyncDatagramAcceptor acceptor = new AsyncDatagramAcceptor(); acceptor.FilterChain.AddLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Encoding.UTF8))); // Define a MulticastOption object specifying the multicast group // address and the local IPAddress. // The multicast group address is the same as the address used by the client. MulticastOption mcastOption = new MulticastOption(mcastAddress, localIPAddr); acceptor.SessionConfig.MulticastOption = mcastOption; acceptor.SessionOpened += (s, e) => { Console.WriteLine("Opened: {0}", e.Session.RemoteEndPoint); }; acceptor.MessageReceived += (s, e) => { Console.WriteLine("Received from {0}: {1}", e.Session.RemoteEndPoint, e.Message); }; acceptor.Bind(new IPEndPoint(localIPAddr, mcastPort)); Console.WriteLine("Acceptor: current multicast group is: " + mcastOption.Group); Console.WriteLine("Acceptor: current multicast local address is: " + mcastOption.LocalAddress); Console.WriteLine("Waiting for multicast packets......."); }
static void StartMulticastConnector() { IPAddress localIPAddr = IPAddress.Any; IPEndPoint mcastEP = new IPEndPoint(mcastAddress, mcastPort); AsyncDatagramConnector connector = new AsyncDatagramConnector(); connector.FilterChain.AddLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Encoding.UTF8))); // Set the local IP address used by the listener and the sender to // exchange multicast messages. connector.DefaultLocalEndPoint = new IPEndPoint(localIPAddr, 0); // Define a MulticastOption object specifying the multicast group // address and the local IP address. // The multicast group address is the same as the address used by the listener. MulticastOption mcastOption = new MulticastOption(mcastAddress, localIPAddr); connector.SessionConfig.MulticastOption = mcastOption; // Call Connect() to force binding to the local IP address, // and get the associated multicast session. IoSession session = connector.Connect(mcastEP).Await().Session; // Send multicast packets to the multicast endpoint. session.Write("hello 1", mcastEP); session.Write("hello 2", mcastEP); session.Write("hello 3", mcastEP); }
/// <summary> /// Constructor for UDP channels. /// </summary> /// <param name="localInfo"> The local endpoint to which you bind the UDP connection. /// <param name="remoteInfo"> A struct with the host name and the port number /// of the remote host /// </param> /// <exception cref="System.IO.IOException"> if an error occurs /// </exception> public MulticastMessageChannel(ConnectionInfo multicastInfo) { try { // Create the Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // Set the reuse address option udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); // Create an IPEndPoint and bind to it IPEndPoint bindaddrs = new IPEndPoint(IPAddress.Any, multicastInfo.Port); udpSocket.Bind(bindaddrs); // Define a MulticastOption object specifying the multicast group // address and the local IPAddress. // The multicast group address is the same as the address used by the server. System.Net.IPAddress ipAddress = IPAddress.Parse(multicastInfo.Addr); MulticastOption mcastOption = new MulticastOption(ipAddress, IPAddress.Any); // IP multicast loopback. udpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, 1); // Add membership in the multicast group //BIG NOTE: If you have an exception at this point and your computer is disconnected // using Windows, the problem is due to a lack of a loopback interface. // You need to install a loopback interface Adapter. // The Microsoft Loopback adapter is a tool for testing in a // virtual network environment where access to a network is not feasible. // Click Start, point to Settings, click Control Panel, and then double-click Add/Remove Hardware. // You will find it in the Manufacturers section, Microsoft. udpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ipAddress, IPAddress.Any)); // Set the Time to Live udpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2); udpMulticastAddress = new IPEndPoint(ipAddress, multicastInfo.Port); udpSocket.Connect(udpMulticastAddress); } catch (SocketException e) { if (log.IsErrorEnabled) log.Error("SocketException caught!. Message : " + e.Message); throw e; } catch (Exception e) { if (log.IsErrorEnabled) log.Error("Exception caught!. Message : " + e.Message); throw e; } if (log.IsDebugEnabled) log.Debug("Connected Multicast, own channel local point: " + udpSocket.LocalEndPoint + " Multicast Address " + udpSocket.RemoteEndPoint); }
public Task SendAsync(string data) { return Task.Factory.StartNew(() => { IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName()); foreach(var ipAddress in localIPs.Where(a => a.AddressFamily == AddressFamily.InterNetwork)) { var mcastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); mcastSocket.Bind(new IPEndPoint(ipAddress, 0)); var mcastOption = new MulticastOption(MulticastAdress); mcastSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption); var endPoint = new IPEndPoint(MulticastAdress, Port); mcastSocket.SendTo(Encoding.ASCII.GetBytes(data), endPoint); } }); }
[Test] // .ctor (IPAddress) public void Constructor1 () { MulticastOption option; IPAddress group; group = IPAddress.Parse ("239.255.255.250"); option = new MulticastOption (group); Assert.AreSame (group, option.Group, "#A:Group"); Assert.AreEqual (0, option.InterfaceIndex, "#A:InterfaceIndex"); Assert.AreEqual (IPAddress.Any, option.LocalAddress, "#A:LocalAddress"); group = IPAddress.Parse ("ff02::1"); option = new MulticastOption (group); Assert.AreSame (group, option.Group, "#B:Group"); Assert.AreEqual (0, option.InterfaceIndex, "#B:InterfaceIndex"); Assert.AreEqual (IPAddress.Any, option.LocalAddress, "#B:LocalAddress"); }
protected virtual void CreateListeningSocket() { lock (Locker) { try { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, _port); _socket.Bind(ipEndPoint); IPAddress ipAddress = IPAddress.Parse(_ipAddress); MulticastOption multicastOption = new MulticastOption(ipAddress); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multicastOption); _endPointSender = new IPEndPoint(IPAddress.Any, 0); } catch (Exception e) { Trace.Error("Socket Creation Exception", e); } } }
public Task ReceiveAsync(Action<string> onData) { var cancellationToken = new CancellationToken(); return Task.Factory.StartNew(() => { var multicastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); EndPoint localEndpoint = new IPEndPoint(IPAddress.Any, Port); multicastSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); multicastSocket.ExclusiveAddressUse = false; multicastSocket.Bind(localEndpoint); var multicastOption = new MulticastOption(MulticastAdress); multicastSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multicastOption); var bytes = new byte[1024]; var remoteEndpoint = (EndPoint)new IPEndPoint(IPAddress.Any, 0); try { while (!cancellationToken.IsCancellationRequested) { int length = multicastSocket.ReceiveFrom(bytes, ref remoteEndpoint); onData(Encoding.ASCII.GetString(bytes, 0, length)); } multicastSocket.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } }, cancellationToken); }
[Test] // .ctor (IPAddress, IPAddress) public void Constructor2 () { MulticastOption option; IPAddress group; IPAddress mcint; group = IPAddress.Parse ("239.255.255.250"); mcint = IPAddress.Any; option = new MulticastOption (group, mcint); Assert.AreSame (group, option.Group, "#A:Group"); #if NET_2_0 Assert.AreEqual (0, option.InterfaceIndex, "#A:InterfaceIndex"); #endif Assert.AreEqual (mcint, option.LocalAddress, "#A:LocalAddress"); group = IPAddress.Parse ("ff02::1"); mcint = IPAddress.IPv6Any; option = new MulticastOption (group, mcint); Assert.AreSame (group, option.Group, "#B:Group"); #if NET_2_0 Assert.AreEqual (0, option.InterfaceIndex, "#B:InterfaceIndex"); #endif Assert.AreEqual (mcint, option.LocalAddress, "#B:LocalAddress"); }
private MulticastOption getMulticastOpt(SocketOptionName optionName) { IPMulticastRequest ipmr = new IPMulticastRequest(); int optlen = IPMulticastRequest.Size; // This can throw ObjectDisposedException. SocketError errorCode = UnsafeNclNativeMethods.OSSOCK.getsockopt( m_Handle, SocketOptionLevel.IP, optionName, out ipmr, ref optlen); GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::getMulticastOpt() UnsafeNclNativeMethods.OSSOCK.getsockopt returns errorCode:" + errorCode); // // if the native call fails we'll throw a SocketException // if (errorCode==SocketError.SocketError) { // // update our internal state after this socket error and throw // SocketException socketException = new SocketException(); UpdateStatusAfterSocketError(socketException); if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "getMulticastOpt", socketException); throw socketException; } #if BIGENDIAN ipmr.MulticastAddress = (int) (((uint) ipmr.MulticastAddress << 24) | (((uint) ipmr.MulticastAddress & 0x0000FF00) << 8) | (((uint) ipmr.MulticastAddress >> 8) & 0x0000FF00) | ((uint) ipmr.MulticastAddress >> 24)); ipmr.InterfaceAddress = (int) (((uint) ipmr.InterfaceAddress << 24) | (((uint) ipmr.InterfaceAddress & 0x0000FF00) << 8) | (((uint) ipmr.InterfaceAddress >> 8) & 0x0000FF00) | ((uint) ipmr.InterfaceAddress >> 24)); #endif // BIGENDIAN IPAddress multicastAddr = new IPAddress(ipmr.MulticastAddress); IPAddress multicastIntr = new IPAddress(ipmr.InterfaceAddress); MulticastOption multicastOption = new MulticastOption(multicastAddr, multicastIntr); return multicastOption; }
private void setMulticastOption(SocketOptionName optionName, MulticastOption MR) { IPMulticastRequest ipmr = new IPMulticastRequest(); ipmr.MulticastAddress = unchecked((int)MR.Group.m_Address); if(MR.LocalAddress != null){ ipmr.InterfaceAddress = unchecked((int)MR.LocalAddress.m_Address); } else { //this structure works w/ interfaces as well int ifIndex =IPAddress.HostToNetworkOrder(MR.InterfaceIndex); ipmr.InterfaceAddress = unchecked((int)ifIndex); } #if BIGENDIAN ipmr.MulticastAddress = (int) (((uint) ipmr.MulticastAddress << 24) | (((uint) ipmr.MulticastAddress & 0x0000FF00) << 8) | (((uint) ipmr.MulticastAddress >> 8) & 0x0000FF00) | ((uint) ipmr.MulticastAddress >> 24)); if(MR.LocalAddress != null){ ipmr.InterfaceAddress = (int) (((uint) ipmr.InterfaceAddress << 24) | (((uint) ipmr.InterfaceAddress & 0x0000FF00) << 8) | (((uint) ipmr.InterfaceAddress >> 8) & 0x0000FF00) | ((uint) ipmr.InterfaceAddress >> 24)); } #endif // BIGENDIAN GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::setMulticastOption(): optionName:" + optionName.ToString() + " MR:" + MR.ToString() + " ipmr:" + ipmr.ToString() + " IPMulticastRequest.Size:" + IPMulticastRequest.Size.ToString()); // This can throw ObjectDisposedException. SocketError errorCode = UnsafeNclNativeMethods.OSSOCK.setsockopt( m_Handle, SocketOptionLevel.IP, optionName, ref ipmr, IPMulticastRequest.Size); GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::setMulticastOption() UnsafeNclNativeMethods.OSSOCK.setsockopt returns errorCode:" + errorCode); // // if the native call fails we'll throw a SocketException // if (errorCode==SocketError.SocketError) { // // update our internal state after this socket error and throw // SocketException socketException = new SocketException(); UpdateStatusAfterSocketError(socketException); if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "setMulticastOption", socketException); throw socketException; } }
private static RegisterMessage ProcessLeaveRequest(RegisterMessage leaveRequestMessage, IPAddress senderIP) { try { lock (clientRegTable.SyncRoot) { if (clientRegTable.ContainsKey(senderIP)) { bool drop = true; clientRegTable.Remove(senderIP); ReflectorMgr.PC[ReflectorPC.ID.CurrentParticipats] = clientRegTable.Count; // Drop membership if no other member exists foreach (ClientEntry entry in clientRegTable.Values) { if (entry.GroupEP.Address.Equals(leaveRequestMessage.groupIP)) { drop = false; break; } } if (drop) { if (leaveRequestMessage.groupIP.AddressFamily == AddressFamily.InterNetwork) { MulticastOption mo = new MulticastOption(leaveRequestMessage.groupIP,ReflectorMgr.MulticastInterfaceIP); ReflectorMgr.Sockets.SockMCv4RTP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo); ReflectorMgr.Sockets.SockMCv4RTCP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo); } else { IPv6MulticastOption mo = new IPv6MulticastOption(leaveRequestMessage.groupIP); ReflectorMgr.Sockets.SockMCv6RTP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo); ReflectorMgr.Sockets.SockMCv6RTCP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo); } } return new RegisterMessage(MessageType.Confirm, leaveRequestMessage.groupIP, leaveRequestMessage.groupPort, leaveRequestMessage.confirmNumber); } else { // No entries found for the leave request return new RegisterMessage(MessageType.LeaveWithoutJoinError, IPAddress.Any); } } } catch { return new RegisterMessage(MessageType.UnknownError, IPAddress.Any); } }
private static RegisterMessage ProcessJoinRequest(RegisterMessage joinRequestMessage, IPAddress senderIP) { try { // If the senderIP already exists, remove it by following the rule - the last one wins if (clientRegTable.ContainsKey(senderIP)) { lock (clientRegTable.SyncRoot) { clientRegTable.Remove(senderIP); } } // Insert the new entry Random rnd = new Random(); int confirmNumber = rnd.Next(1, Int32.MaxValue); lock (clientRegTable.SyncRoot) { clientRegTable.Add(senderIP, new ClientEntry(senderIP, new IPEndPoint(joinRequestMessage.groupIP, joinRequestMessage.groupPort), DateTime.Now, confirmNumber, DateTime.Now)); ReflectorMgr.PC[ReflectorPC.ID.TotalParticipants]++; ReflectorMgr.PC[ReflectorPC.ID.CurrentParticipats] = clientRegTable.Count; } joinRequestMessage.msgType = MessageType.Confirm; joinRequestMessage.confirmNumber = confirmNumber; joinRequestMessage.unicastPort = ReflectorMgr.ReflectorUnicastRTPListenPort; if (joinRequestMessage.groupIP.AddressFamily == AddressFamily.InterNetwork) { MulticastOption mo = new MulticastOption(joinRequestMessage.groupIP,ReflectorMgr.MulticastInterfaceIP); ReflectorMgr.Sockets.SockMCv4RTP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo); ReflectorMgr.Sockets.SockMCv4RTCP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo); } else { IPv6MulticastOption mo = new IPv6MulticastOption(joinRequestMessage.groupIP); ReflectorMgr.Sockets.SockMCv6RTP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mo); ReflectorMgr.Sockets.SockMCv6RTCP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mo); } } catch { joinRequestMessage.msgType = MessageType.UnknownError; } return joinRequestMessage; }
// Leaves a multicast address group. public void DropMulticastGroup(IPAddress multicastAddr) { // Validate input parameters. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (multicastAddr == null) { throw new ArgumentNullException("multicastAddr"); } // IPv6 Changes: we need to create the correct MulticastOption and // must also check for address family compatibility. if (multicastAddr.AddressFamily != _family) { throw new ArgumentException(SR.Format(SR.net_protocol_invalid_multicast_family, "UDP"), "multicastAddr"); } if (_family == AddressFamily.InterNetwork) { MulticastOption mcOpt = new MulticastOption(multicastAddr); _clientSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.DropMembership, mcOpt); } else { IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr); _clientSocket.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mcOpt); } }
public void JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress) { // Validate input parameters. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (_family != AddressFamily.InterNetwork) { throw new SocketException((int)SocketError.OperationNotSupported); } MulticastOption mcOpt = new MulticastOption(multicastAddr, localAddress); _clientSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.AddMembership, mcOpt); }
public static SocketError GetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, out MulticastOption optionValue) { Interop.Winsock.IPMulticastRequest ipmr = new Interop.Winsock.IPMulticastRequest(); int optlen = Interop.Winsock.IPMulticastRequest.Size; // This can throw ObjectDisposedException. SocketError errorCode = Interop.Winsock.getsockopt( handle, SocketOptionLevel.IP, optionName, out ipmr, ref optlen); if (errorCode == SocketError.SocketError) { optionValue = default(MulticastOption); return(GetLastSocketError()); } #if BIGENDIAN ipmr.MulticastAddress = (int)(((uint)ipmr.MulticastAddress << 24) | (((uint)ipmr.MulticastAddress & 0x0000FF00) << 8) | (((uint)ipmr.MulticastAddress >> 8) & 0x0000FF00) | ((uint)ipmr.MulticastAddress >> 24)); ipmr.InterfaceAddress = (int)(((uint)ipmr.InterfaceAddress << 24) | (((uint)ipmr.InterfaceAddress & 0x0000FF00) << 8) | (((uint)ipmr.InterfaceAddress >> 8) & 0x0000FF00) | ((uint)ipmr.InterfaceAddress >> 24)); #endif // BIGENDIAN IPAddress multicastAddr = new IPAddress(ipmr.MulticastAddress); IPAddress multicastIntr = new IPAddress(ipmr.InterfaceAddress); optionValue = new MulticastOption(multicastAddr, multicastIntr); return(SocketError.Success); }
[Test] // SetSocketOption (SocketOptionLevel, SocketOptionName, Object) public void SetSocketOption3_DropMembershipIPv4_MulticastOption () { IPAddress mcast_addr = IPAddress.Parse ("239.255.255.250"); using (Socket s = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { MulticastOption option = new MulticastOption (mcast_addr); s.Bind (new IPEndPoint (IPAddress.Any, 1901)); s.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership, option); s.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DropMembership, option); } }
public static unsafe SocketError SetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, MulticastOption optionValue) { Debug.Assert(optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership); Interop.Sys.MulticastOption optName = optionName == SocketOptionName.AddMembership ? Interop.Sys.MulticastOption.MULTICAST_ADD : Interop.Sys.MulticastOption.MULTICAST_DROP; var opt = new Interop.Sys.IPv4MulticastOption { MulticastAddress = unchecked((uint)optionValue.Group.GetAddress()), LocalAddress = unchecked((uint)optionValue.LocalAddress.GetAddress()), InterfaceIndex = optionValue.InterfaceIndex }; Interop.Error err = Interop.Sys.SetIPv4MulticastOption(handle.FileDescriptor, optName, &opt); return err == Interop.Error.SUCCESS ? SocketError.Success : GetSocketErrorForErrorCode(err); }
//internal class SockInterfacePair //{ // internal UdpSocket sock; // internal IPAddress extInterface; // public bool Initialized; // internal SockInterfacePair(UdpSocket sock, IPAddress extIntf) // { // this.sock = sock; // this.extInterface = extIntf; // Initialized = false; // } //} // Apparently binding to the same ports on UDPSender and UDPListener causes problems in unicast. // Sharing the socket though, allows us to tunnel through firewalls as data is sent and received // on the same endpoint. // This region of code enables sharing sockets between the two classes. //internal static SockInterfacePair GetSharedSocket(IPEndPoint endPoint) //{ // lock (socks) // { // object sockObj = socks[endPoint]; // if (sockObj != null) // { // SockInterfacePair sip = (SockInterfacePair)sockObj; // ++sip.sock.refCount; // return sip; // } // else // { // // Create the socket // UdpSocket sock = new UdpSocket(endPoint.AddressFamily); // // Get the External Interface, save it for future use // IPAddress externalInterface = Utility.GetLocalRoutingInterface(endPoint.Address); // if (externalInterface == null) // { // // Pri3: Do something more helpful here // throw new Exception(Strings.UnableToFindLocalRoutingInterface); // } // if (Utility.IsMulticast(endPoint.Address)) // { // // Allow multiple binds to this socket, as it will still function properly // // (this is only the case if it is a multicast socket. Unicast sockets fail to // // receive all data on all sockets) // sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, -1); // // We don't join the multicast group here, because we may not want to listen // // to our own data (halfing our throughput). jasonv - 10/28/2004 // } // // Add the socket to the hashtable // SockInterfacePair sip = new SockInterfacePair(sock, externalInterface); // socks.Add(endPoint, sip); // // Increase the socket's reference count // ++sock.refCount; // return sip; // } // } //} //internal static void ReleaseSharedSocket(IPEndPoint endPoint, UdpSocket sock) //{ // object sockObj = socks[endPoint]; // if (sockObj == null) // throw new InvalidOperationException(Strings.SockDoesNotExistAsASharedSocket); // lock (socks) // { // if (--sock.refCount <= 0) // { // // Leave the multicast group // if (Utility.IsMulticast(endPoint.Address)) // { // try // { // if (endPoint.AddressFamily == AddressFamily.InterNetworkV6) // { // IPv6MulticastOption mo = new IPv6MulticastOption(endPoint.Address); // sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo); // } // else // { // MulticastOption mo = new MulticastOption(endPoint.Address); // sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo); // } // } // catch { } // The user of the socket *may* not have joined the multicast group (?) // } // // Remove ourselves from the shared pool // socks.Remove(endPoint); // // Close the socket // try // { // sock.Close(); // } // catch (ObjectDisposedException) { } // } // } //} internal static void ReleaseSocket(IPEndPoint endPoint, UdpSocket sock) { // Leave the multicast group if (Utility.IsMulticast(endPoint.Address)) { try { if (endPoint.AddressFamily == AddressFamily.InterNetworkV6) { IPv6MulticastOption mo = new IPv6MulticastOption(endPoint.Address); sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo); } else { MulticastOption mo = new MulticastOption(endPoint.Address); sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo); } } catch { } // The user of the socket *may* not have joined the multicast group (?) } // Close the socket try { sock.Close(); } catch (ObjectDisposedException) { } }
[Test] // .ctor (IPAddress, Int32) public void Constructor3 () { MulticastOption option; IPAddress group; int interfaceIndex; group = IPAddress.Parse ("239.255.255.250"); interfaceIndex = 0; option = new MulticastOption (group, interfaceIndex); Assert.AreSame (group, option.Group, "#A:Group"); Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#A:InterfaceIndex"); Assert.AreEqual (null, option.LocalAddress, "#A:LocalAddress"); group = IPAddress.Parse ("ff02::1"); interfaceIndex = 0; option = new MulticastOption (group, interfaceIndex); Assert.AreSame (group, option.Group, "#B:Group"); Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#B:InterfaceIndex"); Assert.AreEqual (null, option.LocalAddress, "#B:LocalAddress"); group = IPAddress.Parse ("239.255.255.250"); interfaceIndex = 124; option = new MulticastOption (group, interfaceIndex); Assert.AreSame (group, option.Group, "#C:Group"); Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#C:InterfaceIndex"); Assert.AreEqual (null, option.LocalAddress, "#C:LocalAddress"); group = IPAddress.Parse ("ff02::1"); interfaceIndex = 124; option = new MulticastOption (group, interfaceIndex); Assert.AreSame (group, option.Group, "#D:Group"); Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#D:InterfaceIndex"); Assert.AreEqual (null, option.LocalAddress, "#D:LocalAddress"); group = IPAddress.Parse ("239.255.255.250"); interfaceIndex = 0xFFFFFF; option = new MulticastOption (group, interfaceIndex); Assert.AreSame (group, option.Group, "#E:Group"); Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#E:InterfaceIndex"); Assert.AreEqual (null, option.LocalAddress, "#E:LocalAddress"); group = IPAddress.Parse ("ff02::1"); interfaceIndex = 0xFFFFFF; option = new MulticastOption (group, interfaceIndex); Assert.AreSame (group, option.Group, "#F:Group"); Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#F:InterfaceIndex"); Assert.AreEqual (null, option.LocalAddress, "#F:LocalAddress"); }
public void JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress) { if (this.m_CleanedUp) { throw new ObjectDisposedException(base.GetType().FullName); } if (this.m_Family != AddressFamily.InterNetwork) { throw new SocketException(SocketError.OperationNotSupported); } MulticastOption optionValue = new MulticastOption(multicastAddr, localAddress); this.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, optionValue); }
public void JoinMulticastGroup(IPAddress multicastAddr) { if (this.m_CleanedUp) { throw new ObjectDisposedException(base.GetType().FullName); } if (multicastAddr == null) { throw new ArgumentNullException("multicastAddr"); } if (multicastAddr.AddressFamily != this.m_Family) { throw new ArgumentException(SR.GetString("net_protocol_invalid_multicast_family", new object[] { "UDP" }), "multicastAddr"); } if (this.m_Family == AddressFamily.InterNetwork) { MulticastOption optionValue = new MulticastOption(multicastAddr); this.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, optionValue); } else { IPv6MulticastOption option2 = new IPv6MulticastOption(multicastAddr); this.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, option2); } }
public static unsafe SocketError SetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, MulticastOption optionValue) { int optLevel, optName; GetPlatformOptionInfo(SocketOptionLevel.IP, optionName, out optLevel, out optName); var mreqn = new Interop.libc.ip_mreqn { imr_multiaddr = new Interop.libc.in_addr { s_addr = unchecked((uint)optionValue.Group.GetAddress()) } }; if (optionValue.LocalAddress != null) { mreqn.imr_address.s_addr = unchecked((uint)optionValue.LocalAddress.GetAddress()); } else { // TODO: what is the endianness of ipv6mr_ifindex? mreqn.imr_ifindex = optionValue.InterfaceIndex; } int err = Interop.libc.setsockopt(handle.FileDescriptor, optLevel, optName, &mreqn, (uint)sizeof(Interop.libc.ip_mreqn)); return err == -1 ? GetLastSocketError() : SocketError.Success; }
public static SocketError SetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, MulticastOption optionValue) { Interop.Winsock.IPMulticastRequest ipmr = new Interop.Winsock.IPMulticastRequest(); ipmr.MulticastAddress = unchecked ((int)optionValue.Group.GetAddress()); if (optionValue.LocalAddress != null) { ipmr.InterfaceAddress = unchecked ((int)optionValue.LocalAddress.GetAddress()); } else { //this structure works w/ interfaces as well int ifIndex = IPAddress.HostToNetworkOrder(optionValue.InterfaceIndex); ipmr.InterfaceAddress = unchecked ((int)ifIndex); } #if BIGENDIAN ipmr.MulticastAddress = (int)(((uint)ipmr.MulticastAddress << 24) | (((uint)ipmr.MulticastAddress & 0x0000FF00) << 8) | (((uint)ipmr.MulticastAddress >> 8) & 0x0000FF00) | ((uint)ipmr.MulticastAddress >> 24)); if (optionValue.LocalAddress != null) { ipmr.InterfaceAddress = (int)(((uint)ipmr.InterfaceAddress << 24) | (((uint)ipmr.InterfaceAddress & 0x0000FF00) << 8) | (((uint)ipmr.InterfaceAddress >> 8) & 0x0000FF00) | ((uint)ipmr.InterfaceAddress >> 24)); } #endif // This can throw ObjectDisposedException. SocketError errorCode = Interop.Winsock.setsockopt( handle, SocketOptionLevel.IP, optionName, ref ipmr, Interop.Winsock.IPMulticastRequest.Size); return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success); }
public static unsafe SocketError GetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, out MulticastOption optionValue) { int optLevel, optName; GetPlatformOptionInfo(SocketOptionLevel.IP, optionName, out optLevel, out optName); var mreqn = new Interop.libc.ip_mreqn(); var optLen = (uint)sizeof(Interop.libc.ip_mreqn); int err = Interop.libc.getsockopt(handle.FileDescriptor, optLevel, optName, &mreqn, &optLen); if (err == -1) { optionValue = default(MulticastOption); return GetLastSocketError(); } var multicastAddress = new IPAddress((long)mreqn.imr_multiaddr.s_addr); var multicastInterface = new IPAddress((long)mreqn.imr_address.s_addr); optionValue = new MulticastOption(multicastAddress, multicastInterface); return SocketError.Success; }
async Task NetworkRequestAsync(byte[] requestBytes, TimeSpan scanTime, int retries, int retryDelayMilliseconds, Action<string, byte[]> onResponse, System.Net.NetworkInformation.NetworkInterface adapter, CancellationToken cancellationToken) { // http://stackoverflow.com/questions/2192548/specifying-what-network-interface-an-udp-multicast-should-go-to-in-net #if !XAMARIN if (!adapter.GetIPProperties().MulticastAddresses.Any()) return; // most of VPN adapters will be skipped #endif if (!adapter.SupportsMulticast) return; // multicast is meaningless for this type of connection if (OperationalStatus.Up != adapter.OperationalStatus) return; // this adapter is off or not connected if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback) return; // strip out loopback addresses var p = adapter.GetIPProperties().GetIPv4Properties(); if (null == p) return; // IPv4 is not configured on this adapter var ipv4Address = adapter.GetIPProperties().UnicastAddresses .FirstOrDefault(ua => ua.Address.AddressFamily == AddressFamily.InterNetwork)?.Address; if (ipv4Address == null) return; // could not find an IPv4 address for this adapter var ifaceIndex = p.Index; Debug.WriteLine($"Scanning on iface {adapter.Name}, idx {ifaceIndex}, IP: {ipv4Address}"); using (var client = new UdpClient()) { for (var i = 0; i < retries; i++) { #if ANDROID var mlock = wifi.CreateMulticastLock("Zeroconf lock"); #endif try { #if ANDROID mlock.Acquire(); #endif client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(ifaceIndex)); client.ExclusiveAddressUse = false; client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, scanTime.Milliseconds); client.ExclusiveAddressUse = false; var localEp = new IPEndPoint(IPAddress.Any, 5353); Debug.WriteLine($"Attempting to bind to {localEp} on adapter {adapter.Name}"); client.Client.Bind(localEp); Debug.WriteLine($"Bound to {localEp}"); var multicastAddress = IPAddress.Parse("224.0.0.251"); var multOpt = new MulticastOption(multicastAddress, ifaceIndex); client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt); Debug.WriteLine("Bound to multicast address"); // Start a receive loop var shouldCancel = false; var recTask = Task.Run(async () => { try { while (!shouldCancel) { var res = await client.ReceiveAsync() .ConfigureAwait(false); onResponse(res.RemoteEndPoint.Address.ToString(), res.Buffer); } } catch (ObjectDisposedException) { } }, cancellationToken); var broadcastEp = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353); Debug.WriteLine($"About to send on iface {adapter.Name}"); await client.SendAsync(requestBytes, requestBytes.Length, broadcastEp) .ConfigureAwait(false); Debug.WriteLine($"Sent mDNS query on iface {adapter.Name}"); // wait for responses await Task.Delay(scanTime, cancellationToken) .ConfigureAwait(false); shouldCancel = true; #if CORECLR client.Dispose(); #else client.Close(); #endif Debug.WriteLine("Done Scanning"); await recTask.ConfigureAwait(false); return; } catch (Exception e) { Debug.WriteLine($"Execption with network request, IP {ipv4Address}\n: {e}"); if (i + 1 >= retries) // last one, pass underlying out throw; } finally { #if ANDROID mlock.Release(); #endif } await Task.Delay(retryDelayMilliseconds, cancellationToken).ConfigureAwait(false); } } }
public static unsafe SocketError GetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, out MulticastOption optionValue) { Debug.Assert(optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership); Interop.Sys.MulticastOption optName = optionName == SocketOptionName.AddMembership ? Interop.Sys.MulticastOption.MULTICAST_ADD : Interop.Sys.MulticastOption.MULTICAST_DROP; Interop.Sys.IPv4MulticastOption opt; Interop.Error err = Interop.Sys.GetIPv4MulticastOption(handle.FileDescriptor, optName, &opt); if (err != Interop.Error.SUCCESS) { optionValue = default(MulticastOption); return GetSocketErrorForErrorCode(err); } var multicastAddress = new IPAddress((long)opt.MulticastAddress); var localAddress = new IPAddress((long)opt.LocalAddress); optionValue = new MulticastOption(multicastAddress, localAddress) { InterfaceIndex = opt.InterfaceIndex }; return SocketError.Success; }
public void Group () { IPAddress group; IPAddress local; MulticastOption option; local = Dns.GetHostEntry (string.Empty).AddressList [0]; group = IPAddress.Parse ("239.255.255.250"); option = new MulticastOption (group, local); group = IPAddress.Parse ("224.0.0.23"); option.Group = group; Assert.AreSame (group, option.Group, "#A1"); Assert.AreSame (local, option.LocalAddress, "#A2"); group = IPAddress.Parse ("239.255.255.250"); option.Group = group; Assert.AreSame (group, option.Group, "#B1"); Assert.AreSame (local, option.LocalAddress, "#B2"); group = IPAddress.Parse ("ff02::1"); option.Group = group; Assert.AreSame (group, option.Group, "#C1"); Assert.AreSame (local, option.LocalAddress, "#C2"); option.Group = null; Assert.IsNull (option.Group, "#D1"); Assert.AreSame (local, option.LocalAddress, "#D2"); option = new MulticastOption (group, 5); group = IPAddress.Parse ("224.0.0.23"); option.Group = group; Assert.AreSame (group, option.Group, "#E1"); Assert.AreEqual (5, option.InterfaceIndex, "#E2"); Assert.IsNull (option.LocalAddress, "#E3"); }
private void SetMulticastOption(SocketOptionName optionName, MulticastOption MR) { SocketError errorCode = SocketPal.SetMulticastOption(_handle, optionName, MR); GlobalLog.Print("Socket#" + Logging.HashString(this) + "::setMulticastOption() Interop.Winsock.setsockopt returns errorCode:" + errorCode); // Throw an appropriate SocketException if the native call fails. if (errorCode != SocketError.Success) { // Update the internal state of this socket according to the error before throwing. SocketException socketException = new SocketException((int)errorCode); UpdateStatusAfterSocketError(socketException); if (s_loggingEnabled) { Logging.Exception(Logging.Sockets, this, "setMulticastOption", socketException); } throw socketException; } }
public void InterfaceIndex () { IPAddress group; IPAddress local; MulticastOption option; group = IPAddress.Parse ("239.255.255.250"); option = new MulticastOption (group, 10); option.InterfaceIndex = 0; Assert.AreSame (group, option.Group, "#A1"); Assert.AreEqual (0, option.InterfaceIndex, "#A2"); Assert.IsNull (option.LocalAddress, "#A3"); option.InterfaceIndex = 124; Assert.AreSame (group, option.Group, "#B1"); Assert.AreEqual (124, option.InterfaceIndex, "#B2"); Assert.IsNull (option.LocalAddress, "#B3"); option.InterfaceIndex = 0xFFFFFF; Assert.AreSame (group, option.Group, "#C1"); Assert.AreEqual (0xFFFFFF, option.InterfaceIndex, "#C2"); Assert.IsNull (option.LocalAddress, "#C3"); local = Dns.GetHostEntry (string.Empty).AddressList [0]; option = new MulticastOption (group, local); option.InterfaceIndex = 10; Assert.AreSame (group, option.Group, "#D1"); Assert.AreEqual (10, option.InterfaceIndex, "#D2"); Assert.IsNull (option.LocalAddress, "#D3"); }
public void InterfaceIndex_Value_OutOfRange () { IPAddress group = IPAddress.Parse ("239.255.255.250"); MulticastOption option = new MulticastOption (group, 10); try { option.InterfaceIndex = -1; Assert.Fail ("#A1"); } catch (ArgumentOutOfRangeException ex) { // Specified argument was out of the range of valid values Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2"); Assert.IsNull (ex.InnerException, "#A3"); Assert.IsNotNull (ex.Message, "#A4"); Assert.AreEqual ("value", ex.ParamName, "#A5"); } try { option.InterfaceIndex = 0x1000000; Assert.Fail ("#B1"); } catch (ArgumentOutOfRangeException ex) { // Specified argument was out of the range of valid values Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#B2"); Assert.IsNull (ex.InnerException, "#B3"); Assert.IsNotNull (ex.Message, "#B4"); Assert.AreEqual ("value", ex.ParamName, "#B5"); } // ensure original value was retained Assert.AreEqual (10, option.InterfaceIndex, "#C"); }
public void LocalAddress () { IPAddress group; IPAddress local; MulticastOption option; local = Dns.GetHostEntry (string.Empty).AddressList [0]; group = IPAddress.Parse ("239.255.255.250"); option = new MulticastOption (group, local); local = IPAddress.Loopback; option.LocalAddress = local; Assert.AreSame (group, option.Group, "#A1"); Assert.AreEqual (0, option.InterfaceIndex, "#A2"); Assert.AreSame (local, option.LocalAddress, "#A3"); local = Dns.GetHostEntry (string.Empty).AddressList [0]; option.LocalAddress = local; Assert.AreSame (group, option.Group, "#B1"); Assert.AreEqual (0, option.InterfaceIndex, "#B2"); Assert.AreSame (local, option.LocalAddress, "#B3"); option.LocalAddress = null; Assert.AreSame (group, option.Group, "#C1"); Assert.AreEqual (0, option.InterfaceIndex, "#C2"); Assert.IsNull (option.LocalAddress, "#C3"); option = new MulticastOption (group, 5); local = IPAddress.Loopback; option.LocalAddress = local; Assert.AreSame (group, option.Group, "#D1"); Assert.AreEqual (0, option.InterfaceIndex, "#D2"); Assert.AreSame (local, option.LocalAddress, "#D3"); }
internal static void ReleaseSharedSocket(IPEndPoint endPoint, LstSocks.Socket sock) { object sockObj = socks[endPoint]; if( sockObj == null ) throw new InvalidOperationException("Sock does not exist as a shared socket."); lock(socks) { if( --sock.refCount <= 0 ) { // Leave the multicast group if( Utility.IsMulticast(endPoint.Address) ) { try { if (endPoint.AddressFamily == AddressFamily.InterNetworkV6) { IPv6MulticastOption mo = new IPv6MulticastOption(endPoint.Address); sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo); } else { MulticastOption mo = new MulticastOption(endPoint.Address); sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo); } } catch {} // The user of the socket *may* not have joined the multicast group (?) } // Remove ourselves from the shared pool socks.Remove(endPoint); // Close the socket try { sock.Close(); } catch(ObjectDisposedException) {} } } }
public static SocketError SetMulticastOption(SafeSocketHandle handle, SocketOptionName optionName, MulticastOption optionValue) { Interop.Winsock.IPMulticastRequest ipmr = default; #pragma warning disable CS0618 // Address is marked obsolete ipmr.MulticastAddress = unchecked ((int)optionValue.Group.Address); #pragma warning restore CS0618 if (optionValue.LocalAddress != null) { #pragma warning disable CS0618 // Address is marked obsolete ipmr.InterfaceAddress = unchecked ((int)optionValue.LocalAddress.Address); #pragma warning restore CS0618 } else { //this structure works w/ interfaces as well int ifIndex = IPAddress.HostToNetworkOrder(optionValue.InterfaceIndex); ipmr.InterfaceAddress = unchecked ((int)ifIndex); } #if BIGENDIAN ipmr.MulticastAddress = BinaryPrimitives.ReverseEndianness(ipmr.MulticastAddress); if (optionValue.LocalAddress != null) { ipmr.InterfaceAddress = BinaryPrimitives.ReverseEndianness(ipmr.InterfaceAddress); } #endif // This can throw ObjectDisposedException. SocketError errorCode = Interop.Winsock.setsockopt( handle, SocketOptionLevel.IP, optionName, ref ipmr, Interop.Winsock.IPMulticastRequest.Size); return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success); }