Page 1 of 1

Using the Ping Class in C#

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1641
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Posted 10 November 2008 - 11:59 AM

Recently I came across a question on how one would go about pinging a website or computer to see if it was active, so today we are going to look at using the Ping Class, located in the System.Net.NetworkInformation Namespace.

For the record, this is a new Namespace and class in the .Net Framework 2.0, so it isnt available in version 1.1 or older. This Namespace gives us access to all things related to network traffic, network address and it'sa information and allows for notifications of any network address changes on any computer on that specified network.

Before one can ping an outside host, you need to make sure the computer you're on actually has an internet connection, so thats what we start with. The easiest way, and most reliable way, to accomplish this is with the Win32 API function InternetGetConnectedState, this function wil return the current state of your connection. To this we will will pass an enum (ConnectionStatusEnum we will take a look at shortly, and an out instance of our enum.

Before we can do any of this, we need to make sure we reference the proper Namespaces. The Namespaces we need for this tutorial are:
  • System.Runtime.InteropServices: This is for declaring our Win32 API
  • System.Net
  • System.Net.NetworkInformation
  • System.Net.Sockets
Our enum will contain all the flags for determining the different states of a network connection. We will allow the items in our enum to be treated as bit fileds by adding the System.FlagsAttribute to our enum. Our enum looks like this:
/// <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
}



Now we need to declare our Win32 API InternetGetConnectedState. This is where the System.Runtime.InteropServices Namespace comes into play, because we need to be able to access to the DllImportAttribute so we can import and access the Wininet API. This is our Win32 declaration
[DllImport("wininet", CharSet = CharSet.Auto)]
static extern bool InternetGetConnectedState(ref ConnectionStatusEnum flags, int dw);




Next we use the InternetGetConnectedStateAPI and it returns either true (we have a connection) or false (a connection was not found):
/// <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;
}




Now with this we want the user to be able to provide either an IP address or the host name, such as http://www.google.com, so we need to convert this to an IPAddress. For this we will use the Dns.GetHostEntry Method and pass the information the user provides. Since this can throw a SocketException we will wrap it in a try...catch block.

In this example I have created a method GetIpFromHost that returns our IPAddress object. We pass the method the host (either Ip address or host name) the user provides and it will return either an IPAddress object or an error message. So here is that method
/// <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
    IPAddress address = null;

    //wrap the attempt in a try..catch to capture
    //any exceptions that may occur
    try
    {
        //get the host IP from the name provided
        address = Dns.GetHostEntry(host).AddressList[0];
    }
    catch (SocketException ex)
    {
        //some DNS error happened, return the message
        errMessage = string.Format("DNS Error: {0}", ex.Message);
    }
    return address;
}



Now we come to do the actuall pinging. The Send Method requires 4 items to be passed to it:
  • An IPAddress
  • A timeout value (in this case we'll use 1000)
  • A byte buffer
  • A PingOptions class
The first 4 lines of our PingHost() method we create these options
//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];



Next we will use our HasConnection method to ensure we have a valid connection
if(HasConnection())
{
    //in here we will do the work
}



Since a normal ping (from a Windows based computer) send 4 pings we will do the same. We will do this in a for loop, each time calling Send and checking the PingReply status. When doing this we will be checking the IPStatus returned from our Ping. A list of possible responses is located here
for (int i = 0; i < 4; i++)
{
    try
    {
        //send the ping 4 times to the host and record the returned data.
        //The Send() method expects 4 items:
        //1) The IPAddress we are pinging
        //2) The timeout value
        //3) A buffer (our byte array)
        //4) PingOptions
        PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);

        //make sure we dont have a null reply
        if (!(pingReply == null))
        {
            switch (pingReply.Status)
            {
                case IPStatus.Success:
                    returnMessage = 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:
                    returnMessage = "Connection has timed out...";
                    break;
                default:
                    returnMessage = string.Format("Ping failed: {0}", pingReply.Status.ToString());
                    break;
            }
        }
        else
            returnMessage = "Connection failed for an unknown reason...";
    }
    catch (PingException ex)
    {
        returnMessage = string.Format("Connection Error: {0}", ex.Message);
    }
    catch (SocketException ex)
    {
        returnMessage = string.Format("Connection Error: {0}", ex.Message);
    }
}



Now, here is the PingHost() method in it's entirety
/// <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 string PingHost(string host)
{
    //string to hold our return messge
    string returnMessage = string.Empty;

    //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 < 4; i++)
        {
            try
            {
                //send the ping 4 times to the host and record the returned data.
                //The Send() method expects 4 items:
                //1) The IPAddress we are pinging
                //2) The timeout value
                //3) A buffer (our byte array)
                //4) PingOptions
                PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);

                //make sure we dont have a null reply
                if (!(pingReply == null))
                {
                    switch (pingReply.Status)
                    {
                        case IPStatus.Success:
                            returnMessage = 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:
                            returnMessage = "Connection has timed out...";
                            break;
                        default:
                            returnMessage = string.Format("Ping failed: {0}", pingReply.Status.ToString());
                            break;
                    }
                }
                else
                    returnMessage = "Connection failed for an unknown reason...";
            }
            catch (PingException ex)
            {
                returnMessage = string.Format("Connection Error: {0}", ex.Message);
            }
            catch (SocketException ex)
            {
                returnMessage = string.Format("Connection Error: {0}", ex.Message);
            }
        }
    }
    else
        returnMessage = "No Internet connection found...";

    //return the message
    return returnMessage;
}



Though there are tons of other stuff involved with the System.Net.NetworkInformation Namespace, I figured it was time to scratch the surface of this very powerful Namespace. There will be more tutorials on using this Namespace in the future.

Now you know how you can ping a host from within your C# application. I hope you found this tutorial informative and useful and thanks for reading.

Happy Coding! :)

Is This A Good Question/Topic? 1
  • +

Replies To: Using the Ping Class in C#

#2 born2c0de  Icon User is offline

  • printf("I'm a %XR",195936478);
  • member icon

Reputation: 180
  • View blog
  • Posts: 4,667
  • Joined: 26-November 04

Posted 11 November 2008 - 12:20 AM

Nice Tutorial.
I fixed a couple of mismatched Tags (ending a [b] tag with a [/i], etc.). Hope you don't mind.
Was This Post Helpful? 1
  • +
  • -

#3 turkserdar  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-August 09

Posted 29 August 2009 - 04:06 AM

View PostPsychoCoder, on 10 Nov, 2008 - 10:59 AM, said:

Recently I came across a question on how one would go about pinging a website or computer to see if it was active, so today we are going to look at using the Ping Class, located in the System.Net.NetworkInformation Namespace.

For the record, this is a new Namespace and class in the .Net Framework 2.0, so it isnt available in version 1.1 or older. This Namespace gives us access to all things related to network traffic, network address and it'sa information and allows for notifications of any network address changes on any computer on that specified network.

Before one can ping an outside host, you need to make sure the computer you're on actually has an internet connection, so thats what we start with. The easiest way, and most reliable way, to accomplish this is with the Win32 API function InternetGetConnectedState, this function wil return the current state of your connection. To this we will will pass an enum (ConnectionStatusEnum we will take a look at shortly, and an out instance of our enum.

Before we can do any of this, we need to make sure we reference the proper Namespaces. The Namespaces we need for this tutorial are:
  • System.Runtime.InteropServices: This is for declaring our Win32 API
  • System.Net
  • System.Net.NetworkInformation
  • System.Net.Sockets
Our enum will contain all the flags for determining the different states of a network connection. We will allow the items in our enum to be treated as bit fileds by adding the System.FlagsAttribute to our enum. Our enum looks like this:
/// <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
}



Now we need to declare our Win32 API InternetGetConnectedState. This is where the System.Runtime.InteropServices Namespace comes into play, because we need to be able to access to the DllImportAttribute so we can import and access the Wininet API. This is our Win32 declaration
[DllImport("wininet", CharSet = CharSet.Auto)]
static extern bool InternetGetConnectedState(ref ConnectionStatusEnum flags, int dw);




Next we use the InternetGetConnectedStateAPI and it returns either true (we have a connection) or false (a connection was not found):
/// <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;
}




Now with this we want the user to be able to provide either an IP address or the host name, such as http://www.google.com, so we need to convert this to an IPAddress. For this we will use the Dns.GetHostEntry Method and pass the information the user provides. Since this can throw a SocketException we will wrap it in a try...catch block.

In this example I have created a method GetIpFromHost that returns our IPAddress object. We pass the method the host (either Ip address or host name) the user provides and it will return either an IPAddress object or an error message. So here is that method
/// <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
    IPAddress address = null;

    //wrap the attempt in a try..catch to capture
    //any exceptions that may occur
    try
    {
        //get the host IP from the name provided
        address = Dns.GetHostEntry(host).AddressList[0];
    }
    catch (SocketException ex)
    {
        //some DNS error happened, return the message
        errMessage = string.Format("DNS Error: {0}", ex.Message);
    }
    return address;
}



Now we come to do the actuall pinging. The Send Method requires 4 items to be passed to it:
  • An IPAddress
  • A timeout value (in this case we'll use 1000)
  • A byte buffer
  • A PingOptions class
The first 4 lines of our PingHost() method we create these options
//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];



Next we will use our HasConnection method to ensure we have a valid connection
if(HasConnection())
{
    //in here we will do the work
}



Since a normal ping (from a Windows based computer) send 4 pings we will do the same. We will do this in a for loop, each time calling Send and checking the PingReply status. When doing this we will be checking the IPStatus returned from our Ping. A list of possible responses is located here
for (int i = 0; i < 4; i++)
{
    try
    {
        //send the ping 4 times to the host and record the returned data.
        //The Send() method expects 4 items:
        //1) The IPAddress we are pinging
        //2) The timeout value
        //3) A buffer (our byte array)
        //4) PingOptions
        PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);

        //make sure we dont have a null reply
        if (!(pingReply == null))
        {
            switch (pingReply.Status)
            {
                case IPStatus.Success:
                    returnMessage += 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:
                    returnMessage = "Connection has timed out...";
                    break;
                default:
                    returnMessage = string.Format("Ping failed: {0}", pingReply.Status.ToString());
                    break;
            }
        }
        else
            returnMessage = "Connection failed for an unknown reason...";
    }
    catch (PingException ex)
    {
        returnMessage = string.Format("Connection Error: {0}", ex.Message);
    }
    catch (SocketException ex)
    {
        returnMessage = string.Format("Connection Error: {0}", ex.Message);
    }
}



Now, here is the PingHost() method in it's entirety
/// <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 string PingHost(string host)
{
    //string to hold our return messge
    string returnMessage = string.Empty;

    //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 < 4; i++)
        {
            try
            {
                //send the ping 4 times to the host and record the returned data.
                //The Send() method expects 4 items:
                //1) The IPAddress we are pinging
                //2) The timeout value
                //3) A buffer (our byte array)
                //4) PingOptions
                PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);

                //make sure we dont have a null reply
                if (!(pingReply == null))
                {
                    switch (pingReply.Status)
                    {
                        case IPStatus.Success:
                            returnMessage = 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:
                            returnMessage = "Connection has timed out...";
                            break;
                        default:
                            returnMessage = string.Format("Ping failed: {0}", pingReply.Status.ToString());
                            break;
                    }
                }
                else
                    returnMessage = "Connection failed for an unknown reason...";
            }
            catch (PingException ex)
            {
                returnMessage = string.Format("Connection Error: {0}", ex.Message);
            }
            catch (SocketException ex)
            {
                returnMessage = string.Format("Connection Error: {0}", ex.Message);
            }
        }
    }
    else
        returnMessage = "No Internet connection found...";

    //return the message
    return returnMessage;
}



Though there are tons of other stuff involved with the System.Net.NetworkInformation Namespace, I figured it was time to scratch the surface of this very powerful Namespace. There will be more tutorials on using this Namespace in the future.

Now you know how you can ping a host from within your C# application. I hope you found this tutorial informative and useful and thanks for reading.

Happy Coding! :)

Was This Post Helpful? 0
  • +
  • -

#4 turkserdar  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-August 09

Posted 29 August 2009 - 04:12 AM

hey i just sign up for this site. I reviewed the tutorial. if we run the code it will give us only the last ping info. therefore we need to change "Case=IpStatus.Success:
returnmessage = ...."
to
"returnmessage +=.."
hopefully it helps. happy coding
Was This Post Helpful? 0
  • +
  • -

#5 ZwilL2008  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 04-July 10

Posted 05 July 2010 - 12:05 AM

thanks for the tutorial,the code very readable.
Was This Post Helpful? 0
  • +
  • -

#6 jamestechstyle  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 10-October 10

Posted 10 October 2010 - 11:14 AM

All are good!!!I am sure this will guide you. I found this useful!!!

http://www.itpian.co...in-C-sharp.aspx
Was This Post Helpful? 0
  • +
  • -

#7 rcantarino  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 16-April 11

Posted 16 April 2011 - 11:07 AM

Hello, all

I am new in the developer C#, but am very problem in learn program.
I need make one aplication with test ip adress.
But I donīt understend with make code.

Anyone Can send me this code ?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1