Note that there are some explanatory texts on larger screens.

plurals
  1. POTcpListener performance issues with Start() after hundreds of ports open
    primarykey
    data
    text
    <p>Before i get started... this is NOT FOR PRODUCTION; The question really only came about while making a test application. Myself and another developer were poking around with why .net was performing this poorly this way. It may not be .net at all, it could be the OS, I hope someone can shed some light on topic:</p> <p>My test application was created to handle hundreds of connections from our production app which connects to hundreds of devices via TCP only because its easier to simulate 500-700 PCs then then have 500-700 physical machines stacked up in my office running some port software.</p> <p>I created a sample chunk that you can copy/paste into your test VS if you are interested in finding a solution. Its quite simple and easy to reproduce.</p> <p>Issues:</p> <ul> <li>As each port is opened, it takes longer and longer for the next port to open. </li> <li>The CPU is quite intense just to create one port after it has created several hundred</li> </ul> <p>Notes:</p> <ul> <li>Thread count is normal... very low (16ish threads in task manager)</li> <li>Handle count is also normal as it adds each socket.</li> <li>Memory usage also looks normal</li> <li>Used reflector to look at the .net libs to see what Start() was doing, and it looks like normal socket calls.</li> </ul> <p>Sample Code:</p> <pre><code>using System; using System.Diagnostics; using System.Net; using System.Net.Sockets; namespace SocketPerformanceTest { class Program { static void Main(string[] args) { const int socketToOpen = 500; const int socketStartingPoint = 45000; var sw = new Stopwatch(); for (var i = 0; i &lt; socketToOpen; i++) { var thisPort = socketStartingPoint + i; try { var listener = new TcpListener(IPAddress.Any, thisPort); sw.Restart(); listener.Start(); sw.Stop(); Console.WriteLine("Started Port {0} in {1}", thisPort, sw.Elapsed); } catch{} } } } } </code></pre> <p>Console Output:</p> <p>When the test application first starts, notice that each port slowly rises in execution time. The Stopwatch wraps the Start() method:</p> <pre><code>Started Port 45000 in 00:00:00.0086440 Started Port 45001 in 00:00:00.0131427 Started Port 45002 in 00:00:00.0125916 Started Port 45003 in 00:00:00.0140987 Started Port 45004 in 00:00:00.0214274 Started Port 45005 in 00:00:00.0166746 Started Port 45006 in 00:00:00.0178583 Started Port 45007 in 00:00:00.0203611 Started Port 45008 in 00:00:00.0187707 Started Port 45009 in 00:00:00.0209386 Started Port 45010 in 00:00:00.0229595 Started Port 45011 in 00:00:00.0298687 Started Port 45012 in 00:00:00.0331132 Started Port 45013 in 00:00:00.0312815 Started Port 45014 in 00:00:00.0295004 Started Port 45015 in 00:00:00.0312391 Started Port 45016 in 00:00:00.0326538 Started Port 45017 in 00:00:00.0329316 Started Port 45018 in 00:00:00.0330471 Started Port 45019 in 00:00:00.0353324 Started Port 45020 in 00:00:00.0391780 Started Port 45021 in 00:00:00.0405106 Started Port 45022 in 00:00:00.0391909 Started Port 45023 in 00:00:00.0410726 Started Port 45024 in 00:00:00.0519416 </code></pre> <p>After about 400 ports are opened, notice how long it takes for each port to start. 1-2 seconds? CPU is also quite high for this operation:</p> <pre><code>Started Port 45399 in 00:00:01.3031324 Started Port 45400 in 00:00:01.2686192 Started Port 45401 in 00:00:01.2367192 Started Port 45402 in 00:00:01.3912566 Started Port 45403 in 00:00:01.2710675 Started Port 45404 in 00:00:01.2500153 Started Port 45405 in 00:00:01.2685378 Started Port 45406 in 00:00:01.3358896 Started Port 45407 in 00:00:01.2972177 Started Port 45408 in 00:00:01.3002466 Started Port 45409 in 00:00:01.4087936 Started Port 45410 in 00:00:01.5042491 Started Port 45411 in 00:00:01.2869177 Started Port 45412 in 00:00:01.3284299 Started Port 45413 in 00:00:01.3202311 Started Port 45414 in 00:00:01.4406063 Started Port 45415 in 00:00:01.3534663 Started Port 45416 in 00:00:01.7562387 Started Port 45417 in 00:00:01.5572173 Started Port 45418 in 00:00:01.4617214 Started Port 45419 in 00:00:02.1260768 Started Port 45420 in 00:00:01.6841706 Started Port 45421 in 00:00:01.7514512 Started Port 45422 in 00:00:01.5182234 </code></pre> <p>Questions:</p> <ul> <li>Why does each port take longer to open then the last? </li> <li>Why does the CPU get higher and higher </li> <li>Am I doing something wrong? Is there a more efficient way to open a socket and listen for connections?</li> <li>Is this an OS issue, or a .net issue? I tested this on windows 7, do you think it will be different if I tested it on a Server OS? I believe the kernel with 2008 R2 and Win7 SP'ed are the same, so not sure if that matters.</li> </ul> <p>Hardware:</p> <ul> <li>Win7 x64 Ultimate, 8 GB ram, I7, SSD, etc etc</li> </ul> <p>It is not critical for me to find a solution for this, but it would be nice. I would like to have this simulator app start up, and listen to 500-700 unique TCP ports in a reasonable period of time. If there is a better way, please let me know... I am very interested on what is going on or alternative options.</p> <p>Thanks!</p> <p><strong>Update 1</strong></p> <p>Tested it on a Raspberry Pi device which has hardly any CPU/Memory, and it was nearly instant. Others said it was instant in the comments.. and one said they saw the same thing. I also tested on a different PC, same issue I have. Disabled Firewall, AV, etc. I am really curious to why this is happening. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload