Skip to content

Commit 3491751

Browse files
committed
Try to improve GetFreePort method
1 parent 7e6760a commit 3491751

1 file changed

Lines changed: 66 additions & 1 deletion

File tree

src/ElectronNET.API/Runtime/Helpers/PortHelper.cs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,89 @@
22
{
33
using System.Linq;
44
using System.Net.NetworkInformation;
5+
using System.Collections.Generic;
6+
using System.Net;
7+
using System.Net.Sockets;
58

69
internal static class PortHelper
710
{
811
public static int GetFreePort(int? defaultPost)
912
{
1013
var listeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().Select(e => e.Port).ToList();
14+
var localAddresses = GetLocalAddresses();
1115

1216
int port = defaultPost ?? 8000;
1317

1418
while (true)
1519
{
16-
if (!listeners.Contains(port))
20+
if (!listeners.Contains(port) && TryBindPort(port, localAddresses))
1721
{
1822
return port;
1923
}
2024

2125
port += 2;
2226
}
2327
}
28+
29+
private static HashSet<IPAddress> GetLocalAddresses()
30+
{
31+
var addresses = new HashSet<IPAddress>
32+
{
33+
IPAddress.Any,
34+
IPAddress.IPv6Any,
35+
IPAddress.Loopback,
36+
IPAddress.IPv6Loopback
37+
};
38+
39+
try
40+
{
41+
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
42+
43+
foreach (var networkInterface in networkInterfaces)
44+
{
45+
if (networkInterface.OperationalStatus != OperationalStatus.Up)
46+
{
47+
continue;
48+
}
49+
50+
var ipProperties = networkInterface.GetIPProperties();
51+
52+
foreach (var unicastAddress in ipProperties.UnicastAddresses)
53+
{
54+
addresses.Add(unicastAddress.Address);
55+
}
56+
}
57+
}
58+
catch
59+
{
60+
// ignored
61+
}
62+
63+
return addresses;
64+
}
65+
66+
private static bool TryBindPort(int port, HashSet<IPAddress> addresses)
67+
{
68+
TcpListener listener = null;
69+
70+
foreach (var address in addresses)
71+
{
72+
try
73+
{
74+
listener = new TcpListener(address, port);
75+
listener.Start();
76+
}
77+
catch
78+
{
79+
return false;
80+
}
81+
finally
82+
{
83+
listener?.Stop();
84+
}
85+
}
86+
87+
return true;
88+
}
2489
}
2590
}

0 commit comments

Comments
 (0)