Skip to content

Instantly share code, notes, and snippets.

@antonfirsov
Created June 29, 2021 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antonfirsov/ef27d1048dfb362cc19b2c0165dc0d7d to your computer and use it in GitHub Desktop.
Save antonfirsov/ef27d1048dfb362cc19b2c0165dc0d7d to your computer and use it in GitHub Desktop.
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