Solved

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

Posted on 2011-03-18
2
1,719 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

749 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