Convert IP address to DNS value it is slow scanning 254 devices

I'm able to ping 254 devices and get result back for their round trip time between 3-4 seconds. I'm using ThreadPool and it works great.
I have collected all devices IP addresses and keeping records of those that have gotten a round trip values and those that have failed; so I can filter out the IP address that never got back their round trip from ping.
Given a collection of set good IP address; I can collect DNS values for each IP address; I have used everything but it takes 45 secods to over 1 minute to get back some DNS values from those set of good IP addresses.

I have use this code; this is very slooooow

 IPHostEntry ipHostEntry = Dns.GetHostByAddress(IPAddress.Parse(IP));

then I use this code below; it is better at best using ThreadPool but nevertheless it takes 45 secods to 1+ minute.      

        private delegate IPHostEntry GetHostEntryHandler(string ip);
        public string ReverseDNS(string ip, int timeout) // timeout in milliseconds
        {
            try
            {
                GetHostEntryHandler callback = new GetHostEntryHandler(Dns.GetHostEntry);
                IAsyncResult result = callback.BeginInvoke(ip, null, null);
                if (result.AsyncWaitHandle.WaitOne(timeout, false))
                {
                    // Received response within timeout limit
                    return callback.EndInvoke(result).HostName;
                }
                else
                {
                    // Did not receive response within timeout limit,
                    // send back IP Address instead of hostname
                    return ip;
                }
            }
            catch (Exception)
            {
                // Error occurred, send back IP Address instead of hostname
                return ip;
            }
        }
 
I run a comparison to a tool that I found Si360 scanning the same 254 devices as on my test program; SI260 took 9 seconds to get response back resolve all DNS values whenever possible.

Is it anything that I'm missing to get a faster response on converting IP address to DNS.

Your help would be much appreciated.

Regards
Calos.




carlostriassiAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Todd GerbertIT ConsultantCommented:
Hmm, using the code below I'm resolving 174 addresses in about 12 seconds. It looks like you're not passing a callback to BeginGetHostEntry(), just using the WaitHandle for it to finish or timeout, which means the lookups are gonna run synchronously.

Resolved 174 IP addresses in 12.8888075 seconds.
140 IP addresses successfully resolved, 34 failed.

Open in new window


For my test I ran a ping on all of my networks IP addresses and put the ones that responded to the ping in a list. Then ran the DNS lookups on just the addresses in that list. I just started'em all at once, and then waited for the completedCounter to reach the number of addresses in the list. Everytime the callback is called I incremented the counter by one.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;

class Program
{
	static long completedCounter = 0;
	static long errorCounter = 0;
	static long successCounter = 0;

	static object listLock = new object();
	static object consoleLock = new object();

	static void Main(string[] args)
	{
		// Make a list of all alive hosts in my network
		List<IPAddress> aliveHosts = new List<IPAddress>();

		Console.Write("Finding alive hosts...");

		// This just pings .1 through .254, for each network
		// 192.168.1.x, 192.168.2.x, 192.168.3.x and 192.168.4.x
		// This is my entire network, I can't make a test bigger'n this. ;)
		// Everytime a host responds to a ping, add it's address to
		// the aliveHosts list
		for (byte i = 1; i < 5; i++)
		{
			for (byte j = 1; j < 255; j++)
			{
				IPAddress ip = new IPAddress(new byte[] { 192, 168, i, j });
				ThreadPool.QueueUserWorkItem(delegate(object state)
				{
					Ping ping = new Ping();
					if (ping.Send(ip, 50).Status == IPStatus.Success)
						lock (listLock) aliveHosts.Add(ip);
					Interlocked.Increment(ref completedCounter);
					lock (consoleLock)
					{
						Console.CursorLeft = 22;
						Console.Write("{0} of 1016        ", Interlocked.Read(ref completedCounter));
					}
				});
			}
		}

		do
		{
			Thread.Sleep(0);
		} while (Interlocked.Read(ref completedCounter) < 1016);

		// Reset the completedCounter
		completedCounter = 0;

		// Start timer here to check DNS performance
		Stopwatch stopwatch = new Stopwatch();
		stopwatch.Start();

		foreach (IPAddress ip in aliveHosts) // Only do lookups for hosts that are currently up
		{
			// Call GetHostEntry asynchronously - when GetHostEntry
			// finishes our GetHostEntryCallback method will be called
			Dns.BeginGetHostEntry(ip, new AsyncCallback(GetHostEntryCallback), ip);
		}

		do
		{
			// Wait until all pending GetHostEntry's finished
			// Thread.Sleep(0) won't sleep the thread, but will yield
			// processor time if another thread needs it
			Thread.Sleep(0);
		} while (Interlocked.Read(ref completedCounter) < aliveHosts.Count);
		stopwatch.Stop();

		Console.WriteLine("Resolved {0} IP addresses in {1} seconds.", aliveHosts.Count, stopwatch.Elapsed.TotalSeconds);
		Console.WriteLine("{0} IP addresses successfully resolved, {1} failed.", successCounter, errorCounter);
		Console.ReadKey();
	}

	static void GetHostEntryCallback(IAsyncResult iar)
	{
		string hostName = null;
		try
		{
			IPHostEntry host = Dns.EndGetHostEntry(iar); // Gets the result of the asynchronous method
			hostName = host.HostName;
			Interlocked.Increment(ref successCounter);
		}
		catch (Exception ex)
		{
			hostName = ex.Message;
			Interlocked.Increment(ref errorCounter);
		}
		finally
		{
			lock (consoleLock) Console.WriteLine("{0} -> {1}", iar.AsyncState, hostName);
		}
		Interlocked.Increment(ref completedCounter); // Increment the counter everytime a lookup is done (success or failure)
		return;
	}
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
carlostriassiAuthor Commented:
great job and thank you!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.