c# - 为什么这个端口扫描器代码有时会错过打开的端口?

标签 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 个为一组进行扫描,因为如果以更大的 block 进行扫描,我会得到更糟糕的结果。

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;
    }
}

最佳答案

我认为如果循环不均匀的话,你在计算循环时就差了一个。

请注意您在上一关中的所有失败情况。

关于c# - 为什么这个端口扫描器代码有时会错过打开的端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9142952/

相关文章:

TCP连接池

c# - 从命令行向 OpenFire 房间发送 XMPP 消息

c# - 如何重写查询表达式以用整数替换枚举?

c++ - Linux 在多线程程序中处理特定线程上的信号

c# - 从我的 C# 应用程序的 dhcp 服务器获取 IP 地址 - 像虚拟机

sockets - gforth 是否包含网络套接字功能?

c Windows connect() 失败。错误 10049

c# - Kestrel 上的身份验证失败,但 IIS Express 上没有

c# - 如何给SqlCommand 添加参数?

c# - C# 中的 TCP 跟踪路由