Reputation: 26300
I wrote a simple program that makes a port range open by listening on the ports specified. I noticed, that it takes different time on Windows and on Linux for this program to open all ports from port 1 to port 65535.
On Linux it takes about 2 seconds opening all of the ports. On Windows it's closer to half an hour (I did not measure the exact number of minutes, because I never waited for it to finish).
Is Windows objectively slower in this regard, and if yes, why and can I do anything to make this run faster?
Note, that while tests were run on very different hardware, it probably does not matter, given that the timing differs in orders of magnitude.
// This is a very basic TCP port listener that allows you to listen on a port range
// If you run this program outside of firewall and run a port scanner inside a firewall
// pointing to the ip address where this program runs, the port scanner will be able you
// to tell which exactly ports are open on the firewall
// This code will run on Windows, but most importantly also on linux.
// DigitalOcean.com has all ports for their VMs open by default. So spin a new VM,
// copy pln.cs in your (root) home folder and then run:
// sudo apt-get update
// sudo apt-get install mono-complete -y
// mcs pln.cs
// ulimit -n 66000
// ./pln.exe 1 65535
// Now you can use the VM ip address to determine open ports on your firewall
// Note that this is a dev utility, and is aimed to be minimal - no input validation,
// no error handling. In case of a error stack trace is dumpled to console
using System;
using System.Net;
using System.Net.Sockets;
namespace PortListener
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Usage: pln.exe startPort [endPort]");
Listen(args);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex);
}
}
private static void Listen(string[] args)
{
int startPort = int.Parse(args[0]);
int endPort = int.Parse(args[1]);
Console.WriteLine("Started binding...");
for (int i = startPort; i <= endPort; i++)
{
if (i % 100 == 0 && Environment.OSVersion.Platform != PlatformID.Unix)
{
Console.WriteLine("Binding port " + i);
}
TcpListener listener = new TcpListener(IPAddress.Any, i);
try
{
listener.Start();
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
{
Console.WriteLine("Port " + i.ToString() + " already in use");
continue;
}
if (ex.SocketErrorCode == SocketError.AccessDenied)
{
Console.WriteLine("Access denied to port " + i.ToString());
continue;
}
throw;
}
listener.BeginAcceptSocket(DoAcceptSocketCallback, listener);
}
Console.WriteLine("Finished binding. Ctrl-C to stop.");
Console.ReadLine();
}
private static void DoAcceptSocketCallback(IAsyncResult ar)
{
TcpListener listener = (TcpListener) ar.AsyncState;
listener.EndAcceptSocket(ar).Close();
Console.WriteLine("Connection on port " + ((IPEndPoint) listener.LocalEndpoint).Port.ToString());
listener.BeginAcceptSocket(DoAcceptSocketCallback, listener);
}
}
}
Update 1, so this is apparently has nothing to do with .net as such. If we capture a diagnostic trace as described here or here, we will see something like this:
This tells us that winsock listen call takes in vicinity of 400 milliseconds. Any idea why?
This question describes similar problem, and some people can reproduce that and some cannot. My guess would be that it depends on Windows/SP version. I'm running Windows 10. Long time ago, there was a rate limiting issue for half-open connection, which caused many people grief, because they could not run their torrents as efficiently. This might be caused by something similar, although it does not look like this is related to that old issue.
Update 2 - tested on Windows 7 machine, and it worked very fast (comparable to linux timings). Apparently something changed since then?
Upvotes: 3
Views: 320
Reputation: 26300
So, yeah. Bad driver.
The difference between a pc where there is no delay and when there are big delays, is that the one where there is no delays, does not have a lot of crap installed.
Download a tool that allows viewing installed drivers, and try to guess which ones are causing slowdown. You can use Autoruns from sysinternals suite (see drivers tab) or Nirsofts DriverView or InstalledDriversList.
If you use the latter one, sort driver list by the group column and look at NDIS and/or network. It's most likely one of them.
So when I got started I measured how long it takes to open ports from 1 to 10000 on my machine. Then I removed drivers one by one and took measurements again. The results are below:
All Crap installed - 226 seconds
Same as above but removed Networx Traffic monitor - 9 seconds
Same as above but removed TeamViewer remote assistance - 7 seconds
Same as above but removed Checkpoint VPN client - 0 seconds
Note, just switching off these programs do not help. The drivers need to be removed/disabled to see an improvement.
So no need to blame Windows. There are a lot of other software vendors out there to choose from ;)
Upvotes: 1