tags:

views:

61

answers:

3

I'm trying to make a simple app that will "ping" a uri and tell me if its responding or not

I have the following code but it only seems to check domains at the root level

ie www.google.com and not www.google.com/voice

private bool WebsiteUp(string path)
    {

        bool status = false;

        try
        {
            Uri uri = new Uri(path);
            WebRequest request = WebRequest.Create(uri);
            request.Timeout = 3000;
            WebResponse response;
            response = request.GetResponse();
            if (response.Headers != null) 
            {
                status = true;
            }

        }
        catch (Exception loi) 
        {
            return false;
        }


        return status;
    }

Is there any existing code out there that would better fit this need?

+1  A: 

There is a Ping class you can utilize for that, more details can be found here: http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx

Mantisen
A: 

I did something similar when I wrote a torrent client to check valid tracker URLS, pretty sure I found the answer on SO but cant seem to find it anymore, heres the code sample I have from that post.

   using(var client = new WebClient()) { 
        client.HeadOnly = true; 
        // exists
        string Address1 = client.DownloadString("http://google.com"); 
        // doesnt exist - 404 error
        string Address2 = client.DownloadString("http://google.com/sdfsddsf"); 
    } 
kyndigs
Include the code for `MyClient` too?
Jon Hanna
Sorry that should be "WebClient" in the System.Net namespace :p
kyndigs
+1  A: 

Edit: Actually, I tell a lie - by default 404 should cause a web exception anyway, and I've just confirmed this in case I was misremembering. While the code given in the example is leaky, it should still work. Puzzling, but I'll leave this answer here for the better safety with the response object.


The problem with the code you have, is that while it is indeed checking the precise URI given, it considers 404, 500, 200 etc. as equally "successful". It also is a bit wasteful in using GET to do a job HEAD suffices for. It should really clean up that WebResponse too. And the term path is a silly parameter name for something that isn't just a path, while we're at it.

private bool WebsiteUp(string uri)
{
    try
    {
        WebRequest request = WebRequest.Create(uri);
        request.Timeout = 3000;
        request.Method = "HEAD";
        using(WebResponse response = request.GetResponse())
        {
            HttpWebResponse hRes = response as HttpWebResponse;
            if(hRes == null)
                throw new ArgumentException("Not an HTTP or HTTPS request"); // you may want to have this specifically handle e.g. FTP, but I'm just throwing an exception for now.
            return hRes.StatusCode / 100 == 2;
        }
    }
    catch (WebException) 
    {
        return false;
    }
}

Of course there are poor websites out there that return a 200 all the time and so on, but this is the best one can do. It assumes that in the case of a redirect you care about the ultimate target of the redirect (do you finally end up on a successful page or an error page), but if you care about the specific URI you could turn off automatic redirect following, and consider 3xx codes successful too.

Jon Hanna
thats pretty cool. I get a error that i can't apply "/" to operations code and int
Crash893
if i cast it as (int) it works
Crash893
Oops, yes. It should have a cast to int (the alternative is to test against every success possible type, but casting to int should be more future proof and proof against crazy non-standard-but-spirit-of-standard-compliant behaviour).
Jon Hanna
this is fine but it seems to only check if the domain is up not if i give it a full url www.whatever.com/page1.html for example
Crash893
@Crash893, no it does indeed check that, unless the server is telling porkies. What status code does the page give if it's not up?
Jon Hanna