为什么这个端口扫描器代码有时会错过开放端口?

时间:2012-02-04 17:45:38

标签: c# networking tcp network-programming

我正在尝试编写一个简单的连接端口扫描程序。我正在scanme.nmap.org上对前10K端口进行测试。它应该看到端口22,80和9929.如果我扫描1 - 10000它找到22和80,但是没有看到9929.如果我首先扫描9900到10000然后1-10000(如下例所示)它看到9929 ,但往往看不到端口80或22。

我知道我可以尝试通过.NET包装器使用WinPcap并进入较低级别,但是无论如何都可以使用简单的TCP连接端口扫描器在没有WinPcap的情况下可靠地工作吗?

注意:我目前分批进行100次扫描,因为如果以更大的块进行扫描,结果会更糟。

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

namespace ps
{
internal class Program
{
    private const int batchSize = 100;

    public static void Main(string[] args)
    {
        int minPort = Convert.ToInt32(args[0]);
        int maxPort = Convert.ToInt32(args[1]);

        int loops;

        if (maxPort < batchSize)
        {
            loops = 1;
        }
        else
        {
            loops = maxPort/batchSize;
        }

        // If I look for 9929 in the inital 100 - I can find it
        Parallel.For(9900, 10000, port =>
                                      {
                                          string host = "scanme.nmap.org";
                                          bool res = TryConnect(host, port, 5000);

                                          if (res)
                                          {
                                              Console.WriteLine("\nConnected: " + port + "\n");
                                          }
                                      });

        // now loop through all ports in batches
        // should see 22, 80 & 9929 but normally doesn't
        for (int i = 0; i < loops; i++)
        {
            minPort = 1 + (i*batchSize);
            if (loops != 1)
            {
                maxPort = batchSize + (i*batchSize);
            }
            Console.WriteLine("minPort:" + minPort + " maxPort:" + maxPort);
            Parallel.For(minPort, maxPort, port =>
                                               {
                                                   string host = "scanme.nmap.org";
                                                   bool res = TryConnect(host, port, 5000);

                                                   if (res)
                                                   {
                                                       Console.WriteLine("\nConnected: " + port + "\n");
                                                   }
                                               });
        }

        // Can see port 22 and 80 still?
        Parallel.For(1, 100, port =>
                                 {
                                     string host = "scanme.nmap.org";
                                     bool res = TryConnect(host, port, 5000);

                                     if (res)
                                     {
                                         Console.WriteLine("\nConnected: " + port + "\n");
                                     }
                                 });
    }


    private static bool TryConnect(string strIpAddress, int intPort, int nTimeoutMsec)
    {
        Socket socket = null;
        bool retval = false;

        try
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IAsyncResult result = socket.BeginConnect(strIpAddress, intPort, null, null);
            bool success = result.AsyncWaitHandle.WaitOne(nTimeoutMsec, true);
            retval = socket.Connected;
        }
        catch
        {
            Console.WriteLine("error: " + intPort);
            retval = false;
        }
        finally
        {
            if (null != socket)
                socket.Close();
        }
        return retval;
    }
}

}

1 个答案:

答案 0 :(得分:0)

我认为如果它没有出现,你就会有一个关于计算循环的逐个过程。

注意所有失败都是在最后一次传递中。