Recently, I was asked to automate the process of checking a set of known URLs and determining if each URL corresponded to a “live” site. For our purposes, a site is live if I can PING it and get a reply back.
I can open a command prompt and use the PING command and read the response to determine if a site is live. A live site would return a series of messages starting with “Reply from”, while a non-existent site would report an error.
Unfortunately it is difficult to automate this task from the command prompt. Fortunately, the .Net framework provides the tools to allow me to ping a URL with just a few lines of code. The functionality I need is in the System.Net.NetworkInformation namespace.
I have created a public class PingUtils and added the statement
using System.Net.NetworkInformation;
at the top of this class.
Next, I added the following method to attempt to ping a URL and return true, if successful.
public bool UrlIsLive(string url, int timeOut)
{
bool pingSuccess = false;
Ping ping = new Ping();
string pingData = "TEST";
byte[] pingDataBytes = Encoding.ASCII.GetBytes(pingData);
try
{
PingReply reply = ping.Send(url, timeOut, pingDataBytes);
if (reply.Status == IPStatus.Success)
{
pingSuccess = true;
}
}
catch(PingException)
{
pingSuccess = false;
}
return pingSuccess;
}
That’s it. If an error occurs when I try to ping, it is most likely a PingException, which is equivalent to the "Ping request could not find host" error reported at the command prompt.
This function returns true for a URL that exists and is live; and false for one that does not exist.
The following unit tests should deomonstrate this
///
///A positive test for IsLive
///
[TestMethod()]
public void IsLive_PingGoodUrl_ShouldReturnTrue()
{
PingUtils pu = new PingUtils();
string url = @"DavidGiard.com";
int timeOut = 1000;
bool siteIsLive = pu.UrlIsLive(url, timeOut);
Assert.IsTrue(siteIsLive, "PingUtils.IsLive did not return true as expected");
}
///
///A negative test for IsLive
///
[TestMethod()]
public void IsLive_PingBadUrl_ShouldReturnFalse()
{
PingUtils pu = new PingUtils();
string url = @"notDavidGiard.com";
int timeOut = 1000;
bool siteIsLive = pu.UrlIsLive(url, timeOut);
Assert.IsFalse (siteIsLive, "PingUtils.IsLive did not return false as expected");
}
It’s worth pointing out a couple limitations of this function.
- Some site’s reject all PING request as a way to protect themselves against Denial of Service attacks. For example, if you PING Microsoft.com, it will not Reply, even though the site does exist.
- As with any program that uses networking, the internal firewall rules where the program runs may affect the success of the program.
- The PING command checks for valid URLs, even if the URL returns an error page. So, foo.DavidGiard will reply to a PING request because my hosting provider redirects this to an error page.
Even given those limitations, this can be a very useful function for testing if all the Links stored in your database are still relevant.
You can download the code here.