Windows Mobile GPRS拨号上网及连接通道选择

随着大家对数据传书安全性的重视,越来越多的用户在建设自己企业的无线解决方案时,选择APN作为数据传输通道,是应用程序采用自己专有的通道进行数据传出,这样,其他非企业内部用户便无法访问企业架构的服务器,大大提供企业无线方案本身的安全性。

     专有通道是不可以连接到Internet公网上的。而用户本身,花了几K的MONEY,不可能只用来办公,用户对设备连接公网具有强烈的需求。然而,在技术角度,很难将应用程序绑定到固定的通道上,特别是使用C#语言连接WEB SERVICE进行通讯时,该程序便解决了这个问题。

     当然,如果使用底层API很容易达到这个效果,但,当前做Windows Mobile开发的人,很少有即懂得EVC又懂得C#的人,如果您刚好是这种人才,您不需要对本人的文章进行任何参考,可以直接封装底层API中的四个方法为一个DLL,然后进行调用。

     在底层API中,包含以下四个方法

[DllImport("cellcore.dll", EntryPoint = "ConnMgrReleaseConnection", SetLastError = true)]
        internal static extern int ConnMgrReleaseConnection(IntPtr hConnection, int bCache);

        [DllImport("cellcore.dll", EntryPoint = "ConnMgrEstablishConnection", SetLastError = true)]
        internal static extern int ConnMgrEstablishConnection(IntPtr pConnInfo, out IntPtr phConnection);

        [DllImport("cellcore.dll", EntryPoint = "ConnMgrEstablishConnectionSync", SetLastError = true)]
        internal static extern int ConnMgrEstablishConnectionSync(IntPtr pConnInfo, out IntPtr phConnection, int dwTimeout, out int dwStatus);

        [DllImport("cellcore.dll", EntryPoint = "ConnMgrEnumDestinations", SetLastError = true)]
        internal static extern int ConnMgrEnumDestinations(int nIndex, IntPtr pDestinationInfo);

        [DllImport("cellcore.dll", EntryPoint = "ConnMgrMapURL", SetLastError = true)]
        internal static extern int ConnMgrMapURL(string pwszUrl, ref Guid pguid, ref int pdwIndex);

        [DllImport("cellcore.dll", EntryPoint = "ConnMgrConnectionStatus", SetLastError = true)]
        internal static extern int ConnMgrConnectionStatus(IntPtr hConnection, out int pdwStatus);

这四个方法的具体含义,这里不做详细介绍,大家可以在MSDN中查到,如果查不到,可以找高人请教一下。

本模块首先要导入这四个方法,如上面的代码片段,然后就是对连接对象DestinationInfo的封装了,该对象的原型,这里不再列举,下面为封装好的结构

public class DestinationInfo
    {
        private object syncRoot = new object();

        /// <summary>
        /// Size of the DestinationInfo structure in unmanaged memory.
        /// </summary>
        public static int NativeSize = 272;

        /// <summary>
        /// The destination's GUID identifier.
        /// </summary>
        public Guid guid;

        /// <summary>
        /// The destination's description.
        /// </summary>
        public string description = null;

        /// <summary>
        /// Default constructor.
        /// </summary>
        public DestinationInfo()
        {
        }
        public override string ToString()
        {
            return description;
        }
        /// <summary>
        /// Creates a new instance of DestinationInfo at the specific memory address.
        /// </summary>
        /// <param name="baseAddr">Memory address where the DestinationInfo object should be created.</param>
        public DestinationInfo(IntPtr baseAddr)
        {
            lock (syncRoot)
            {
                guid = new Guid(MarshalEx.ReadByteArray(baseAddr, 0, 16));
                description = MarshalEx.PtrToStringUni(baseAddr, 16, 256);
            }
        }
    }

接下来封装ConnectionInfo结构

internal struct ConnectionInfo
    {
        public int cbSize;
        public int dwParams;
        public int dwFlags;
        public int dwPriority;
        public bool bExclusive;
        public bool bDisabled;
        public Guid guidDestNet;
        public IntPtr hWnd;
        public int uMsg;
        public int lParam;
        int ulMaxCost;
        int ulMinRcvBw;
        int ulMaxConnLatency;
        internal IntPtr handle;

        /// <summary>
        /// Writes the ConnectionInfo data to unmanaged memory.
        /// </summary>
        /// <returns>A pointer to the unmanaged memory block storing the ConnectionInfo data</returns>  
        public IntPtr ToPtr()
        {
            //    ulMaxCost = 0;
            //    ulMinRcvBw = 0;
            //    ulMaxConnLatency = 0;

            IntPtr p = MarshalEx.AllocHLocal((uint)Marshal.SizeOf(typeof(ConnectionInfo)));

            MarshalEx.WriteInt32(p, 0, this.cbSize);
            MarshalEx.WriteInt32(p, 4, this.dwParams);
            MarshalEx.WriteInt32(p, 8, this.dwFlags);
            MarshalEx.WriteInt32(p, 12, this.dwPriority);
            MarshalEx.WriteBool(p, 16, this.bExclusive);
            MarshalEx.WriteBool(p, 20, this.bDisabled);
            MarshalEx.WriteByteArray(p, 24, this.guidDestNet.ToByteArray());
            MarshalEx.WriteIntPtr(p, 40, this.hWnd);
            MarshalEx.WriteInt32(p, 44, this.uMsg);
            MarshalEx.WriteInt32(p, 48, this.lParam);
            MarshalEx.WriteInt32(p, 52, this.ulMaxCost);
            MarshalEx.WriteInt32(p, 56, this.ulMinRcvBw);
            MarshalEx.WriteInt32(p, 60, this.ulMaxConnLatency);
           // Marshal.WriteByte(p,
            handle = p;
            return p;
        }

        /// <summary>
        /// Disposes of the ConnectionInfo object.
        /// </summary>
        public void Dispose()
        {
            this.hWnd = IntPtr.Zero;
            if (handle != IntPtr.Zero)
                MarshalEx.FreeHLocal(handle);
        }
    };

这样,所有的准备工作都已经做好,就剩下封装一个对外的方法了,起名为ConnectionManager,代码如下

该对象负责对外提供枚举连接个数、选择某个连接进行连接、断开当前连接,以及在连接开始、连接成功、连接断开、连接报错时提供对外的事件通知,由于代码过多,在这里不粘贴。OK,一起准备完成。

在WINDOWS MOBILE 2003SE,Windows Mobile5.0 以及Windows Mobile6.0中测试通过。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页