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:
Ping these addresses to find available machines
Connect to a known socket on the available machines
Send a message to the successfully established sockets
Compare the response to the expected response
Steps 2-4 are straight forward for 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;
}