使用线程池进行端口扫描

时间:2010-06-11 15:25:03

标签: c# threadpool ports

我正在尝试运行一个小应用程序来扫描端口并检查它们是否打开使用和练习线程池。控制台窗口将询问一个号码并扫描从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);
        }
    }

}

3 个答案:

答案 0 :(得分:3)

如果这是整个代码,那么错误可能是由于您只是在main()结束而没有等待所有线程池线程完成而导致的。一旦主线程在通过ThreadPool后退出,main()个线程全部中止。 尝试删除Thread.Sleep(100)(这是不需要的,这是错误的方式,你永远不知道睡了多长时间,它首先部分地违背了使用ThreadPool的目的)你可能甚至不会检查一个端口!

相反,您可以让每个工作线程设置一个事件,并在main中使用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的解决方案和解决方案

答案 1 :(得分:0)

什么操作系统?不要忘记,不同版本的XP具有tcp连接限制,同时您也可能触发反DDOS保护。

另外,你的逻辑是有缺陷的。仅仅因为TcpClient.Connect除外,并不意味着端口已关闭。您应该捕获并显示该异常的详细信息,因为我想它可以让您更深入地了解代码停止的原因。请记住,它也可能抛出SocketException或SecurityException。

答案 2 :(得分:0)

关于线程部分,您可以考虑使用任务并行库(TPL)而不是直接访问ThreadPool。 恕我直言,它提供了更简单的使用和更直观/可读的语法。