【发布时间】:2014-07-25 15:44:17
【问题描述】:
所以我正在尝试扫描具有给定 IP 地址的开放端口。 我找到了一些例子,但如果我给出 65535 个任务,我会得到一个内存不足的异常。 我虽然嗯,也许是太多了。所以我尝试了2000 ..还是很多。一个1000?是的。
但显然问题在于“TaskCreationOptions.LongRunning”。如果我尝试 TaskCreationOptions.None 是做everyhting 但真的很慢!!像我奶奶一样可以更快地扫描端口。
有趣的是,如果我调试(F5 - Visual Studio),那么它可以工作,但如果我在不调试的情况下执行程序,它就不会。 所以我可以在几秒钟内扫描 1000 个端口,但是如何实现队列呢?
这是我的代码。 我尝试循环,在完成时执行等等。什么都没有:(
如有任何帮助,请提前致谢!
private void ScanPorts()
{
int startPort = 1000;
int endPoint = 65535;
myProgressBar.Value = 0;
myProgressBar.Step = 1;
myProgressBar.Maximum = endPoint - startPort + 1;
var scans = from i in Enumerable.Range(startPort, endPoint - startPort + 1)
select ScanSinglePortTask(i).ContinueWith(t => Response(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("127.0.0.1", (int)currPort);
}
return "IP: 127.0.0.1 - Port " + currPort + " open.\n";
}
catch (Exception)
{
return "IP: 127.0.0.1 - Port " + currPort + " closed.\n";
}
}, TaskCreationOptions.LongRunning);
}
private void Response(object message)
{
lblProgress.Text = ((string)message);
listBox1.Items.Add(((string)message));
listBox1.SelectedIndex = listBox1.Items.Count - 1;
myProgressBar.PerformStep();
}
编辑
临时解决方案
所以我设法通过将我的平台目标从 x86 设置为 x64 来消除内存不足异常。
所以显然 x86 有 2Gigs 虚拟内存,而 x64 超过 6TB+ 虚拟内存。
如果你问我,这不是解决方案,而是临时解决方案。
新解决方案
x86 和 x64 位兼容!
我实施的排队系统,这篇文章没有答案,所以我想我会分享我的解决方案给有需要的人。
所以基本上这段代码会扫描任何给定 IP 地址的所有端口(同时 1000 个端口,所以 1000 个线程) 我可以在 2 分钟内扫描一个本地 ip,一个更长的互联网 IP,也许 5。当然取决于你的 cpu 速度和互联网连接。
我为你们添加了一些 cmets :)
(请不要将其用于黑客目的xD 如果您喜欢,请投票)
public partial class PortScanner : Form
{
private int totalScans = 0;
private IPAddress ipAddress;
public PortScanner()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
//Check for valid IP
if (IPAddress.TryParse(txtIP.Text, out ipAddress))
{
btnScan.Enabled = false;
btnScan.Text = "Scanning...";
//Stops GUI Freeze
MethodInvoker startScanning = new MethodInvoker(ScanPorts);
startScanning.BeginInvoke(null, null);
}
else
{
MessageBox.Show("Invalid IP");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void ScanPorts()
{
int startPort = 1;
int endPoint = 65535;
// n ports to scan!
int maxTheads = 1000;
//Set progressbar
myProgressBar.Value = 0;
myProgressBar.Step = 1;
myProgressBar.Maximum = endPoint - startPort + 1;
//Main task list (consist of multiple lists of 1000 tasks)
List<List<Task>> myTasks = new List<List<Task>>();
for (int i = startPort; i <= endPoint; i = i + maxTheads)
{
List<Task> subTasks = new List<Task>();
for (int j = i; j < i + maxTheads && j <= endPoint; j++)
{
subTasks.Add(ScanSinglePortTask(j));
}
myTasks.Add(subTasks);
}
//Start ALL TASKS
startTask(myTasks);
}
public void startTask(List<List<Task>> myTasks)
{
//A thousand task at a time.
foreach (List<Task> t in myTasks)
{
foreach (Task st in t)
{
st.Start();
}
Task.WaitAll(t.ToArray());
}
btnScan.Enabled = true;
btnScan.Text = "Start Scanning";
}
private Task ScanSinglePortTask(int currPort)
{
return new Task(()=>
{
try
{
using (var tcpportScan = new TcpClient())
{
tcpportScan.SendTimeout = 10;
tcpportScan.Connect(ipAddress, (int)currPort);
}
Response("IP: " + ipAddress.ToString() + " - Port " + currPort + " open.\n");
}
catch (Exception)
{
Response("IP: " + ipAddress.ToString() + " - Port " + currPort + " closed.\n");
}
}, TaskCreationOptions.LongRunning);
}
private void Response(object message)
{
totalScans++;
if (message != null)
{
try
{
lblProgress.Text = "Total portscan: " + totalScans.ToString();
lbConnections.Items.Add(((string)message));
lbConnections.SelectedIndex = lbConnections.Items.Count - 1;
myProgressBar.PerformStep();
if (((string)message).EndsWith("open.\n"))
{
lbOpenConnections.Items.Add((string)message);
}
}
catch (Exception)
{
}
}
}
}
【问题讨论】: