C#如何获得指定机器开着的端口

作者:网际浪子

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

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); //父、子线程同步 

    static void Main(string[] args)
    {
        //下面一大段完成参数检查 
        //可以使用这样的命令行执行程序: 
        // 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)));
    }
    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(); //同时存在的对象个数减一
            }
        }
    }
}

Powered by DvNews.net

来源:uncj.net 阅读:169 次 日期:2003-6-30

Contributors: FHL