C# Ping code performance

HavocXphere

Honorary Master
Joined
Oct 19, 2007
Messages
33,153
Reaction score
1,297
Location
Europe
I'm toying around with some code, most of which I got off MSDN over here.

Pings 256 IPs on a local LAN, 3 of which should respond.

The code works largely as expected, but a couple of things are bothering me about it:
  • It seems slow to me. 2 minutes to run through 256 IPs. Is that normal?
  • The timeout value has no effect on the time taken. I think the time taken should drop if I reduce the timeout.
  • [-]The IDE shows a warning for the exception handling I'm doing (variable e unused). Is there a more correct way to ignore exceptions (Ping accepts hostnames too & bombs if it can't resolve them)?[/-]
  • [-]Is this something one would use threading for to make it more async?[/-]

Thanks

Code:
         public static bool PingIP(string ip)
        {
            bool outcome = false;            
            Ping pingSender = new Ping();
            PingOptions options = new PingOptions();

            // Use the default Ttl value which is 128,
            // but change the fragmentation behavior.
            options.DontFragment = true;

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 120;
            try
            {
                PingReply reply = pingSender.Send(ip, timeout, buffer, options);
                if (reply.Status == IPStatus.Success)
                {
                    outcome = true;
                }
            }
            catch (Exception e)
            {
               
            }
            return outcome;

        }

        public void PingNow()
        {
            int tickstart = Environment.TickCount;
            for (int i = 0; i < 256; i++)
            {
                if (PingIP("192.168.0." + i))
                {
                    //LB.Items.Add("192.168.0." + i +" succeeded");
                }
                else
                {
                    //LB.Items.Add("192.168.0." + i + " failed");
                }
            }
            LB.Items.Add("Done: " + (Environment.TickCount - tickstart));
        }
 
Last edited:
try using

options.ttl= 50;

instead of the
 
240 seconds is less than 1 second per IP. Seems reasonable to me.
How many seconds in 2 minutes? :p

Works out to about 500ms each. Still...sounds slow. Very little data, fat 100mb LAN pipe & super low latency (<2ms). imo it should be possible to abandon each IP after say 10-20ms of no response, so total time should be around the 5 sec mark....assuming I can set the timeout, which doesn't seem to work.:mad:

Thanks the exception warning is fixed & I see there is a threading link in the .Net knowledge thread.

options.ttl= 50;
No effect. I think TTL relates to the number of hops though & the LAN only has 1 (or 2 depending on how its counted).
 
ttl is time to live.

maybe set ttl and set timeout to 0
 
Try lowering your timeout even more. Even though you are pinging your local LAN, if there is no response it only sees that on timeout.
That is what puzzles me: 10ms timeout and 120ms timeout yield exactly the same total time.

Its not really an issue...I don't specifically need this to be very fast. Just puzzled by it...

20 seconds using TPL
Thanks. Impressive code...looks cleaner than the MSDN code..:cool: The threading pool thing is pretty cool too, though that syntax is going to take some getting used to. :erm:
 
I'm toying around with some code, most of which I got off MSDN over here.

Pings 256 IPs on a local LAN, 3 of which should respond.

The code works largely as expected, but a couple of things are bothering me about it:
  • It seems slow to me. 2 minutes to run through 256 IPs. Is that normal?
  • The timeout value has no effect on the time taken. I think the time taken should drop if I reduce the timeout.
  • [-]The IDE shows a warning for the exception handling I'm doing (variable e unused). Is there a more correct way to ignore exceptions (Ping accepts hostnames too & bombs if it can't resolve them)?[/-]
  • [-]Is this something one would use threading for to make it more async?[/-]

Thanks
Threading is definitely the way to go.
For example: 20 threads would have this done in ~12 seconds.

With C# it's really not complicated at all (actually easy) -- if you'd like some help PM me.

Btw another alternative is asynchronous pings.
 
Last edited:
[)roi(];7352267 said:
Threading is definitely the way to go.
For example: 20 threads would have this done in ~12 seconds.

With C# it's really not complicated at all (actually easy) -- if you'd like some help PM me.

Btw another alternative is asynchronous pings.
Thanks. I think I've got it mostly figured out (the ping part of C#).

Only part that is still fuzzy is why its so slow at all. 256 pings of 32 bytes of data on a LAN & 10ms timeout should be super fast even without async/threading. I see apps like NetScan are pretty slow too though, so whatever the reason its probably a good one. Like I said though...its not a problem, just a bit puzzled about that aspect.
 
Thanks. I think I've got it mostly figured out (the ping part of C#).

Only part that is still fuzzy is why its so slow at all. 256 pings of 32 bytes of data on a LAN & 10ms timeout should be super fast even without async/threading. I see apps like NetScan are pretty slow too though, so whatever the reason its probably a good one. Like I said though...its not a problem, just a bit puzzled about that aspect.
256 pings one after each other is always slower than issuing many at the same time -- hence threading.
The offer stands... btw don't be scared of threading it's principle is simple and significantly accelerates workflow.

Understanding things like ttl and their behavior through routers / switches is a different matter -- important to make the distinction.

Netscan is not just performing one ping, in essence it is usually check multiple ports to identify open services; your example is very basic in comparison.
 
Last edited:
[)roi(];7353093 said:
256 pings one after each other is always slower than issuing many at the same time -- hence threading.
The offer stands... btw don't be scared of threading it's principle is simple and significantly accelerates workflow.
I get that a bunch of 500ms operations in parallel is faster, but why is it taking 500ms in the first place given that I've set the timeout to 10ms?

[)roi(];7353093 said:
Netscan is not just performing one ping, in essence it is usually check multiple ports to identify open services; your example is very basic in comparison.
We must be talking about a different app. The one I've got here, does not port scanning. I just checked with a packet sniffer to verify: Simple ICMPs w/ netbios followup to get the PC name.

[)roi(];7353093 said:
btw don't be scared of threading
I'm not. Well OK a little bit if it involves mutexs & similar horrors.:o
 
I get that a bunch of 500ms operations in parallel is faster, but why is it taking 500ms in the first place given that I've set the timeout to 10ms?
it's by design re setting small timeout values, makes no sense. http://msdn.microsoft.com/en-us/library/ms144955.aspx look for the following note:
Note
When specifying very small numbers for timeout, the Ping reply can be received even if timeout milliseconds have elapsed.
To get around the problem (the underlying reason you chose to reduce the timeout in the 1st place) you should as I mentioned either consider threading or asynchronous pings.

To pick up a unresolved topic from my previous TTL btw in contrast to what was mentioned controls the number of hops before the packets can be discarded I.e. to ensure your network and the Internet is not flooded with ping packets. Basically the TTL value is reduced by one for each hop it takes, and at zero its discarded.

We must be talking about a different app. The one I've got here, does not port scanning. I just checked with a packet sniffer to verify: Simple ICMPs w/ netbios followup to get the PC name.
http://www.extralan.co.uk/products/Diagnostic-Tools/NetScan-Tools-Pro.htm

I'm not. Well OK a little bit if it involves mutexs & similar horrors.:o
Actually many people over complicate threading, Microsoft with .NET and C# has made threading very simple.

There are some simple concepts/rules to grasp, and then you create a routine that each thread instance will execute, including choosing a mechanism to pass each thread it's specific data, and how these threads pass the results back to the main thread (you could for example use a queue, well at least one that is synchronized to ensure thread safety I.e. to ensure two or more threads are not "fighting" over the same thing).

Triggering them is the easy part, so too monitoring if they're still busy from the main thread (they all get killed if you let the main thread terminate, hence one reason to monitor.)

What is the reason for building your subnet ping app, the purpose will influence the design approach?
 
Last edited:
[)roi(];7358699 said:
it's by design re setting small timeout values, makes no sense.
I see. I figured with 1ms response time, 10ms timeout should work. Guess not.

[)roi(];7358699 said:
Actually many people over complicate threading, Microsoft with .NET and C# has made threading very simple.
Had a bad experiences with threading. I wanted to write a fast file copier for copying from between physical disks w/ 3 threads: Read, Write & UI. Ended up requiring tons of locking code & what not. That wasn't C# though.

[)roi(];7358699 said:
What is the reason for building your subnet, the purpose will influence the design approach?
Not sure what you mean by subnet here, its all one LAN & subnet. The original purpose behind the code was to see what PCs are switched on at any time on the LAN. I wanted it to be as "live" as possible, hence my interest in sending them fast.
 
I see. I figured with 1ms response time, 10ms timeout should work. Guess not.


Had a bad experiences with threading. I wanted to write a fast file copier for copying from between physical disks w/ 3 threads: Read, Write & UI. Ended up requiring tons of locking code & what not. That wasn't C# though.


Not sure what you mean by subnet here, its all one LAN & subnet. The original purpose behind the code was to see what PCs are switched on at any time on the LAN. I wanted it to be as "live" as possible, hence my interest in sending them fast.
On C and C++ threading was complicated; languages like C# and Java have simplified this a lot -- you should try again.

In your code example you are using a C class subnet, e.g. subnet mask of 255.255.255.0

Considering your case, you have a few options;
1. Threading
2. Asynchronous
3. Layer 2 broadcast and listen for responses (the fastest and most complicated approach as it will require a custom device driver written in C++)

Clearly for your case, I'd recommend 1 or 2;
2 avoids threading and is event driven.
1 offers the most flexibility, for example once you have a successful ping it is easy to tag on additional checks.
 
As a rough idea try something like this:

Define 2 queues, address and response

Create a ping module;
1. Pull address from queue, terminate if no more
2. Ping address
3. Push only positive results onto the response queue.

Main thread:
1. Initialize address queue and load it with ip addresses.
2. Initialize response queue.
3. Create as many thread instances of the ping module as you need and start them.
4. Wait until all threads have terminated.
5. Extract results from queue and write out to UI (can also be done interactively during in wait cycle).
 
Last edited:
Suddenly #2 sounds like a pretty good plan. :) That approach is slightly above my pay grade.
 
Suddenly #2 sounds like a pretty good plan. :) That approach is slightly above my pay grade.
Lol the asynchronous approach is also going to be a challenge; do you need help with the threading example I described?
 
[)roi(];7359855 said:
Lol the asynchronous approach is also going to be a challenge; do you need help with the threading example I described?
MSDN has an async example I think. Thanks, I think I'm fine though. Dequadins code above is already threaded, so I'll probably use that.
 
Top
Sign up to the MyBroadband newsletter
X