我编写了一个简单的程序,通过监听指定的端口来打开端口范围。我注意到,在Windows和Linux上使用不同的时间来打开从端口1到端口65535的所有端口。
在Linux上打开所有端口大约需要2秒钟。在Windows上,它接近半小时(我没有测量确切的分钟数,因为我从未等待它完成)。
Windows在这方面是否客观上较慢,如果是,为什么我可以做任何事情以使其运行更快?
请注意,尽管测试是在非常不同的硬件上运行的,但考虑到时序的数量级不同,它可能并不重要。
// 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);
}
}
}
更新1 ,所以这显然与.net无关。如果我们按照here或here描述捕获诊断跟踪,我们将看到如下内容:
这告诉我们winsock listen调用接近400毫秒。知道为什么吗?
This question描述了类似的问题,有些人可以重现,有些则不能。我的猜测是它取决于Windows / SP版本。我正在运行 Windows 10 。很久以前,半开连接存在速率限制问题,导致许多人感到悲伤,因为他们无法有效地运行他们的种子。这可能是由类似的东西造成的,虽然看起来这与旧的问题无关。
更新2 - 在Windows 7计算机上测试过,它的工作速度非常快(与Linux时序相当)。显然从那以后发生了一些变化?
答案 0 :(得分:1)
所以,是的。坏司机。
没有延迟的电脑和有大延迟的电脑之间的区别在于没有延迟的电脑,没有安装很多垃圾。
下载允许查看已安装驱动程序的工具,并尝试猜测哪些驱动程序正在减速。您可以使用sysinternals套件中的Autoruns(请参阅驱动程序标签)或Nirsofts DriverView或InstalledDriversList。
如果使用后者,请按组列对驱动程序列表进行排序,然后查看NDIS和/或网络。这很可能就是其中之一。
所以当我开始时,我测量了在我的机器上打开1到10000端口所需的时间。然后我逐个删除了驱动程序并再次进行了测量。结果如下:
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
注意,关闭这些程序并没有帮助。需要删除/禁用驱动程序才能看到改进。
所以没必要责怪Windows。有很多其他软件供应商可供选择;)