winRT 网络通讯的一些问题

      开发winRT工程已经一周左右,框架已经搭建完成,但是发现网络通讯这块相比Windows Phone确实有较大变化,今天总结一下遇到的问题,普通的网络连接发送接收是没什么问题的,看看官方例子就可以解决,但是由于金融交易的功能必须采用SSL证书的安全网络通讯形式,所以关于SSL这块确实纠结了几天时间。

 

1,创建网络连接

/// <summary>
        /// 创建连接
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public async Task<NetworkStatusEnum> Connect(NetworkAddr address)
        {
            NetWorkState = NetworkStatusEnum.NotConnected;
            try
            {
                //创建连接
                await mSocket.ConnectAsync(new HostName(address.IP), address.NetPort.ToString());
                //连接成功
                NetWorkState = NetworkStatusEnum.Connected;

                BeginReceived();
              
            }
            catch(Exception ex)
            {
                NetWorkState = NetworkStatusEnum.ConnectedError;
                Debug.WriteLine("创建连接失败!=="+ex.Message);

            }



            return NetWorkState;
        }

创建连接为异步可等待方法,上层调用的时候一定要记得await,否则可能会遇到,连接没连上已经发送数据的情况。

2,连接的状态

由于StreamSocket没有连接状态属性,我们只能自定义一个枚举类型

    /// <summary>
    /// 网络状态枚举
    /// </summary>
    public enum NetworkStatusEnum
    {
        /// <summary>
        /// 已连接
        /// </summary>
        Connected,
        /// <summary>
        /// 未连接
        /// </summary>
        NotConnected,
        /// <summary>
        /// 连接失败
        /// </summary>
        ConnectedError,
        /// <summary>
        /// 无网络可用
        /// </summary>
        NetworkNotAvailable,
        /// <summary>
        /// 发送错误
        /// </summary>
        SendError,
        /// <summary>
        /// 接收错误
        /// </summary>
        ReceivedError
    }

在创建链接的时候可能会失败,这是一种常见情况,还有一种是在网络已经连接上,中间使用过程中服务器无法连接的情况就比较特殊,我们这里采用的是心跳包的方案。 客户端每10秒钟发个心跳包,服务端会反馈心跳包,保证链接通畅。

 

3,发送数据包

/// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<NetworkStatusEnum> Send(byte[] data)
        {
            if (null != mSocket)
            {

                if (mWriter == null)
                {
                    mWriter = new DataWriter(mSocket.OutputStream);
                }
                //把数据写入到发送流
                mWriter.WriteBytes(data);
                //异步发送
                try
                {

                    await mWriter.StoreAsync();
                    NetWorkState = NetworkStatusEnum.Connected;
                }
                catch (Exception ex)
                {
                    NetWorkState = NetworkStatusEnum.SendError;
                    Debug.WriteLine("发送数据失败!==" + ex.Message);

                }
                return NetWorkState;
            }

            return NetWorkState;
        }

 

4,接受数据包

/// <summary>
        /// 数据接受
        /// </summary>
        public async Task BeginReceived()
        {
           

            //绑定已连接的StreamSocket到DataReader
             mReader = new DataReader(mSocket.InputStream);
             mReader.InputStreamOptions = InputStreamOptions.Partial;
                while (isRun)
                {
                    try
                    {
                      
                        uint sizeFieldCount = await mReader.LoadAsync(16);

                        if (sizeFieldCount == 0)
                        {
                            continue;
                        }


                        byte[] tempByteArr = new byte[sizeFieldCount];
                        //将刚才reader读取到的数据填充到tempByteArr
                        mReader.ReadBytes(tempByteArr);
                        NetWorkState = NetworkStatusEnum.Connected;
                        PostPacket(tempByteArr);

                    }
                    catch(Exception ex)
                    {
                        NetWorkState = NetworkStatusEnum.ReceivedError;
                        Debug.WriteLine("接受数据失败!==" + ex.Message);
                        break;
                    }
                }
           
        }

接收的时候要注意一个设置,InputStreamOptions得设置为Partial,这样就可以不用等待服务端攒到一定字节再返回,否则会影响返回的即时性。

5,SSL证书连接

由于微软取消了本地证书的X.509的帮助类,所以没法解析此证书文件,现在可以使用三方的开源类库(bouncycastle)解析它,他支持SSL安全证书网络流。方便好用,关键是开源。

http://www.bouncycastle.org/csharp/

 

posted @ 2013-02-04 11:25  龙月  阅读(1973)  评论(5编辑  收藏  举报