c# - 在 Windows Mobile 中管理网络状态的最佳方式

标签 c# windows-mobile compact-framework

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

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

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

您如何理解 WiFi、通讯座和 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

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

Testing for and responding to network connections in the .NET Compact Framework

编辑:

现在,对于 GPRS 支持:

如果您使用网络请求或网络服务,框架将为您处理连接。如果您更深入地研究 TCPClient 或 UDPClient,您需要自己使用连接管理器 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 的博客:

Anthony Wong

请记住,您只需要将它用于较低级别的 TCP 或 UDP 内容。 HTTPRequests 不需要这个。

关于c# - 在 Windows Mobile 中管理网络状态的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/715318/

相关文章:

c# - 撇号导致查询问题

c# - 正则表达式提取属性值

c++ - 如何在 Windows Mobile 6 上获得 "busy wheel"?

c# - 将多个内阁文件捆绑在一起? (适用于 Windows 移动设备)

c# - 如何从 Windows CE 设备 (Compact Framework) 发送电子邮件?

compact-framework - .NET CF 2.0:在具有背景透明度的图像上绘制PNG

javascript - 按钮单击事件后更新 UpdatePanel

c# - 是否可以在 EF Code First 实体上禁用更新/删除?

c# - 如何将我的 .net WinForms 应用程序转换为 Windows 10 Mobile?

c# - 使用 C# 以编程方式重启 Windows Mobile 6.x 设备