C#如何获得指定机器开着的端口(修订版)

原程序在VC#中编写,本版主在C# Builder进行了改写,修改了几个BUG,调试成功!

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace Project35
{

   /// <summary>
   /// Summary description for Class.
   /// </summary>
   class ScanPort
   {
      private static string host;      //目标主机
       private static int startPort;  //开始端口
      private static int endPort;   //结束端口
       private static int timeStart;  //开始时间
       private static int timeEnd;   //结束时间
       private static int portCount;  //要扫描的端口总数
       private static int MaxThreadCount=200; //同时运行的线程最大数目
       private static ManualResetEvent ev=new ManualResetEvent(false); //父、子线程同步

      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main(string[] args)
      {
         //
         // TODO: Add code to start application here
         //

         //下面一大段完成参数检查
       //可以使用这样的命令行执行程序:
       // scanport bbs.whu.edu.cn 1 1024 -t 300
       // "-t" 参数表示同时运行的最大线程个数。也可不用此参数,默认为200。
       if((args.Length!=3)&&(args.Length!=5))
         {
            Help();
            return;
         }

       host=args[0]; 
       try
       {
            startPort=int.Parse(args[1]);
            endPort=int.Parse(args[2]);
         }
       catch(Exception)
         {
            Console.WriteLine("错误:端口应该为整数!");
            Help();
            return;
         }

       if(startPort>endPort)
         {
            Console.WriteLine("起始端口不应该大于终止端口");
            Help();
            return;
         }
         if(args.Length==5)
       {
           if(args[3]!=@"-t")
            {
               Console.WriteLine("参数格式不正确!");
               Help();
               return;
            }
      
            try
           {
           MaxThreadCount=int.Parse(args[4]);
           }
           catch(Exception )
           { 
               Console.WriteLine("错误:线程数目应该为整数!"); Help(); return;
           }
       }

    
       portCount=endPort-startPort+1;    
       Console.WriteLine("开始扫描时间: {0}",DateTime.Now);
         timeStart=Environment.TickCount;

       //设置一个定时器,每200ms检测一下,若运行线程个数太少,就增加至MaxThreadCount
       Timer timer1=new Timer(new TimerCallback(OnTimer),null,0,200);    

       //等待子线程结束
       ev.WaitOne();     
       Console.WriteLine("--扫描结束.--");
       Console.WriteLine("结束扫描时间: {0}",DateTime.Now);
       timeEnd=Environment.TickCount;
       Console.WriteLine("约用了 :{0} 秒.",(int)((timeEnd-timeStart)/1000));
       Console.WriteLine("端口扫描速率约为:{0} 端口/秒.",
         (int)(1000.0*portCount/(timeEnd-timeStart)));
         Console.ReadLine();
      }

      private static void OnTimer(object state)
       {
       lock(typeof(ScanIt))
      { 
           //如果运行的线程较少,且扫描未完成
        if((ScanIt.instanceCount<MaxThreadCount)&&(startPort<=endPort)) 
        {
           while(startPort<=endPort)
          {
            ScanIt scanIt1=new ScanIt(host,startPort,ev);
            scanIt1.DoScan();
            startPort++;
            if(ScanIt.instanceCount>=MaxThreadCount) break;              
          }       
        }
        if(startPort>endPort) ScanIt.ShouldStop=true;
      }
       }
  
      private static void Help()
       {    
       Console.WriteLine("Usage: scanport TargetHost startPort endPort");
       }

   }

   class ScanIt //此类完成对目标主机某一端口的扫描
   { 
    private string host;         //目标主机
    private int port;                  //端口
    private ManualResetEvent ev;
    private Thread thread;
    private TcpClient tcpclient;
    public static int instanceCount=0;  //同时存在的对象个数
    public static bool ShouldStop=false;

    public ScanIt(string _host,int _port,ManualResetEvent _ev) 
    { 
      host=_host; port=_port; ev=_ev; 
      thread=new Thread(new ThreadStart(target));
      lock(typeof(ScanIt)){ instanceCount++; } //同时存在的对象个数加一 
    } 
    public void DoScan() 
    { 
      thread.Start(); 
    } 
    private void target() 
    { 
      try 
      { 
        tcpclient=new TcpClient(Dns.Resolve(host).AddressList[0].ToString(),port);        
        Console.WriteLine("{0} is found!",port); 
      }
      catch(Exception){} 
      try 
      { tcpclient.Close(); 
      } 
      catch(Exception){}
      finally 
      {  lock(typeof(ScanIt)) 
        {  if((--instanceCount==0)&&(ScanIt.ShouldStop)) ev.Set(); //同时存在的对象个数减一 
        } 
        
      }
    }
   }
}
posted @ 2005-07-06 11:58  情义俩难全  阅读(558)  评论(0)    收藏  举报