Quantcast
Channel: Common Language Runtime Internals and Architecture forum
Viewing all articles
Browse latest Browse all 1710

Windows tcp table not allowing to inspect all occupied ports

$
0
0
I try to build an app, monitoring application consumption of occupied dynamic ports. In order to inspect tcp table content, I use netstat and winapi's GetExtendedTcpTable, which I believe is actually used by netstat.

I noticed unobvious behaviour of tcp table. If listener side doesn't properly disposes client but client gets finalized by GC, I expect in such case connection to hang in ESTABLISHED state in tcp table, because TcpClient destructor doesn't close socket. The actual behavior is that connection disappears from tcp table but it seems like port still remains occupied, because if I continue establish more connections, after 16k connections I'll get an SocketException (10055), indicating that I'm out of free ports.

Code below reproduces this issue. Within infinite loop client-server connections are established in batches of 2k with period of 1 minute. I expect that if I start app, wait 7 minutes and call netstat or GetExtendedTcpTable I'll see 14k ESTABLISHED connections. But when I do it I actually see that this number varies in range 1-5k and never goes above. So it comes to the final problem: app crashes in about 8 minutes with exception of exhausted tcp ports though netstat nor tcp table don't show any sign of port exhaustion.

var l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
Task.Factory.StartNew(() =>
                          {
                              while (true)
                              {
                                 // accepted TcpClients are periodically finalized by GC (without freeing socket connection)
                                 l.AcceptTcpClient();
                             }
                         });

// must remember clients' references, otherwise, GC finalizes clients and since server side also finalizes accepted clients, tcp connection gets utilized
var clients = new List<TcpClient>();
while (true)
{
    for (var i = 0; i < 2000; i++)
    {
        clients.Add(new TcpClient());
        clients.Last().Connect(IPAddress.Loopback, ((IPEndPoint) l.LocalEndpoint).Port);
    }
    Task.Delay(1000).GetAwaiter().GetResult();
}


Viewing all articles
Browse latest Browse all 1710

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>