使用线程池的端口扫描
我想运行一个小应用程序,扫描端口并检查它们是否打开使用并使用线程池实践。控制台窗口会询问一个数字并扫描从1到X的端口,并显示每个端口是否打开或关闭。我的问题是,当它通过每个端口时,它有时会过早停止。它不止于一个数字,它非常随意。例如,它指定200.控制台将滚动通过每个端口,然后停在110.下一次我运行它,它停在80.使用线程池的端口扫描
代码 遗漏了一些事情,假设所有变量声明在哪里他们应该。第一部分在Main。
static void Main(string[] args)
{
string portNum;
int convertedNum;
Console.WriteLine("Scanning ports 1-X");
portNum = Console.ReadLine();
convertedNum = Convert.ToInt32(portNum);
try
{
for (int i = 1; i <= convertedNum; i++)
{
ThreadPool.QueueUserWorkItem(scanPort, i);
Thread.Sleep(100);
}
}
catch (Exception e)
{
Console.WriteLine("exception " + e);
}
}
static void scanPort(object o)
{
TcpClient scanner = new TcpClient();
try
{
scanner.Connect("127.0.0.1",(int)o);
Console.WriteLine("Port {0} open", o);
}
catch
{
Console.WriteLine("Port {0} closed",o);
}
}
}
如果这是整个代码,那么该错误可能是由您刚刚经历到的main()
末下降所致,而无需等待所有线程池中的线程来完成。 ThreadPool
线程会在您的主线程在通过main()
后退出时全部中止。 尝试删除Thread.Sleep(100)
(不需要,这是错误的方式,你永远不会知道睡了多久,它部分地挫败了首先使用ThreadPool
的目的),你甚至可能不会检查一个单一的端口!
相反,您可以让每个工作线程设置一个事件并使用主要的WaitAll
来完成所有事件。一个例子见http://msdn.microsoft.com/en-us/library/3dasc8as.aspx。
编辑: 通过在链接引用该解决方案思考这上面可能比您理想的选择较少,以及(可能涉及其分配的65000个事件的数组,这将是过度)。在.net 4中,您可以使用如下所示的CountdownEvent
:
对不起,我必须运行,但请检查此示例http://msdn.microsoft.com/en-us/library/system.threading.countdownevent.aspx并让我们知道您何时还有其他问题,我确定有人可以并将详细说明或建议更好解决方案和更适合.net3的解决方案
它看起来像我本打在头上钉。如果你这样做了解更多关于线程的信息,你可能需要考虑使用SetMaxThreads()来明确地设置池中的最大线程。 MSDN表示默认值是池中的250个线程。对于某些类型的操作,使用更多或更少数量的并发线程可能会获得更好的性能。 – 2010-06-11 19:22:36
什么是操作系统?不要忘记,不同版本的XP有tcp连接限制,同时你也可能触发反DDOS保护。
此外,你的逻辑是有缺陷的。只是因为TcpClient.Connect例外,并不意味着该端口已关闭。您应该捕获并显示该异常的详细信息,因为我想它会让您更深入地了解代码停止的原因。请记住,它也可能抛出SocketException或SecurityException。
关于线程部分,您可以考虑使用任务并行库(TPL),而不是直接访问ThreadPool。它提供了一个更简单的使用和更直观/可读的语法。
告诉我们一些代码 – unbeli 2010-06-11 15:26:48
第二@unbeli。 – 2010-06-11 17:22:50
@thenry用你评论中的代码编辑你的文章....如果有格式化问题...问好,我敢肯定有人会为你清理它。 – Rusty 2010-06-11 17:41:45