Created
May 11, 2012 16:34
-
-
Save epetrie/2660809 to your computer and use it in GitHub Desktop.
misc network
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Gets the next available open port for use with RTP Video Streams. Range is evenly numbered UDP ports between 9000 and 9999. | |
/// </summary> | |
/// <param name="localAddress">The local address.</param> | |
/// <returns></returns> | |
public static int GetOpenPort(IPAddress localAddress) | |
{ | |
return GetOpenPort(localAddress, 9000, 9999, 2, true, true); | |
} | |
/// <summary> | |
/// Gets the nearest open port (or port + range). | |
/// </summary> | |
/// <param name="localAddress">The local address.</param> | |
/// <param name="startingPort">The starting port.</param> | |
/// <param name="endingPort">The ending port.</param> | |
/// <param name="range">The range.</param> | |
/// <param name="requireEvenBasePort">if set to <c>true</c> [require even base port].</param> | |
/// <param name="udp">if set to <c>true</c> [UDP].</param> | |
/// <returns></returns> | |
public static int GetOpenPort(IPAddress localAddress, int startingPort, int endingPort, int range, bool requireEvenBasePort, bool udp) | |
{ | |
// This will work fine in most cases, but there is no guarantee that a port obtained here will be open at the time that | |
// you attempt to use it. This should suffice for our purposes here, but a more robust implementation is advised for production applications. | |
// best practice here is to make sure we use the ports obtained through this method before allowing it to be called again. | |
ArgHelper.AssertThat(range >= 1); | |
ArgHelper.AssertThat(endingPort <= 65535); | |
if (requireEvenBasePort) | |
ArgHelper.AssertThat(startingPort % 2 == 0); | |
var additionalPorts = range - 1; | |
var validUsedPorts = new List<int>( | |
( | |
from endPoint in (udp ? IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners() : IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()) | |
where ((endPoint.Address == localAddress) && (endPoint.Port >= startingPort) && (endPoint.Port + additionalPorts <= endingPort)) | |
select endPoint.Port | |
)); | |
if (validUsedPorts.Count == 0) | |
return startingPort; | |
validUsedPorts.Sort(); | |
for (var i = startingPort; i <= endingPort - additionalPorts; i++) | |
{ | |
//skip odd base ports if needed. | |
if (requireEvenBasePort && i % 2 != 0) | |
continue; | |
//skip the rest if the port is in use. | |
if (validUsedPorts.Contains(i)) | |
continue; | |
//return current port if no range was defined. | |
if (additionalPorts == 0) | |
return i; | |
var isUsed = false; | |
//test to see if the requested range is available | |
for (var j = i + 1; j <= i + additionalPorts; j++) | |
{ | |
if (!validUsedPorts.Contains(j)) | |
continue; | |
isUsed = true; | |
i = j; | |
} | |
if (isUsed) | |
continue; | |
return i; | |
} | |
return 0; //socket creation with port 0 will find any port available outside our range. | |
} | |
/// <summary> | |
/// Gets the local ip that the system will use for a connection to the specified remote IP Address. | |
/// | |
/// Use this to automate RTP Sendback Url definition. | |
/// </summary> | |
/// <param name="remoteIpAddress">The remote ip address.</param> | |
/// <returns></returns> | |
public static IPAddress GetLocalIpAddressUsedFor(IPAddress remoteIpAddress) | |
{ | |
using (var udpClient = new UdpClient()) | |
{ | |
udpClient.Connect(remoteIpAddress, 1); | |
return ((IPEndPoint)udpClient.Client.LocalEndPoint).Address; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment