WinCE、Windows Mobile GPRS连接类

     在做手机应用程序开发的时候,我们经常需要手动建立GPRS连接,下面我提供一个经过简单改动过的GPRS连接类。

     这个类核心的代码,在网上都可以找到,我只是在这个基础上,进行了简单的封装,让他可以在后台自动监视连接,在连接断开的时候,可以自动建立,让我们在做业务逻辑的时候,可以不必去管GPRS连接着一块。

/// <summary>
/// GPRS自动连接服务
/// </summary>
public class ConnectionBLL
{
    private static ConnectionBLL _ConnectionBLL = null;
    private bool _autoConnect = false;
    private int _interval = 30000;
    private ConnectState _connectState;

    private ConnectionBLL()
    {
    }

    public static ConnectionBLL Instance
    {
        get
        {
            if (_ConnectionBLL == null)
            {
                lock (typeof(ConnectionBLL))
                {
                    if (_ConnectionBLL == null)
                    {
                        _ConnectionBLL = new ConnectionBLL();
                    }
                }
            }
            return _ConnectionBLL;
        }
    }
    /// <summary>
    /// 连接状态
    /// </summary>
    public ConnectState ConnectState
    {
        get { return _connectState; }
    }
    /// <summary>
    /// 是否自动连接
    /// </summary>
    public bool AutoConnect
    {
        get { return _autoConnect; }
    }

    /// <summary>
    /// 监听频率
    /// </summary>
    public int Interval
    {
        get { return _interval; }
        set { _interval = value; }
    }

    const int S_OK = 0;
    const uint CONNMGR_PARAM_GUIDDESTNET = 0x1;
    const uint CONNMGR_PRIORITY_USERINTERACTIVE = 0x08000;
    const uint INFINITE = 0xffffffff;
    const uint CONNMGR_STATUS_CONNECTED = 0x10;
    const int CONNMGR_MAX_DESC = 128;    // @constdefine Max size of a network description

    const int CONNMGR_FLAG_PROXY_HTTP = 0x1; // @constdefine HTTP Proxy supported
    const int CONNMGR_FLAG_PROXY_WAP = 0x2; // @constdefine WAP Proxy (gateway) supported
    const int CONNMGR_FLAG_PROXY_SOCKS4 = 0x4; // @constdefine SOCKS4 Proxy supported
    const int CONNMGR_FLAG_PROXY_SOCKS5 = 0x8; // @constdefine SOCKS5 Proxy supported

    const UInt16 IDC_WAIT = 32514;
    const UInt16 IDC_ARROW = 32512;

    private IntPtr m_hConnection = IntPtr.Zero;

    public enum ConnMgrStatus
    {
        AuthenticationFailed = 0x2b,
        Connected = 0x10,
        ConnectionCanceled = 0x22,
        ConnectionDisabled = 0x23,
        ConnectionFailed = 0x21,
        ConnectionLinkFailed = 0x2a,
        Disconnected = 0x20,
        ExclusiveConflict = 40,
        NoPathToDestination = 0x24,
        NoPathWithProperty = 0x2c,
        NoResources = 0x29,
        PhoneOff = 0x27,
        Suspended = 0x11,
        Unknown = 0,
        WaitingConnection = 0x40,
        WaitingConnectionAbort = 0x81,
        WaitingDisconnection = 0x80,
        WaitingForNetwork = 0x42,
        WaitingForPath = 0x25,
        WaitingForPhone = 0x26,
        WaitingForResource = 0x41
    }

    public ConnectionBLL()
    {
    }

    ~ConnectionBLL()
    {
        ReleaseConnection();
    }

    /// <summary>
    /// 开始连接
    /// </summary>
    public void Start()
    {
        try
        {
            if (!_autoConnect)
            {
                _autoConnect = true;
                ThreadPool.QueueUserWorkItem(new WaitCallback(Connect));
            }
        }
        catch
        {
        }
    }

    /// <summary>
    /// 停止
    /// </summary>
    public void Stop()
    {
        try
        {
            _autoConnect = false;
            this.ReleaseConnection();
            _connectState = ConnectState.DisConnect;
            _ConnectionBLL = null;
        }
        catch { }
    }

    /// <summary>
    /// 连接
    /// </summary>
    private void Connect(object obj)
    {
        while (this.AutoConnect)
        {
            uint status = 0;
            bool result = false;
            if (m_hConnection != IntPtr.Zero)
            {
                result = WaitForConnected(10, ref status);
            }
            if (!result)
            {
                _connectState = ConnectState.DisConnect;
                //枚举连接
                List<CONNMGR_DESTINATION_INFO> lst = EnumConnDestinations();

                for (int i = 0; i < lst.Count; i++)
                {
                    string str = lst[i].Description;
                    if (str.ToUpper().IndexOf("CMNET") > -1 || str.ToUpper().IndexOf("CMWAP") > -1)
                    {
                        if (EstablishConnection((uint)i))
                        {
                            _connectState = ConnectState.Connected;
                            break;
                        }
                    }
                }
            }
            else
            {
                _connectState = ConnectState.Connected;
            }
            Thread.Sleep(_interval);
        }
    }

    /// <summary>
    /// 枚举网络标识符信息
    /// </summary>
    /// <param name="lstNetIdentifiers"></param>
    public List<CONNMGR_DESTINATION_INFO> EnumConnDestinations()
    {
        List<CONNMGR_DESTINATION_INFO> lstNetIdentifiers = new List<CONNMGR_DESTINATION_INFO>();
        // 得到网络列表
        for (uint dwEnumIndex = 0; ; dwEnumIndex++)
        {
            CONNMGR_DESTINATION_INFO networkDestInfo = new CONNMGR_DESTINATION_INFO();

            if (ConnMgrEnumDestinations((int)dwEnumIndex, ref networkDestInfo) != 0)
            {
                break;
            }
            lstNetIdentifiers.Add(networkDestInfo);
        }

        return lstNetIdentifiers;
    }

    /// <summary>
    /// 建立连接
    /// </summary>
    /// <param name="nIndex"></param>
    /// <returns></returns>
    public bool EstablishConnection(uint nIndex)
    {
        ReleaseConnection();
        // 得到正确的连接信息
        CONNMGR_DESTINATION_INFO DestInfo = new CONNMGR_DESTINATION_INFO();
        int hResult = ConnMgrEnumDestinations((int)nIndex, ref DestInfo);

        if (hResult >= 0)
        {
            // 初始化连接结构
            CONNMGR_CONNECTIONINFO ConnInfo = new CONNMGR_CONNECTIONINFO();

            ConnInfo.cbSize = (uint)Marshal.SizeOf(ConnInfo);
            ConnInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
            ConnInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP | CONNMGR_FLAG_PROXY_WAP | CONNMGR_FLAG_PROXY_SOCKS4 | CONNMGR_FLAG_PROXY_SOCKS5;
            ConnInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
            ConnInfo.guidDestNet = DestInfo.DestID;
            ConnInfo.bExclusive = 1;
            ConnInfo.bDisabled = 0;

            uint dwStatus = 0;
            hResult = ConnMgrEstablishConnectionSync(ref ConnInfo, ref m_hConnection, 10 * 1000, ref dwStatus);
            if (hResult < 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        return false;
    }
    /// <summary>
    /// 连接状态
    /// </summary>
    /// <param name="nTimeoutSec"></param>
    /// <param name="pdwStatus"></param>
    /// <returns></returns>
    public bool WaitForConnected(int nTimeoutSec, ref uint pdwStatus)
    {
        uint dwStartTime = GetTickCount();
        bool bRet = false;

        while (GetTickCount() - dwStartTime < (uint)nTimeoutSec * 1000)
        {
            if (m_hConnection.ToInt32() != 0)
            {
                uint dwStatus = 0;
                int hr = ConnMgrConnectionStatus(m_hConnection, ref dwStatus);
                if (dwStatus != 0) pdwStatus = dwStatus;
                if (hr >= 0)
                {
                    if (dwStatus == CONNMGR_STATUS_CONNECTED)
                    {
                        bRet = true;
                        break;
                    }
                }
            }
            Thread.Sleep(100);
        }

        return bRet;
    }

    /// <summary>
    /// 释放所有连接
    /// </summary>
    public void ReleaseConnection()
    {

        if (m_hConnection.ToInt32() != 0)
        {
            ConnMgrReleaseConnection(m_hConnection, 0);
            m_hConnection = IntPtr.Zero;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct CONNMGR_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;
    }

    /// <summary>
    /// 此结构的内容对应:注册表中:
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct CONNMGR_DESTINATION_INFO
    {
        public GUID DestID;  // @field GUID associated with network
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CONNMGR_MAX_DESC)]
        public string Description;  // @field Description of network
        public int Secure; // @field Is it OK to allow multi-homing on the network
    }

    public struct GUID
    {          // size is 16
        public uint Data1;
        public UInt16 Data2;
        public UInt16 Data3;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Data4;
    }

    [DllImport("coredll.dll")]
    public static extern uint GetTickCount();

    [DllImport("coredll.dll")]
    public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

    [DllImport("cellcore.dll")]
    public static extern int ConnMgrMapURL(string pwszURL, ref GUID pguid, ref uint pdwIndex);

    [DllImport("cellcore.dll")]
    public static extern int ConnMgrEstablishConnectionSync(ref CONNMGR_CONNECTIONINFO ci, ref IntPtr phConnection, uint dwTimeout, ref uint pdwStatus);

    [DllImport("cellcore.dll")]
    private static extern IntPtr ConnMgrApiReadyEvent();

    [DllImport("cellcore.dll")]
    public static extern int ConnMgrReleaseConnection(IntPtr hConnection, int bCache);

    [DllImport("cellcore.dll")]
    public static extern int ConnMgrEnumDestinations(int nIndex, ref CONNMGR_DESTINATION_INFO pDestInfo);

    [DllImport("cellcore.dll")]
    public static extern int ConnMgrConnectionStatus(IntPtr hConnection,    // @parm Handle to connection, returned from ConnMgrEstablishConnection
        ref uint pdwStatus       // @parm Returns current connection status, one of CONNMGR_STATUS_*
        );

    [DllImport("coredll.dll")]
    private static extern int CloseHandle(IntPtr hObject);
}

/// <summary>
/// 连接状态
/// </summary>
public enum ConnectState
{
    /// <summary>
    /// 断开
    /// </summary>
    DisConnect = 0,
    /// <summary>
    /// 已连接
    /// </summary>
    Connected = 2
}

注意:为了加快连接速度,这里指定了连接移动的CMNET和CMWAP,可以根据需要修改,也可以不指定。

posted @ 2011-05-27 11:21  HOH  阅读(654)  评论(0编辑  收藏  举报