diff --git a/src/Azure.Functions.Cli/Actions/HostActions/StartHostAction.cs b/src/Azure.Functions.Cli/Actions/HostActions/StartHostAction.cs index a36335740..edb2fb9ef 100644 --- a/src/Azure.Functions.Cli/Actions/HostActions/StartHostAction.cs +++ b/src/Azure.Functions.Cli/Actions/HostActions/StartHostAction.cs @@ -82,7 +82,7 @@ public override ICommandLineParserResult ParseArgs(string[] args) Parser .Setup('p', "port") .WithDescription($"Local port to listen on. Default: {DefaultPort}") - .SetDefault(hostSettings.LocalHttpPort == default(int) ? DefaultPort : hostSettings.LocalHttpPort) + .SetDefault(hostSettings.LocalHttpPort == default(int) ? NetworkHelpers.GetNextAvailablePort(DefaultPort) : hostSettings.LocalHttpPort) .Callback(p => Port = p); Parser diff --git a/src/Azure.Functions.Cli/Helpers/NetworkHelpers.cs b/src/Azure.Functions.Cli/Helpers/NetworkHelpers.cs index af0aec8c3..65abdce70 100644 --- a/src/Azure.Functions.Cli/Helpers/NetworkHelpers.cs +++ b/src/Azure.Functions.Cli/Helpers/NetworkHelpers.cs @@ -1,4 +1,8 @@ +using System; +using System.Collections.Generic; +using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; namespace Azure.Functions.Cli.Helpers @@ -33,5 +37,33 @@ public static int GetAvailablePort() listener.Stop(); } } + + public static int GetNextAvailablePort(int startPort) + { + var usedPorts = new List(); + var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); + + usedPorts.AddRange(ipGlobalProperties + .GetActiveTcpConnections() + .Where(c => c.LocalEndPoint.Port >= startPort) + .Select(c => c.LocalEndPoint.Port)); + usedPorts.AddRange(ipGlobalProperties + .GetActiveTcpListeners() + .Where(l => l.Port >= startPort) + .Select(l => l.Port)); + + usedPorts.Sort(); + + foreach (var usedPort in usedPorts) + { + if (startPort < usedPort) + { + return startPort; + } + startPort++; + } + + return GetAvailablePort(); + } } } \ No newline at end of file