// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // Defines the PortService type. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.Services { using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetworkInformation; using HandBrakeWPF.Services.Interfaces; public class PortService : IPortService { private readonly object lockObject = new object(); private List usedPorts = new List(); public PortService() { } public void FreePort(int port) { lock (this.lockObject) { this.usedPorts.Remove(port); } } public int GetOpenPort(int startPort) { lock (this.lockObject) { int foundPort = FindUnusedPort(startPort); // If we find a port that's free on the system, but we've already allocated, try find another. while (this.usedPorts.Contains(foundPort)) { int nextPort = foundPort + 1; foundPort = FindUnusedPort(nextPort); } // Record we've used this port. this.usedPorts.Add(foundPort); return foundPort; } } private int FindUnusedPort(int startPort) { if (startPort == 0) { startPort = 8037; } int portStartIndex = startPort; IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties(); IPEndPoint[] tcpEndPoints = properties.GetActiveTcpListeners(); List usedPorts = tcpEndPoints.Select(p => p.Port).ToList(); int unusedPort = 0; unusedPort = Enumerable.Range(portStartIndex, 99).FirstOrDefault(p => !usedPorts.Contains(p)); return unusedPort; } } }