Skip to main content

Articles

Featured Products

Windows Mobile Developer Controls
Windows Mobile Developer Controls
Stay in touch using the DEVBUSS RSS feeds.
 

News

Windows Mobile Developer Controls
Windows Mobile Developer Controls

Determing Network Connectivity

Written by W.G. Ryan  [author's bio]  [read 27710 times]
Edited by Derek

Page 1 

Determing Network Connectivity

Barely a week goes by without a post or 10 on the various Compact Framework Newsgroups where someone doesn't inquire about network connectivity. Some people are trying to use the full SQL Client namespace which isn't very useful if you aren't connected to a network. Other's ask about invoking a web service in an effort to pull back some data, something else that's kind of sucky if you don't have a network connection. Then there are folks who are trying to move files back and forth from their device to the desktop, and want to have the ability to immediately detect when the device is cradled and show some sort of notification. All of these are fairly common tasks when dealing with PDA development and all of them share one thing in common, namely, the need to determine whether or not the device is cradled or not (I know, techincally you can grab data from a Web Service via GRPS, but assuming one doesn't, it's still a valid thing to inquire about.)

The following code snippet in Devbuzz's Code Snippets section shows how one might go about accomplishing this task:

 

Public Shared Function GotInternet() As Boolean
   Dim req As HttpWebRequest
   Dim res As HttpWebResponse
   Try req = CType(WebRequest.Create("http://www.devbuzz.com"), HttpWebRequest)
   res = CType(req.GetResponse(), HttpWebResponse) req.Abort()
   If res.StatusCode = HttpStatusCode.OK Then
      GotInternet = True
   End If
  Catch weberrt As WebException
     GotInternet = False
  Catch except As Exception
    GotInternet = False
   End Try
End Function

This solution is easy to use, easy to understand, and in most instance gets the job done. All you'd need to do is intermittently call this function via a timer or low priority background thread and you could keep track of whether or not you're connected thereby giving you app the ability to respond accordingly. (Whether or not you should opt for a multi-threaded solution over a timer based one is a whole different can of worms but the logic is the same with either approach).

But there some shortcomings to this approach. For one thing, we've got to remember that PDA's at their present state aren't exactly oozing resources like RAM and processor speed. So, if you polled frequently enough, you'd invariably raise quite a few exceptions when the device wasn't cradled and exceptions aren't the cheapest thing in the world. But a more serious issue might arise if you were using a Smart Phone or device that might need to call into the network at each request. As you can see, that could get ugly quite quickly. But what if you lost your internet connection ? If you have my cable modem service company (who's name coincidentally rhymes with BombBlast) that's a pretty common scenario. You'd end up with False Positives. If someone pulled out the desktop machine's network cable, it'd report a false positive as well (I know, if the desktop wasn't connected to the network then you don't actually have "Network Connectivity" but what we're ultimately trying to determine here is whether or not we are cradled. If our goal was solely to ascertain whether or not we had actual Internet Connectivity, then the approach I'm about to recommend won't work). Finally the web site in question might be down for maintenance or whatever else. In each instance, your device would think it wasn't cradled even though it was.

So how do you resolve this? In order to understand what we're about to do, you'll need some background info on what goes on behind the scenes when you 'cradle' the device. Upon cradling the device, the cradle and desktop machine morph into a new role, that of a network gateway. Now the device's IP Address is going to be something other than Home aka 127.0.0.1. This provides you the ability to infer (accurately) if the device is cradled by virtue of its IP Address. So any instance where IP Address != 127.0.0.1 accurately indicates your device is cradled and any instace where it is, means that it's not.

Now, let me emphasize something here. Just because your IP Address isn't 127.0.0.1 DOESN'T NECESSARILY mean you have internet connectivity. You may or may not, but you can't tell from this alone. However, you can tell from this alone if your device is cradled or not. Secondly, the code snippet above will port over directly to the full framework and you can use it from any desktop app to determine if you can hit the internet or not (provided of course that the web site you are sending requests to is up and running). However, if you use the code below, the logic will break because ActiveSync and the cradle aren't sitting in between your computer and the network but the code WILL compile. The assumption behind the logic no longer holds though and you don't have the benefit of a compiler barking at you to indicate that your logic isn't valid.

With that said, all we need to do is use the System.Net namespace and use DNS to determine the device's IP Address.

VB.NET:

Imports System.Net
#Region "Enums"
Public Enum CradleResult As Integer
     Cradled = 0
     Uncradled = 1
     WebException = 2
     OtherException = 3
End Enum
#End Region


'Class Definition here
Const Home as String = "127.0.0.1"
#Region "Functions"
Public Shared Function IsDeviceCradled() as CradleResult
Try
   Dim HostName as String = Dns.GetHostName()
   Dim IPHost as System.Net.IPHostEntry = Dns.GetHostByName(HostName)
   Dim DeviceIP as String = CType(IPHost.AddressList(0), String)
     If DeviceIP <> IPAddress.Parse(Home).ToString Then
       Return CradleResult.Cradled
     Else
       Return CradleResult.Uncradled
     End If

     Catch webEx as System.Net.WebException
       Return CradleResult.WebException
     Catch othEx as System.Exception
     Return CradleResult.OtherException
End Try

End Function
#End Region

C#

using System.Net;

public enum CradleResult : uint{cradled, uncradled, webException, otherException};

const string Home = "127.0.0.1";

#region "Functions"
public static CradleResult IsDeviceCradled(){
try{
string HostName = Dns.GetHostName();
System.Net.IPHostEntry IPHost = Dns.GetHostByName(HostName);
string DeviceIP = (string)IPHost.AddressList[0];
if(DeviceIP != IPAddress.Parse(Home).ToString()){
return CradleResult.Cradled;
}
else { return CradleResult.Uncradled;}
}
catch(System.Net.WebException webEx){
return CradleResult.WebException;
}
catch(System.Exception othEx){
return CradleResult.othException;
}
}
#endregion

So all we're really doing is using System.Net to determine out IP Address and respond accordingly. The same issue regarding using a timer or a background thread is present here, but that's a whole different matter.