【问题标题】:Port scanning using threadpool使用线程池进行端口扫描
【发布时间】:2010-06-11 15:25:02
【问题描述】:

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

}

【问题讨论】:

  • @thenry 使用您评论中的代码编辑您的帖子....如果格式化有问题...问好,我相信有人会为您清理它。
  • 是的,忽略这一点,快速谷歌搜索如何格式化。编辑以便代码在我的问题中

标签: c# threadpool ports


【解决方案1】:

如果这是整个代码,那么该错误可能是由于您刚刚落到main() 的末尾而没有等待所有线程池线程完成。一旦你的主线程在通过main() 后退出,ThreadPool 线程就会全部中止。 尝试删除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 的解决方案

【讨论】:

  • 在我看来,Ben 就像一针见血。如果您这样做是为了了解有关线程的更多信息,您可能需要考虑使用 SetMaxThreads() 显式设置池中的最大线程数。 MSDN 说默认池中有 250 个线程。对于某些类型的操作,您可能会通过更多或更少的并发线程数获得更好的性能。
【解决方案2】:

什么操作系统?别忘了,不同版本的 XP 都有 tcp 连接限制,而你也可能触发了反 DDOS 保护。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2018-11-19
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多