Created
June 29, 2021 14:25
-
-
Save antonfirsov/ef27d1048dfb362cc19b2c0165dc0d7d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
public class _ExhaustTest : IDisposable | |
{ | |
public const int ListenerCount = 1000; | |
public const int ConnectCount = 1024 * 20; | |
//public const int ConnectCount = 10; | |
private readonly ITestOutputHelper _output; | |
private Task[] _listenTasks = new Task[ListenerCount]; | |
private Socket[] _listeners = new Socket[ListenerCount]; | |
private IPEndPoint[] _listenerEndpoints = new IPEndPoint[ListenerCount]; | |
private CancellationTokenSource _cancelListen; | |
private ConcurrentBag<Socket> _handlers = new ConcurrentBag<Socket>(); | |
private ConcurrentBag<Socket> _clients = new ConcurrentBag<Socket>(); | |
private List<int> _clientPortsUsed = new List<int>(); | |
private List<int> _listenerPortsUsed = new List<int>(); | |
public _ExhaustTest(ITestOutputHelper output) | |
{ | |
_output = output; | |
_cancelListen = new CancellationTokenSource(); | |
for (int i = 0; i < _listeners.Length; i++) | |
{ | |
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); | |
listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); | |
listener.Listen(100); | |
_listenerEndpoints[i] = (IPEndPoint) listener.LocalEndPoint; | |
_listenerPortsUsed.Add(_listenerEndpoints[i].Port); | |
_listeners[i] = listener; | |
_listenTasks[i] = RunAccept(listener, _cancelListen.Token); | |
} | |
} | |
private async Task RunAccept(Socket listener, CancellationToken ct) | |
{ | |
try | |
{ | |
while (!ct.IsCancellationRequested) | |
{ | |
Socket handler = await listener.AcceptAsync(ct); | |
_handlers.Add(handler); | |
} | |
} | |
catch (OperationCanceledException) | |
{ | |
} | |
} | |
public void Dispose() | |
{ | |
_output.WriteLine("Listener ports used:"); | |
_output.WriteLine(string.Join(',', _listenerPortsUsed)); | |
_output.WriteLine("Client ports used:"); | |
_output.WriteLine(string.Join(',', _clientPortsUsed)); | |
_cancelListen.Cancel(); | |
Task.WhenAll(_listenTasks).GetAwaiter().GetResult(); | |
foreach (Socket s in _clients) | |
{ | |
s.Dispose(); | |
} | |
foreach (Socket s in _handlers) | |
{ | |
s.Dispose(); | |
} | |
foreach (Socket s in _listeners) | |
{ | |
s.Dispose(); | |
} | |
_listeners = null; | |
} | |
[Fact] | |
public async Task ExhaustAllDaPorts() | |
{ | |
for (int i = 0; i < ConnectCount; i++) | |
{ | |
//_output.WriteLine($"Connect attempt {i}..."); | |
IPEndPoint remoteEp = _listenerEndpoints[i % ListenerCount]; | |
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); | |
try | |
{ | |
await client.ConnectAsync(remoteEp); | |
//client.Connect(remoteEp); | |
//await Task.CompletedTask; | |
IPEndPoint localEp = (IPEndPoint)client.LocalEndPoint; | |
_clientPortsUsed.Add(localEp.Port); | |
} | |
catch(SocketException ex) | |
{ | |
throw new Exception($"Connect attempt {i} failed with {ex.SocketErrorCode}, {ex.Message}", ex); | |
} | |
//_output.WriteLine($"Connect attempt {i} sucesful"); | |
_clients.Add(client); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment