GetRandomInt() public static method

public static GetRandomInt ( Int32 minValue, Int32 maxValue ) : Int32
minValue System.Int32
maxValue System.Int32
return System.Int32
Ejemplo n.º 1
0
            public void SampleTest()
            {
                Console.WriteLine("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
                int initRandomNumber = Crypto.GetRandomInt();

                Console.WriteLine("Random int = " + initRandomNumber + ".");
                Console.WriteLine("-----------------------------------------");
            }
Ejemplo n.º 2
0
        public static UdpClient CreateRandomUDPListener(IPAddress localAddress, int start, int end, ArrayList inUsePorts, out IPEndPoint localEndPoint)
        {
            try
            {
                UdpClient randomClient = null;
                int       attempts     = 1;

                localEndPoint = null;

                while (attempts < 50)
                {
                    int port = Crypto.GetRandomInt(start, end);
                    if (inUsePorts == null || !inUsePorts.Contains(port))
                    {
                        try
                        {
                            localEndPoint = new IPEndPoint(localAddress, port);
                            randomClient  = new UdpClient(localEndPoint);
                            break;
                        }
                        catch
                        {
                            //logger.LogWarning("Warning couldn't create UDP end point for " + localAddress + ":" + port + "." + excp.Message);
                        }

                        attempts++;
                    }
                }

                //logger.LogDebug("Attempts to create UDP end point for " + localAddress + ":" + port + " was " + attempts);

                return(randomClient);
            }
            catch
            {
                throw new ApplicationException("Unable to create a random UDP listener between " + start + " and " + end);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Attempts to create and bind a new RTP, and optionally an control (RTCP), socket(s) within a specified port range.
        /// The RTP and control sockets created are IPv4 and IPv6 dual mode sockets which means they can send and receive
        /// either IPv4 or IPv6 packets.
        /// </summary>
        /// <param name="rangeStartPort">The start of the port range that the sockets should be created within.</param>
        /// <param name="rangeEndPort">The end of the port range that the sockets should be created within.</param>
        /// <param name="startPort">A port within the range indicated by the start and end ports to attempt to
        /// bind the new socket(s) on. The main purpose of this parameter is to provide a pseudo-random way to allocate
        /// the port for a new RTP socket.</param>
        /// <param name="createControlSocket">True if a control (RTCP) socket should be created. Set to false if RTP
        /// and RTCP are being multiplexed on the same connection.</param>
        /// <param name="localAddress">Optional. If null The RTP and control sockets will be created as IPv4 and IPv6 dual mode
        /// sockets which means they can send and receive either IPv4 or IPv6 packets. If the local address is specified an attempt
        /// will be made to bind the RTP and optionally control listeners on it.</param>
        /// <param name="rtpSocket">An output parameter that will contain the allocated RTP socket.</param>
        /// <param name="controlSocket">An output parameter that will contain the allocated control (RTCP) socket.</param>
        public static void CreateRtpSocket(int rangeStartPort, int rangeEndPort, int startPort, bool createControlSocket, IPAddress localAddress, out Socket rtpSocket, out Socket controlSocket)
        {
            if (startPort == 0)
            {
                startPort = Crypto.GetRandomInt(rangeStartPort, rangeEndPort);
            }
            else if (startPort < rangeStartPort || startPort > rangeEndPort)
            {
                logger.LogWarning($"The start port of {startPort} supplied to CreateRtpSocket was outside the request range of {rangeStartPort}:{rangeEndPort}. A new valid start port will be pseudo-randomly chosen.");
                startPort = Crypto.GetRandomInt(rangeStartPort, rangeEndPort);
            }

            logger.LogDebug($"CreateRtpSocket start port {startPort}, range {rangeStartPort}:{rangeEndPort}.");

            rtpSocket     = null;
            controlSocket = null;

            bool bindSuccess = false;
            int  rtpPort     = startPort;

            // Attempt to adjust the start port for:
            // - If in use ports can be checked find the first even unused port,
            // - Otherwise if not even then set to the nearest even port.
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                // On Windows we can get a list of in use UDP ports and avoid attempting to bind to them.
                IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
                var udpListeners = ipGlobalProperties.GetActiveUdpListeners();

                var portRange  = Enumerable.Range(rangeStartPort, rangeEndPort - rangeStartPort).OrderBy(x => (x > startPort) ? x : x + rangeEndPort);
                var inUsePorts = udpListeners.Where(x => x.Port >= rangeStartPort && x.Port <= rangeEndPort).Select(x => x.Port);

                logger.LogDebug($"In use UDP ports count {inUsePorts.Count()}.");

                rtpPort = portRange.Except(inUsePorts).Where(x => x % 2 == 0).FirstOrDefault();
            }
            else
            {
                // If the start port isn't even adjust it so it is. The original RTP specification required RTP ports to be even
                // numbered and the control port to be the RTP port + 1.
                if (rtpPort % 2 != 0)
                {
                    rtpPort = (rtpPort + 1) > rangeEndPort ? rtpPort - 1 : rtpPort + 1;
                }
            }

            for (int bindAttempts = 0; bindAttempts <= MAXIMUM_RTP_PORT_BIND_ATTEMPTS; bindAttempts++)
            {
                //lock (_allocatePortsMutex)
                //{
                int controlPort = (createControlSocket == true) ? rtpPort + 1 : 0;

                try
                {
                    // The potential ports have been found now try and use them.
                    if (localAddress != null)
                    {
                        rtpSocket = new Socket(localAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
                        rtpSocket.ReceiveBufferSize = RTP_RECEIVE_BUFFER_SIZE;
                        rtpSocket.SendBufferSize    = RTP_SEND_BUFFER_SIZE;
                        rtpSocket.Bind(new IPEndPoint(localAddress, rtpPort));
                    }
                    else
                    {
                        // Create a dual mode IPv4/IPv6 socket.
                        rtpSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
                        rtpSocket.ReceiveBufferSize = RTP_RECEIVE_BUFFER_SIZE;
                        rtpSocket.SendBufferSize    = RTP_SEND_BUFFER_SIZE;
                        var bindAddress = (Socket.OSSupportsIPv6) ? IPAddress.IPv6Any : IPAddress.Any;
                        rtpSocket.Bind(new IPEndPoint(bindAddress, rtpPort));
                    }

                    if (controlPort != 0)
                    {
                        if (localAddress != null)
                        {
                            controlSocket = new Socket(localAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
                            controlSocket.Bind(new IPEndPoint(localAddress, controlPort));
                        }
                        else
                        {
                            // Create a dual mode IPv4/IPv6 socket.
                            controlSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
                            var bindAddress = (Socket.OSSupportsIPv6) ? IPAddress.IPv6Any : IPAddress.Any;
                            controlSocket.Bind(new IPEndPoint(bindAddress, controlPort));
                        }

                        logger.LogDebug($"Successfully bound RTP socket {rtpSocket.LocalEndPoint} and control socket {controlSocket.LocalEndPoint}.");
                    }
                    else
                    {
                        logger.LogDebug($"Successfully bound RTP socket {rtpSocket.LocalEndPoint}.");
                    }

                    bindSuccess = true;

                    break;
                }
                catch (SocketException sockExcp)
                {
                    if (sockExcp.SocketErrorCode != SocketError.AddressAlreadyInUse)
                    {
                        if (controlPort != 0)
                        {
                            logger.LogWarning($"Socket error {sockExcp.ErrorCode} binding to address {localAddress} and RTP port {rtpPort} and/or control port of {controlPort}, attempt {bindAttempts}.");
                        }
                        else
                        {
                            logger.LogWarning($"Socket error {sockExcp.ErrorCode} binding to address {localAddress} and RTP port {rtpPort}, attempt {bindAttempts}.");
                        }
                    }
                    else
                    {
                        logger.LogWarning($"SocketException in NetServices.CreateRtpSocket. {sockExcp}");
                    }
                }
                catch (Exception excp)
                {
                    logger.LogWarning($"Exception in NetServices.CreateRtpSocket. {excp}");
                }

                // Adjust the start port for the next attempt.
                int step = Crypto.GetRandomInt(RTP_STEP_MIN, RTP_STEM_MAX);
                step    = (step % 2 == 0) ? step : step + 1;
                rtpPort = (rtpPort + step + 1) > rangeEndPort ? rangeStartPort + step : rtpPort + step;
                //}
            }

            if (!bindSuccess)
            {
                throw new ApplicationException($"RTP socket allocation failure range {rangeStartPort}:{rangeEndPort}.");
            }
        }