예제 #1
0
        /// <summary>
        /// Instantiates a UDP Broadcast client
        /// </summary>
        /// <param name="address">The IPAddress which the socket should be bound to</param>
        /// <param name="port">The port used by the endpoint that should different than 0 on a Subscriber context</param>
        /// <param name="pubSubContext">The context in which the UDP client is to be used </param>
        public UdpClientBroadcast(IPAddress address, int port, UsedInContext pubSubContext)
        {
            Address       = address;
            Port          = port;
            PubSubContext = pubSubContext;

            CustomizeSocketToBroadcastThroughIf();

            IPEndPoint boundEndpoint = null;

            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || pubSubContext == UsedInContext.Publisher)
            {
                //Running on Windows or Publisher on Windows/Linux
                boundEndpoint = new IPEndPoint(address, port);
            }
            else
            {
                //Running on Linux and Subscriber
                // On Linux must bind to IPAddress.Any on receiving side to get Broadcast messages
                boundEndpoint = new IPEndPoint(IPAddress.Any, port);
            }

            Client.Bind(boundEndpoint);
            EnableBroadcast = true;

            Utils.Trace("UdpClientBroadcast was created for address: {0}:{1} - {2}.", address, port, pubSubContext);
        }
예제 #2
0
        /// <summary>
        /// Create specific <see cref="UdpClient"/> for specified <see cref="NetworkInterface"/> and <see cref="IPEndPoint"/>.
        /// </summary>
        /// <param name="pubSubContext">Is the method called in a publisher context or a subscriber context</param>
        /// <param name="networkInterface"></param>
        /// <param name="configuredEndpoint"></param>
        /// <returns></returns>
        private static UdpClient CreateUdpClientForNetworkInterface(UsedInContext pubSubContext, NetworkInterface networkInterface, IPEndPoint configuredEndpoint)
        {
            UdpClient             udpClient    = null;
            IPInterfaceProperties ipProps      = networkInterface.GetIPProperties();
            IPAddress             localAddress = IPAddress.Any;

            foreach (var address in ipProps.UnicastAddresses)
            {
                if (address.Address.AddressFamily == AddressFamily.InterNetwork)
                {
                    localAddress = address.Address;
                }
            }

            try
            {
                //detect the port used for binding
                int port = 0;
                if (pubSubContext == UsedInContext.Subscriber)
                {
                    port = configuredEndpoint.Port;
                }
                if (IsIPv4MulticastAddress(configuredEndpoint.Address))
                {
                    //instantiate multi-cast UdpClient
                    udpClient = new UdpClientMulticast(localAddress, configuredEndpoint.Address, port);
                }
                else if (IsIPv4BroadcastAddress(configuredEndpoint.Address, networkInterface))
                {
                    //instantiate broadcast UdpClient depending on publisher/subscriber usage context
                    udpClient = new UdpClientBroadcast(localAddress, port, pubSubContext);
                }
                else
                {
                    //instantiate unicast UdpClient depending on publisher/subscriber usage context
                    udpClient = new UdpClientUnicast(localAddress, port);
                }
                if (pubSubContext == UsedInContext.Publisher)
                {
                    //try to send 1 byte for target IP
                    udpClient.Send(new byte[] { 0 }, 1, configuredEndpoint);
                }

                // On Windows Only since Linux does not support this
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    // Disable exceptions raised by ICMP Port Unreachable messages
                    udpClient.Client.IOControl((IOControlCode)SIO_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
                }
            }
            catch (Exception ex)
            {
                Utils.Trace(Utils.TraceMasks.Information, "Cannot use Network interface '{0}'. Exception: {1}",
                            networkInterface.Name, ex.Message);
                if (udpClient != null)
                {
                    //cleanup
                    udpClient.Dispose();
                    udpClient = null;
                }
            }

            return(udpClient);
        }
예제 #3
0
        /// <summary>
        /// Creates and returns a list of <see cref="UdpClient"/> created based on configuration options
        /// </summary>
        /// <param name="pubSubContext">Is the method called in a publisher context or a subscriber context</param>
        /// <param name="networkAddressUrl">The configuration object <see cref="NetworkAddressUrlDataType"/>.</param>
        /// <param name="configuredEndpoint">The configured <see cref="IPEndPoint"/> that will be used for data exchange.</param>
        /// <returns></returns>
        internal static List <UdpClient> GetUdpClients(UsedInContext pubSubContext, NetworkAddressUrlDataType networkAddressUrl, IPEndPoint configuredEndpoint)
        {
            StringBuilder buffer = new StringBuilder();

            buffer.AppendFormat("networkAddressUrl.NetworkInterface = {0} \n", networkAddressUrl != null ? networkAddressUrl.NetworkInterface : "null");
            buffer.AppendFormat("networkAddressUrl.Url = {0} \n", networkAddressUrl?.Url != null ? networkAddressUrl?.Url : "null");
            buffer.AppendFormat("configuredEndpoint = {0}", configuredEndpoint != null ? configuredEndpoint.ToString() : "null");

            Utils.Trace(Utils.TraceMasks.Information, buffer.ToString());

            List <UdpClient> udpClients = new List <UdpClient>();

            //validate input parameters
            if (networkAddressUrl == null || configuredEndpoint == null)
            {
                //log warning?
                return(udpClients);
            }
            //detect the list on network interfaces that will be used for creating the UdpClient s
            List <NetworkInterface> usableNetworkInterfaces = new List <NetworkInterface>();
            var interfaces = NetworkInterface.GetAllNetworkInterfaces();

            if (string.IsNullOrEmpty(networkAddressUrl.NetworkInterface))
            {
                Utils.Trace(Utils.TraceMasks.Information, "No NetworkInterface name was provided. Use all available NICs.");
                usableNetworkInterfaces.AddRange(interfaces);
            }
            else
            {
                //the configuration contains a NetworkInterface name, try to locate it
                foreach (NetworkInterface nic in interfaces)
                {
                    if (nic.Name.Equals(networkAddressUrl.NetworkInterface, StringComparison.OrdinalIgnoreCase))
                    {
                        usableNetworkInterfaces.Add(nic);
                    }
                }
                if (usableNetworkInterfaces.Count == 0)
                {
                    Utils.Trace(Utils.TraceMasks.Information, "The configured value for NetworkInterface name('{0}') could not be used.", networkAddressUrl.NetworkInterface);
                    usableNetworkInterfaces.AddRange(interfaces);
                }
            }

            foreach (NetworkInterface nic in usableNetworkInterfaces)
            {
                Utils.Trace(Utils.TraceMasks.Information, "NetworkInterface name('{0}') attempts to create instance of UdpClient.", nic.Name);
                //ignore loop-back interface
                if (nic.NetworkInterfaceType == NetworkInterfaceType.Loopback)
                {
                    continue;
                }
                //ignore tunnel interface
                if (nic.NetworkInterfaceType == NetworkInterfaceType.Tunnel)
                {
                    continue;
                }
                UdpClient udpClient = CreateUdpClientForNetworkInterface(pubSubContext, nic, configuredEndpoint);
                if (udpClient == null)
                {
                    continue;
                }
                //store UdpClient
                udpClients.Add(udpClient);
                Utils.Trace(Utils.TraceMasks.Information, "NetworkInterface name('{0}') UdpClient successfully created.", nic.Name);
            }
            return(udpClients);
        }