开发者

Proper way to scan a range of IP addresses

Given a range of IP addresses entered by a user (through various means), I want to identify which of these machines have software running that I can talk to.

Here's the basic process:

  1. Ping these addresses to find available machines

  2. Connect to a known socket on the available machines

  3. Send a message to the successfully established sockets

  4. Compare the response to the expected response

Steps 2-4 are straight forward fo开发者_StackOverflowr me. What is the best way to implement the first step in .NET?

I'm looking at the System.Net.NetworkInformation.Ping class. Should I ping multiple addresses simultaneously to speed up the process? If I ping one address at a time with a long timeout it could take forever. But with a small timeout, I may miss some machines that are available.

Sometimes pings appear to be failing even when I know that the address points to an active machine. Do I need to ping twice in the event of the request getting discarded?

To top it all off, when I scan large collections of addresses with the network cable unplugged, Ping throws a NullReferenceException in FreeUnmanagedResources(). !?

Any pointers on the best approach to scanning a range of IPs like this?


Since not all machines respond to pings (depending on firewall settings) I suggest skipping step 1 if possible.

If you know the machines you will be connecting to respond to pings the ping class works well enough. It only sends 1 packet so ping more than once in case it gets dropped. Also, in my experience the ping class will often throw an exception instead of returning a PingReply object if the host is unreachable.

This is my suggested implementation:

public bool
   Ping (string host, int attempts, int timeout)
   {
      System.Net.NetworkInformation.Ping  ping = 
                                       new System.Net.NetworkInformation.Ping ();

      System.Net.NetworkInformation.PingReply  pingReply;

      for (int i = 0; i < attempts; i++)
      {
         try
         {
            pingReply = ping.Send (host, timeout); 

            // If there is a successful ping then return true.
            if (pingReply != null &&
                pingReply.Status == System.Net.NetworkInformation.IPStatus.Success)
               return true;
         }
         catch
         {
            // Do nothing and let it try again until the attempts are exausted.
            // Exceptions are thrown for normal ping failurs like address lookup
            // failed.  For this reason we are supressing errors.
         }
      }

      // Return false if we can't successfully ping the server after several attempts.
      return false;
   }


Don't forget the headache of the people who will deny pinging in their firewall rules.

My only suggestion is perhaps a question: Do you have to do #1?

Can't you simply try to connect to that known socket? Successful connection to that socket kills two birds with one stone: yes the host is there/alive, and yes, the known-socket is open.

This type of situation does lend itself well to multithreading, fire it off on another thread, and wait for it to come back with an answer...


As many people mentioned Ping is not the best ways to detect if the machine is alive, if it is an absolute must to detect all available machine on the subnet, you could use some of the trick nmap scanner uses, to detect available machines.

You couuld use nmap -sP 192.168.2.1-200 to scan 192.168.2.0 to 192.168.2.255


Sounds suspiciously like someone trying to write a botnet and scanning subnets for infected PCs.

There's hardly ever a reason to "detect computers on the network", let them talk to you instead when and if they want to.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜