zoukankan      html  css  js  c++  java
  • 与众不同 windows phone (46)

    [源码下载]


    与众不同 windows phone (46) - 8.0 通信: Socket, 其它



    作者:webabcd


    介绍
    与众不同 windows phone 8.0 之 通信

    • Socket Demo
    • 获取当前连接的信息
    • http rss odata socket bluetooth nfc voip winsock



    示例
    1、演示 socket tcp 的应用(本例既做服务端又做客户端)
    Communication/SocketDemo.xaml

    <phone:PhoneApplicationPage
        x:Class="Demo.Communication.SocketDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    
        <Grid Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <StackPanel>
                    <Button Name="btnStartListener" Content="start a socket listener" Click="btnStartListener_Click" />
                    <Button Name="btnConnectListener" Content="connect to the socket listener" Click="btnConnectListener_Click" Margin="0 10 0 0" />
                    <Button Name="btnSendData" Content="send data" Click="btnSendData_Click" Margin="0 10 0 0" />
                    <Button Name="btnCloseSocket" Content="close server socket and client socket" Click="btnCloseSocket_Click" Margin="0 10 0 0" />
                </StackPanel>
    
                <TextBlock Name="lblMsg" TextWrapping="Wrap" Margin="20 0 0 0" />
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>

    Communication/SocketDemo.xaml.cs

    /*
     * 演示 socket tcp 的应用(本例既做服务端又做客户端)
     * 
     * 通过 StreamSocketListener 实现 tcp 通信的服务端的 socket 监听
     * 通过 StreamSocket 实现 tcp 通信的客户端 socket
     * 
     * 注:需要在 manifest 中增加配置 <Capability Name="ID_CAP_NETWORKING" />
     * 
     * 
     * 另:
     * 本例完全摘自之前写的 win8 socket demo
     */
    
    using System;
    using System.Windows;
    using Microsoft.Phone.Controls;
    using Windows.Networking.Sockets;
    using Windows.Storage.Streams;
    using Windows.Networking;
    
    namespace Demo.Communication
    {
        public partial class SocketDemo : PhoneApplicationPage
        {
            /// <summary>
            /// 服务端 socket
            /// </summary>
            private StreamSocketListener _listener;
    
            /// <summary>
            /// 客户端 socket
            /// </summary>
            private StreamSocket _client;
    
            /// <summary>
            /// 客户端向服务端发送数据时的 DataWriter
            /// </summary>
            private DataWriter _writer;
    
            public SocketDemo()
            {
                this.InitializeComponent();
            }
    
            // 在服务端启动一个 socket 监听
            private async void btnStartListener_Click(object sender, RoutedEventArgs e)
            {
                // 实例化一个 socket 监听对象
                _listener = new StreamSocketListener();
                // 监听在接收到一个连接后所触发的事件
                _listener.ConnectionReceived += _listener_ConnectionReceived;
    
                try
                {
                    // 在指定的端口上启动 socket 监听
                    await _listener.BindServiceNameAsync("2211");
    
                    lblMsg.Text += "已经在本机的 2211 端口启动了 socket(tcp) 监听";
                    lblMsg.Text += Environment.NewLine;
    
                }
                catch (Exception ex)
                {
                    SocketErrorStatus errStatus = SocketError.GetStatus(ex.HResult);
    
                    lblMsg.Text += "errStatus: " + errStatus.ToString();
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
    
            // socket 监听接收到一个连接后
            async void _listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
            {
                // 实例化一个 DataReader,用于读取数据
                DataReader reader = new DataReader(args.Socket.InputStream);
    
                this.Dispatcher.BeginInvoke(delegate()
                {
                    lblMsg.Text += "服务端收到了来自: " + args.Socket.Information.RemoteHostName.RawName + ":" + args.Socket.Information.RemotePort + " 的 socket 连接";
                    lblMsg.Text += Environment.NewLine;
                });
    
                try
                {
                    while (true)
                    {
                        // 自定义协议(header|body):前4个字节代表实际数据的长度,之后的实际数据为一个字符串数据
    
                        // 读取 header
                        uint sizeFieldCount = await reader.LoadAsync(sizeof(uint));
                        if (sizeFieldCount != sizeof(uint))
                        {
                            // 在获取到合法数据之前,socket 关闭了
                            return;
                        }
    
                        // 读取 body
                        uint stringLength = reader.ReadUInt32();
                        uint actualStringLength = await reader.LoadAsync(stringLength);
                        if (stringLength != actualStringLength)
                        {
                            // 在获取到合法数据之前,socket 关闭了
                            return;
                        }
    
                        this.Dispatcher.BeginInvoke(delegate()
                        {
                            // 显示客户端发送过来的数据
                            lblMsg.Text += "接收到数据: " + reader.ReadString(actualStringLength);
                            lblMsg.Text += Environment.NewLine;
                        });
                    }
                }
                catch (Exception ex)
                {
                    this.Dispatcher.BeginInvoke(delegate()
                    {
                        SocketErrorStatus errStatus = SocketError.GetStatus(ex.HResult);
    
                        lblMsg.Text += "errStatus: " + errStatus.ToString();
                        lblMsg.Text += Environment.NewLine;
                        lblMsg.Text += ex.ToString();
                        lblMsg.Text += Environment.NewLine;
                    });
                }
            }
    
            // 创建一个客户端 socket,并连接到服务端 socket
            private async void btnConnectListener_Click(object sender, RoutedEventArgs e)
            {
                HostName hostName;
                try
                {
                    hostName = new HostName("127.0.0.1");
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
    
                    return;
                }
    
                // 实例化一个客户端 socket 对象
                _client = new StreamSocket();
    
                try
                {
                    // 连接到指定的服务端 socket
                    await _client.ConnectAsync(hostName, "2211");
    
                    lblMsg.Text += "已经连接上了 127.0.0.1:2211";
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    SocketErrorStatus errStatus = SocketError.GetStatus(ex.HResult);
    
                    lblMsg.Text += "errStatus: " + errStatus.ToString();
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
    
            // 从客户端 socket 发送一个字符串数据到服务端 socket
            private async void btnSendData_Click(object sender, RoutedEventArgs e)
            {
                // 实例化一个 DataWriter,用于发送数据
                if (_writer == null)
                    _writer = new DataWriter(_client.OutputStream);
    
                // 自定义协议(header|body):前4个字节代表实际数据的长度,之后的实际数据为一个字符串数据
    
                string data = "hello webabcd " + DateTime.Now.ToString("hh:mm:ss");
                _writer.WriteUInt32(_writer.MeasureString(data)); // 写 header 数据
                _writer.WriteString(data); // 写 body 数据
    
                try
                {
                    // 发送数据
                    await _writer.StoreAsync();
    
                    lblMsg.Text += "数据已发送: " + data;
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    SocketErrorStatus errStatus = SocketError.GetStatus(ex.HResult);
    
                    lblMsg.Text += "errStatus: " + errStatus.ToString();
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
    
            // 关闭客户端 socket 和服务端 socket
            private void btnCloseSocket_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    _writer.DetachStream(); // 分离 DataWriter 与 Stream 的关联
                    _writer.Dispose();
    
                    _client.Dispose();
                    _listener.Dispose();
    
                    lblMsg.Text += "服务端 socket 和客户端 socket 都关闭了";
                    lblMsg.Text += Environment.NewLine;
                }
                catch (Exception ex)
                {
                    lblMsg.Text += ex.ToString();
                    lblMsg.Text += Environment.NewLine;
                }
            }
        }
    }


    2、演示如何获取当前连接的信息
    Communication/ConnectionProfileDemo.xaml.cs

    /*
     * 演示如何获取当前连接的信息
     * 
     * 
     * 注:
     * 关于数据成本的判断参见:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj207005
     */
    
    using System;
    using System.Windows.Navigation;
    using Microsoft.Phone.Controls;
    using Windows.Networking.Connectivity;
    
    namespace Demo.Communication
    {
        public partial class ConnectionProfileDemo : PhoneApplicationPage
        {
            public ConnectionProfileDemo()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 获取当前的 Internet 连接信息
                ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile();
    
                /*
                 * 获取由 IANA(Internet Assigned Names Authority - Internet 编号分配管理机构) 定义的接口类型
                 *     1 - 其他类型的网络接口
                 *     6 - 以太网网络接口
                 *     9 - 标记环网络接口
                 *     23 - PPP 网络接口
                 *     24 - 软件环回网络接口
                 *     37 - ATM 网络接口
                 *     71 - IEEE 802.11 无线网络接口
                 *     131 - 隧道类型封装网络接口
                 *     144 - IEEE 1394 (Firewire) 高性能串行总线网络接口
                 */
                uint ianaInterfaceType = connectionProfile.NetworkAdapter.IanaInterfaceType;
                lblMsg.Text = "接口类型: " + ianaInterfaceType;
                lblMsg.Text += Environment.NewLine;
    
                ConnectionCost connectionCost = connectionProfile.GetConnectionCost();
    
                // 网络成本的类型: Unknown, Unrestricted(无限制), Fixed, Variable
                NetworkCostType networkCostType = connectionCost.NetworkCostType;
                lblMsg.Text += "网络成本的类型: " + networkCostType.ToString();
                lblMsg.Text += Environment.NewLine;
    
                lblMsg.Text += "是否接近了数据限制的阈值: " + connectionCost.ApproachingDataLimit;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "是否超过了数据限制的阈值: " + connectionCost.OverDataLimit;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "是否处于漫游网络(即本地提供商以外的网络): " + connectionCost.Roaming;
                
                base.OnNavigatedTo(e);
            }
        }
    }


    3、其它(http rss odata socket bluetooth nfc voip winsock)
    Communication/Other.xaml

    <phone:PhoneApplicationPage
        x:Class="Demo.Communication.Other"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d"
        shell:SystemTray.IsVisible="True">
    
        <Grid Background="Transparent">
            <StackPanel Orientation="Vertical">
    
                <TextBlock Name="lblMsg" TextWrapping="Wrap">
                    <Run>1、序列化, http, rss, socket 参见之前写的 win8 相关的文章即可</Run>
                    <LineBreak />
                    <Run>2、OData:参见:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/gg521146</Run>
                    <LineBreak />
                    <Run>3、蓝牙:参见:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj207007</Run>
                    <LineBreak />
                    <Run>4、NFC:参见:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj207060</Run>
                    <LineBreak />
                    <Run>5、VoIP:参见:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj206983, http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj207046, http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj553780</Run>
                    <LineBreak />
                    <Run>6、支持 Winsock API(socket 的本地 api),关于 wp8 支持的 Win32 API 参见:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj662956</Run>
                    <LineBreak />
                </TextBlock>
    
            </StackPanel>
        </Grid>
    
    </phone:PhoneApplicationPage>



    OK
    [源码下载]

  • 相关阅读:
    总结几种常见web攻击手段及其防御方式(转)
    使用Chrome DevTools的Timeline分析页面性能(转)
    Sublime Text 无法使用Package Control或插件安装失败的解决方法(转)
    typeScript笔记
    ProtoBuf.js – Protocol Buffers的Javascript实现(转)
    JS到JAVA反射
    cocos 优化方案相关参考
    PMP学习笔记 (二)
    PMP学习笔记 (一)
    CentOS7安装GLPI资产管理系统
  • 原文地址:https://www.cnblogs.com/webabcd/p/3516854.html
Copyright © 2011-2022 走看看