Jim Scott's Coding Blog

It's all about that code, that code, that code, no treble

C# Ping

I was recently tasked with putting together a ping and traceroute feature in an application and like I always do I googled to see if someone had already worked out how to do this.

I found a few people who had posted ICMP libraries and so I used one of them and tested and everything seemed to work properly. However I was getting reports that it was not working on Vista. However the person could use the built in ping and tracert utilities with no issue.

At first I thought it might be related to permissions or firewall but none of those ended up resolving the issue.

So I fired up wireshark and looked at what was different at the packet level between what I was doing and what the built in windows ping was doing.

The code I was using was returning an incorrect checksum on the ICMP reply. So I searched a bit to learn about the checksum and ended up finding somehow that as of .NET 2.0 framework there is a Ping class built into the framework!!

So I am posting this in hopes of saving someone a bunch of time with the same issue I had. Also the code I had to put together initially was much more complex. This I think you will see is very straight forward.

Download PingUtility.cs (3.14 kb)

Example Output:

Pinging with 32 bytes of data:

Reply from bytes=32 time=11ms TTL=128
Reply from bytes=32 time=3ms TTL=128
Reply from bytes=32 time=3ms TTL=128
Reply from bytes=32 time=3ms TTL=128

Ping statistics for
	Packets: Sent = 4, Received = 4, Lost = 0
Approximate round trip times in milli-seconds:
	Minimum = 3ms, Maximum = 11ms
public static string Ping()
    using (Ping pingSender = new Ping())
        PingOptions pingOptions = null;
        StringBuilder pingResults = null;
        PingReply pingReply = null;
        IPAddress ipAddress = null;
        int numberOfPings = 4;
        int pingTimeout = 1000;
        int byteSize = 32;
        byte[] buffer = new byte[byteSize];
        int sentPings = 0;
        int receivedPings = 0;
        int lostPings = 0;
        long minPingResponse = 0;
        long maxPingResponse = 0;
        string ipAddressString = "";
        pingOptions = new PingOptions();
        //pingOptions.DontFragment = true;
        //pingOptions.Ttl = 128;
        ipAddress = IPAddress.Parse(ipAddressString);
        pingResults = new StringBuilder();
        pingResults.AppendLine(string.Format("Pinging {0} with {1} bytes of data:", ipAddress, byteSize));
        for (int i = 0; i < numberOfPings; i++)
            pingReply = pingSender.Send(ipAddress, pingTimeout, buffer, pingOptions);
            if (pingReply.Status == IPStatus.Success)
                pingResults.AppendLine(string.Format("Reply from {0}: bytes={1} time={2}ms TTL={3}", ipAddress, byteSize, pingReply.RoundtripTime, pingReply.Options.Ttl));
                if (minPingResponse == 0)
                    minPingResponse = pingReply.RoundtripTime;
                    maxPingResponse = minPingResponse;
                else if (pingReply.RoundtripTime < minPingResponse)
                    minPingResponse = pingReply.RoundtripTime;
                else if (pingReply.RoundtripTime > maxPingResponse)
                    maxPingResponse = pingReply.RoundtripTime;
        pingResults.AppendLine(string.Format("Ping statistics for {0}:", ipAddress));
        pingResults.AppendLine(string.Format("\tPackets: Sent = {0}, Received = {1}, Lost = {2}", sentPings, receivedPings, lostPings));
        pingResults.AppendLine("Approximate round trip times in milli-seconds:");
        pingResults.AppendLine(string.Format("\tMinimum = {0}ms, Maximum = {1}ms", minPingResponse, maxPingResponse));
        return pingResults.ToString();

Comments (1) -

  • yolylight

    3/27/2012 9:32:12 PM | Reply