在Windows Mobile中管理网络状态的最佳方法

我有一个.NET Compact Framework 3.5程序,用作“偶尔连接”的业务线(LOB)应用程序。 如果它可以看到在线Web服务,它将使用它进行数据访问,但如果网络连接丢失,它将使用本地缓存。

处理所有连接选项和状态更改的最佳方法是什么?

  • OpenNetCF的ConnectionManager类?
  • Microsoft.WindowsBile.State.SystemState?
  • API调用?

你如何理解WiFi,Cradle和GPRS之间的区别并使用最好的方法?

有人对此有任何指导吗?

我只是创建一个简单的共享类,我可以这样调用:

If MyConnectionClass.IsConnected then 'Do connected stuff Else 'Do local save End If 

然后我的所有实际业务类/函数都可以使用它来隐藏UI代码中的这种肮脏。

MyConnectionClass的IsConnected属性将具有以下内容:

 Public ReadOnly Property IsConnected As Boolean Get Try Dim HostName As String = Dns.GetHostName() Dim thisHost As IPHostEntry = Dns.GetHostByName(HostName) Dim thisIpAddr As String = thisHost.AddressList(0).ToString return (thisIpAddr <> Net.IPAddress.Parse("127.0.0.1").ToString()) Catch ex As Exception Return False End Try End Get End Property 

还建议您使用后台线程轮询连接状态,然后在状态更改时将事件激活回主应用程序线程。 这是详细的写作:

在.NET Compact Framework中测试和响应网络连接

编辑:

现在,对于GPRS支持:

如果您使用Web请求或Web服务,框架将为您处理连接。 如果您深入了解TCPClient或UDPClient,您需要使用Connection Manager API自己处理它,如下所示:

 public class GPRSConnection { const int S_OK = 0; const uint CONNMGR_PARAM_GUIDDESTNET = 0x1; const uint CONNMGR_FLAG_PROXY_HTTP = 0x1; const uint CONNMGR_PRIORITY_USERINTERACTIVE = 0x08000; const uint INFINITE = 0xffffffff; const uint CONNMGR_STATUS_CONNECTED = 0x10; static Hashtable ht = new Hashtable(); static GPRSConnection() { ManualResetEvent mre = new ManualResetEvent(false); mre.Handle = ConnMgrApiReadyEvent(); mre.WaitOne(); CloseHandle(mre.Handle); } ~GPRSConnection() { ReleaseAll(); } public static bool Setup(Uri url) { return Setup(url.ToString()); } public static bool Setup(string urlStr) { ConnectionInfo ci = new ConnectionInfo(); IntPtr phConnection = IntPtr.Zero; uint status = 0; if (ht[urlStr] != null) return true; if (ConnMgrMapURL(urlStr, ref ci.guidDestNet, IntPtr.Zero) != S_OK) return false; ci.cbSize = (uint) Marshal.SizeOf(ci); ci.dwParams = CONNMGR_PARAM_GUIDDESTNET; ci.dwFlags = CONNMGR_FLAG_PROXY_HTTP; ci.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE; ci.bExclusive = 0; ci.bDisabled = 0; ci.hWnd = IntPtr.Zero; ci.uMsg = 0; ci.lParam = 0; if (ConnMgrEstablishConnectionSync(ref ci, ref phConnection, INFINITE, ref status) != S_OK && status != CONNMGR_STATUS_CONNECTED) return false; ht[urlStr] = phConnection; return true; } public static bool Release(Uri url) { return Release(url.ToString()); } public static bool Release(string urlStr) { return Release(urlStr, true); } private static bool Release(string urlStr, bool removeNode) { bool res = true; IntPtr ph = IntPtr.Zero; if (ht[urlStr] == null) return true; ph = (IntPtr)ht[urlStr]; if (ConnMgrReleaseConnection(ph, 1) != S_OK) res = false; CloseHandle(ph); if (removeNode) ht.Remove(urlStr); return res; } public static void ReleaseAll() { foreach(DictionaryEntry de in ht) { Release((string)de.Key, false); } ht.Clear(); } [StructLayout(LayoutKind.Sequential)] public struct ConnectionInfo { public uint cbSize; public uint dwParams; public uint dwFlags; public uint dwPriority; public int bExclusive; public int bDisabled; public Guid guidDestNet; public IntPtr hWnd; public uint uMsg; public uint lParam; public uint ulMaxCost; public uint ulMinRcvBw; public uint ulMaxConnLatency; } [DllImport("cellcore.dll")] private static extern int ConnMgrMapURL(string pwszURL, ref Guid pguid, IntPtr pdwIndex); [DllImport("cellcore.dll")] private static extern int ConnMgrEstablishConnectionSync(ref ConnectionInfo ci, ref IntPtr phConnection, uint dwTimeout, ref uint pdwStatus); [DllImport("cellcore.dll")] private static extern IntPtr ConnMgrApiReadyEvent(); [DllImport("cellcore.dll")] private static extern int ConnMgrReleaseConnection(IntPtr hConnection, int bCache); [DllImport("coredll.dll")] private static extern int CloseHandle(IntPtr hObject); } 

要使用它,请执行以下操作:

 public void DoTcpConnection() { string url = "www.msn.com"; bool res = GPRSConnection.Setup("http://" + url + "/"); if (res) { TcpClient tc = new TcpClient(url, 80); NetworkStream ns = tc.GetStream(); byte[] buf = new byte[100]; ns.Write(buf, 0, 100); tc.Client.Shutdown(SocketShutdown.Both); ns.Close(); tc.Close(); MessageBox.Show("Wrote 100 bytes"); } else { MessageBox.Show("Connection establishment failed"); } } 

这是来自Anthony Wong的博客:

安东尼黄

请记住,您只需要更低级别的TCP或UDP内容。 HTTPRequests不需要这个。

如何在Microsoft.WindowsMo​​bile.Status命名空间中使用SystemState类? 当状态发生变化时,您可以监视系统的当前状态并获取通知。 有关一些代码,请参阅此帖

SystemState仅与连接状态有关。 您可以通过ConnectionManager使用特定连接。 我建议阅读这篇文章 。 如果您使用的是.NET Compact Framework 3.5,则会包含托管API。 您也可以使用OpenNetCF ConnectionManager。

我尝试编写移动应用程序,因此他们甚至不知道有涉及的网络。 我在本地保留了足够好的validation数据,然后将事务写入本地队列,该队列在连接时清除; 队列读取器包括一个计时器,用于在未连接时重试。 队列消息是双向的,因此也可以提供本地刷新。 基本消息队列模式。

这允许我以最简单的方式处理网络连接,使用高度可移植的基本套接字打开/关闭/读/写/ ioctl逻辑; 并且您的连接不需要持续任何重要的时间。 (我不想想在过去几年中与所有MS架构变体保持同步需要什么 – 这仍然没有解决恕我直言。)

我发现Microsoft.WindowsMo​​bile.State.SystemState报告的网络连接不可靠。 这是6.0及更早。 我没有进行详尽的测试,但是当它说没有连接的时候就被抛弃了。