我在C#中创建了一个端口扫描程序,但我似乎无法让它更快:
private void Scan()
{
int startPort = Convert.ToInt32(txtFrom.Text);
int endPoint = Convert.ToInt32(txtTo.Text);
progressBar1.Value = 0;
progressBar1.Maximum = endPoint - startPort + 1;
for (int currPort = startPort; currPort <= endPoint; currPort++)
{
TcpClient tcpportScan = new TcpClient();
tcpportScan.SendTimeout = 10;
try
{
tcpportScan.Connect(txtIPaddress.Text, currPort);
txtDisplay.AppendText("Port " + currPort + " open.\n");
}
catch (Exception)
{
txtDisplay.AppendText("Port " + currPort + " closed.\n");
}
progressBar1.PerformStep();
}
}
有谁知道如何加快这个过程?
答案 0 :(得分:2)
在请求被视为失败之前,创建连接会受到超时限制,这使得您的scannig变得如此之慢。使用异步代码和/或多个线程来加快速度。
答案 1 :(得分:1)
以下C#4代码将并行扫描端口,并在其中一个扫描完成时通知UI。
每次扫描都由ScanSinglePortTask方法执行,该方法启动扫描并返回字符串结果并显示消息。每个任务都以LongRunning选项开始,以通知运行时并行运行大量任务是正常的,因为每个操作都需要很长时间。
每次扫描后,在UI线程上运行的新任务将使用TaskScheduler.FromCurrentSynchronizationContext更新消息和进度条。
ToArray调用是强制枚举LINQ查询并启动任务所必需的。任务数组可以与Task.Factory.ContinueWhenAll一起使用,以在扫描完成后运行一些其他代码,例如。更新忙碌指标
private void ScanP()
{
int startPort = Convert.ToInt32(txtFrom.Text);
int endPoint = Convert.ToInt32(txtTo.Text);
progressBar1.Value = 0;
progressBar1.Maximum = endPoint - startPort + 1;
var scans = from i in Enumerable.Range(startPort,
endPoint - startPort + 1)
select ScanSinglePortTask(i)
.ContinueWith(t => Report(t.Result),
TaskScheduler.FromCurrentSynchronizationContext());
var tasks=scans.ToArray();
}
private Task<string> ScanSinglePortTask(int currPort)
{
return Task.Factory.StartNew(() =>
{
try
{
using (var tcpportScan = new TcpClient())
{
tcpportScan.SendTimeout = 10;
tcpportScan.Connect(txtIPaddress.Text, (int) currPort);
}
return "Port " + currPort + " open.\n";
}
catch (Exception)
{
return "Port " + currPort + " closed.\n";
}
}, TaskCreationOptions.LongRunning);
}
private void Report(object message)
{
txtDisplay.AppendText((string)message);
progressBar1.PerformStep();
}
答案 2 :(得分:0)
尝试使用parallel.foreach / for循环。这会快得多。
Parallel.For(0, 100, d =>
{
// Do processing here
// d is the equivalent to i in a standard for loop
});
List<int> numbers = new List<int>();
Parallel.ForEach(numbers, n =>
{
// Do Processing here
// n is the current item
});
以下是我的博客链接,其中包含更多详细信息。
http://tsells.wordpress.com/2011/03/03/using-parallel-for-and-foreach-loops-in-net-4-2/