我写了一个简单的程序,通过监听指定端口使端口范围开放。我发现,在Windows和Linux上,这个程序打开从端口1到65535的所有端口所需的时间不同。
在Linux上,打开所有端口大约需要2秒钟。在Windows上,这个过程接近半个小时(我没有测量确切的分钟数,因为我从来没有等待它完成)。
Windows在这方面是否明显较慢,如果是,原因是什么,我能做些什么来加快运行速度吗?
请注意,尽管测试运行在非常不同的硬件上,但鉴于计时的数量级差异,这可能并不重要。
在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无关。如果我们按照此处或此处所述的方法捕获诊断跟踪,我们将看到如下内容:
这告诉我们winsock listen调用需要大约400毫秒的时间。有什么想法吗?
这个问题描述了类似的问题,有些人可以重现,而有些人则不能。我猜测这可能取决于Windows/SP版本。我正在运行Windows 10。很久以前,半开放连接存在速率限制问题,这给许多人带来了烦恼,因为他们无法有效地运行他们的torrent。尽管它看起来与旧问题无关,但这可能是由类似的原因引起的。
更新2 - 在Windows 7机器上测试,速度非常快(与Linux时间相当)。显然从那时起有些变化?
listener.Start();
上。这告诉你什么? - Andrew Savinykh