![]() |
General Programming »
Internet / Network »
Utilities
Intermediate
License: The Code Project Open License (CPOL)
Simple Ping Utility with GUIBy Mladen JankovicUsing the Ping class in .NET Framework |
C# 2.0, Windows, .NET 2.0, Visual Studio, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
This article demonstrates Ping class located in the System.Net.NetworkInformation namespace. The demo application can be useful to network administrators or others who need to monitor their servers and connections.
I have a pretty unreliable Internet connection over wireless, so packets are being lost all the time. From time to time my access point pretends to be dead or, not-so-rarely, my ISP's servers go down. To identify the problem, I usually have to run a few ping commands in different windows and that really annoys me. The other disadvantage of the ping command is that it doesn't provide statistics until you stop it. So, I decided to make a simple GUI application which will provide needed information as quickly as possible.
The most common way to ping another host is to send ICMP [RFC792] echo message and then wait for the response from the targeted host. As I stated at the beginning of the article you can use Ping class available in .NET Framework that wraps this type of ICMP message to make your life easier and save yourself from implementing the protocol by yourself.
Ping class goes together with some other classes and data types such as PingOptions and PingReply classes and IPStatus enumeration. The heart of the class is the Send method [and SendAsync] that sends echo message and waits for the response. The method has several overloads but all of them return an instance of the PingReply class which contains results of echo request [Status property] and response time [RoundtripTime]. Here are a few examples:
Ping pinger = new Ping();
// first parameter is TTL and second sets flag in IP header to
// tell routers not to fragment the datagram
PingReply reply = PingOptions pingerOptions = new PingOptions(127, false);
// specify computer by its name
PingReply reply = pinger.Send("localhost");
// with timeout specified
PingReply reply = pinger.Send("localhost", 1000);
// specify computer by its IP address
PingReply reply = pinger.Send(new IPAddress(new byte[] { 127, 0, 0, 1 }));
// specify computer by its name, sets timeout, uses user defined buffer and
// options
PingReply reply = pinger.Send(new IPAddress(new byte[] { 127, 0, 0, 1 }),
1000, buffer, pingerOptions);
But it is only the first half of the story. Based on that simple method, we need to provide some meaningful and useful statistical information. HostPinger class is built on top of the Ping class and it is in charge of pinging the host and calculating, storing and providing statistics about it.
The class has five public constructors:
// constructs pinger for localhost (127.0.0.1)
public HostPinger()
// constructs pinger from XML config file
public HostPinger(XmlNode node)
// use DNS to resolve the IP address from hostname
public HostPinger(string hostName)
// construct pinger for host without a name
public HostPinger(IPAddress address)
// it the IP address specified, hostname can be used as a description
public HostPinger(string hostName, IPAddress address);
Pinging is controlled with Start and Stop methods or by setting the IsRunning property. HostPinger class has four events [their names describe their purpose well, so there is no need for additional explanations]:
OnPingOnStatusChangeOnStartPingingOnStopPingingUser can also provide a logger to log these events [except OnPing event] by setting Logger property. Provided logger must implement IPingLogger interface.
public interface IPingLogger
{
void LogStart(HostPinger host);
void LogStop(HostPinger host);
void LogStatusChange(HostPinger host, HostStatus oldStatus, HostStatus newStatus);
}
And finally the Save method will write ping options and host information using the provided XmlWriter object.
The information about the host that this class can provide to the user is as listed below:
| Name/Description | Property Name | Data Type | Values |
| Host's current status | Status |
HostStatus |
Alive, Dead, DnsError, Unknown |
| Number of sent requests | SentPackets |
int |
positive number |
| Number of received responses [successful pings] | ReceivedPackets |
int |
positive number |
| Percent of received responses [successful pings] | ReceivedPacketsPercent |
float |
(0, 100) |
| Number of lost packets [unsuccessful pings] | LostPackets |
int |
positive number |
| Percent of lost packets[successful pings] | LostPacketsPercent |
float |
(0, 100) |
| Whether the last packet lost | LastPacketLost |
bool |
true/false |
| Number of recently received responses [successful pings] | RecentlyReceivedPackets |
int |
positive number |
| Percent of recently received responses [successful pings] | RecentlyReceivedPacketsPercent |
float |
(0, 100) |
| Number of recently lost packets[unsuccessful pings] | RecentlyLostPackets |
int |
positive number |
| Percent of recently lost packets[unsuccessful pings] | RecentlyLostPacketsPercent |
float |
(0, 100) |
| Current response time of the host [in milliseconds] | CurrentResponseTime |
long |
positive number |
| Average response time of the host [in milliseconds] | AverageResponseTime |
float |
(0, ?) |
| Duration of the current host's status | GetStatusDuration method provides this information |
TimeSpan |
|
| How long the host has been alive | GetStatusDuration method provides this information |
TimeSpan |
|
| How long the host has been dead | GetStatusDuration method provides this information |
TimeSpan |
|
| How long the pinger has not been able to obtain IP address of the host from its name | GetStatusDuration method provides this information |
TimeSpan |
|
| How long the host status has been unknown | |
TimeSpan |
|
| Availability of the host[in percents] | HostAvailability |
float |
(0, 100) |
| Total duration of all ran tests | TotalTestDuration |
TimeSpan |
|
| Duration of the current test | CurrentTestDuration |
TimeSpan |
Host pinger can be configured with following options:
| Name of XML element in the configuration file that stores option | Name of the property | Type | Required | Default Value |
name |
HostName |
string |
Yes | none |
| Host name. If IP address is not specified, pinger uses this name to query DNS server and obtain IP address of the host. | ||||
ip |
IPAddress |
IP Address format | No | DNS query if not set |
| IP address of host. It is not a required field. If IP address is not specified, pinger uses this host name to query DNS server and obtain IP address of the host. | ||||
description |
HostDescription |
string |
No | none |
| Description of the host. | ||||
timeout |
Timeout |
int |
No | 2000 |
| Time [milliseconds] to wait for each reply. | ||||
interval |
PingInterval |
int |
No | 1000 |
| Time [milliseconds] that pinger waits after it receives reply from previous ping and before it sends another ping. | ||||
pingsbeforedead |
PingsBeforeDead |
int |
No | 10 |
| Number of unsuccessful pings before pinger declares host as dead. | ||||
buffersize |
BufferSize |
int |
No | 32 |
| Size [bytes] of echo message. | ||||
ttl |
TTL |
int |
No | 32 |
| Time To Live. | ||||
dontfragment |
DontFragment |
bool |
No | false |
| Sets "Don't fragment flag" in IP packet. | ||||
dnsinterval |
DnsQueryInterval |
int |
No | 60000 |
| Time [milliseconds] between unsuccessful try and new try to obtain host's IP address using DNS. | ||||
recenthistorydepth |
RecentHistoryDepth |
int |
No | 10 |
| Number of sent pings used for recent history. | ||||
The application uses hosts.cfg file located in the same directory as executable file to store list of hosts for pinging and ping options in XML format.
<pinger>
<!-- List of host -->
<host>
<!-- Host options -->
<name><!-- host name --></name>
<ip><!-- host ip --></ip>
<timeout><!-- timeout --></timeout>
<interval><!-- ping interval --></interval>
<pingsbeforedead><!-- pings before dead --></pingsbeforedead>
<buffersize><!-- echo message size --></buffersize>
<ttl><!-- Time To Live --></ttl>
<dontfragment><!-- Don't fragment flag --></dontfragment>
<description><!-- Description of the host --></description>
<dnsinterval><!-- Duration of interval between DNS queries --></dnsinterval>
<recenthistorydepth><!-- Depth of recent history --></recenthistorydepth>
</host>
<host>
<!-- Host options -->
<!-- ... -->
</host>
<!-- More host... -->
</pinger>
<pinger>
<host>
<name>localhost</name>
<ip>127.0.0.1</ip>
<timeout>300</timeout>
<interval>2000</interval>
<pingsbeforedead>5</pingsbeforedead>
<buffersize>32</buffersize>
<ttl>3</ttl>
<dontfragment>false</dontfragment>
</host>
<host>
<name>google.com</name>
<timeout>2000</timeout>
<interval>2000</interval>
</host>
<host>
<name>some local host</name>
<ip>192.168.0.1</ip>
<timeout>500</timeout>
<interval>2000</interval>
</host>
<host>
<name>yahoo.com</name>
<timeout>2000</timeout>
<interval>2000</interval>
</host>
</pinger>
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 28 Oct 2008 Editor: Deeksha Shenoy |
Copyright 2007 by Mladen Jankovic Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |