Subscribe to Blog.Parse(typeof(PsychoCoder), Richard McCutchen);        RSS Feed
-----

To Ping or Not To Ping

Icon Leave Comment
Recently there was a question in the C# forum regarding creating a Ping utility so this got me to thinking about updating my own utility up to C# 3.5 (currently it's 2.0) so I created a new Console Application and got started.

Before anyone can Ping a site they need to make sure they actually have an Internet connection, and we have taken care of that with the Win32 API (otherwise known as P/Invoke) so to make this work you'll need to add the following to the top of your code file

using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;



So inorder to check for ana ctive connection with P/Invoke we'll require an enum (ConnectionStatsEnum) and a Win32 API (InternetGetConnectedState) so let's take a look at these

ConnectionStatusEnum
/// <summary>
/// enum to hold the possible connection states
/// </summary>
[Flags]
enum ConnectionStatusEnum : int
{
    INTERNET_CONNECTION_MODEM = 0x1,
    INTERNET_CONNECTION_LAN = 0x2,
    INTERNET_CONNECTION_PROXY = 0x4,
    INTERNET_RAS_INSTALLED = 0x10,
    INTERNET_CONNECTION_OFFLINE = 0x20,
    INTERNET_CONNECTION_CONFIGURED = 0x40
}



InternetGetConnectionState
[DllImport("wininet", CharSet = CharSet.Auto)]
static extern bool InternetGetConnectedState(ref ConnectionStatusEnum flags, int dw);



We then put that together in a private method so we can check for a valid connection before attemtping to Ping a host. That looks like this (and it's well commented as well)
/// <summary>
/// method to check the status of the pinging machines internet connection
/// </summary>
/// <returns></returns>
private static bool HasConnection()
{
    //instance of our ConnectionStatusEnum
    ConnectionStatusEnum state = 0;

    //call the API
    InternetGetConnectedState(ref state, 0);

    //check the status, if not offline and the returned state
    //isnt 0 then we have a connection
    if (((int)ConnectionStatusEnum.INTERNET_CONNECTION_OFFLINE & (int)state) != 0)
    {
        //return true, we have a connection
        return false;
    }
    //return false, no connection available
    return true;
}



The next think we do is to get the ip address of the host being pinged. This method will return an IPAddress array

/// <summary>
/// method for retrieving the IP address from the host provided
/// </summary>
/// <param name="host">the host we need the address for</param>
/// <returns></returns>
private static IPAddress[] GetIpFromHost(ref string host)
{
    //variable to hold our error message (if something fails)
    string errMessage = string.Empty;

    //IPAddress instance for holding the returned host
    IPHostEntry address = Dns.GetHostEntry("google.com");

    //wrap the attempt in a try..catch to capture
    //any exceptions that may occur
    try
    {
        //get the host IP from the name provided
        IPAddress[] add = address.AddressList;

        return add;
    }
    catch (SocketException ex)
    {
        //some DNS error happened, return the message
        errMessage = string.Format("DNS Error: {0}", ex.Message);
        return null;
    }
    //return address;
}



Now we need to put it altogether to perform a ping to a host

/// <summary>
/// method to check the ping status of a provided host
/// </summary>
/// <param name="addr">the host we need to ping</param>
/// <returns></returns>
public static void PingHost(string host, int numTimes)
{
    //IPAddress instance for holding the returned host
    IPAddress[] address = GetIpFromHost(ref host);

    //set the ping options, TTL 128
    PingOptions pingOptions = new PingOptions(128, true);

    //create a new ping instance
    Ping ping = new Ping();

    //32 byte buffer (create empty)
    byte[] buffer = new byte[32];

    //first make sure we actually have an internet connection
    if (HasConnection())
    {
        //here we will ping the host 4 times (standard)
        for (int i = 0; i < numTimes; i++)
        {
            try
            {
                //send the ping 4 times to the host and record the returned data.
                //The Send() method expects 4 items:
                //1) The host we are pinging
                //2) The timeout value
                //3) A buffer (our byte array)
                //4) PingOptions
                PingReply pingReply = ping.Send(address[0], 120, buffer, pingOptions);

                //make sure we dont have a null reply
                if (!(pingReply == null))
                {
                    switch (pingReply.Status)
                    {
                        case IPStatus.Success:
                            Console.WriteLine(string.Format("Reply from {0}: bytes={1} time={2}ms TTL={3}", pingReply.Address, pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl) );
                            break;
                        case IPStatus.TimedOut:
                            Console.WriteLine("Connection has timed out...");
                            break;
                        default:
                            Console.WriteLine(string.Format("Ping failed: {0}", pingReply.Status.ToString()));
                            break;
                    }
                }
                else
                    Console.WriteLine("Connection failed for an unknown reason...");
            }
            catch (PingException ex)
            {
                Console.WriteLine(string.Format("Ping Error: {0}", ex.Message));
            }
            catch (SocketException ex)
            {
                Console.WriteLine(string.Format("Socket Error: {0}", ex.Message));
            }
        }
    }
    else
        Console.WriteLine("No Internet connection found...");
}



Now we can run an example of it in action in our main method like this

static void Main(string[] args)
{
    PingHost("google.com", 6);
    Console.ReadLine();
}



This will give us these results

Attached Image

0 Comments On This Entry

 

Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

May 2020

S M T W T F S
     12
3456789
10111213141516
17181920212223
2425262728 29 30
31      

Recent Entries

Search My Blog

1 user(s) viewing

1 Guests
0 member(s)
0 anonymous member(s)