Solved

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

Posted on 2011-03-18
2
1,627 Views
Last Modified: 2012-05-11
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.




0
Comment
Question by:carlostriassi
2 Comments
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 500 total points
ID: 35170264
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
 

Author Closing Comment

by:carlostriassi
ID: 35178251
great job and thank you!
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There have been a lot of times when we have seen the need to enter a large number of DNS entries in a forward lookup zone. The standard procedure would be to launch the DNS Manager console, create the Zone and start adding new hosts using the New…
Occasionally you run into the website or two that will not resolve properly using your own DNS servers.  Some people simply set up global forwarders for their DNS server.  I don’t recommend doing this because it can cause problems resolving addresse…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now