我写了一个简单的程序,通过监听指定的端口来打开一个端口范围。我注意到,此程序在 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 时间相比)。显然从那以后发生了一些变化?
最佳答案
所以,是的。坏司机。
没有延迟和有大延迟的电脑之间的区别在于,没有延迟的电脑没有安装很多垃圾。
下载一个允许查看已安装驱动程序的工具,并尝试猜测哪些驱动程序导致速度下降。您可以使用 Autoruns来自 sysinternals 套件(请参阅驱动程序选项卡)或 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。还有很多其他软件供应商可供选择;)
关于c# - 在 Windows 中监听端口是否比在 Linux 中慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36687050/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub