与众不同 windows phone (46) - 8.0 通信: Socket, 其它-阿里云开发者社区

开发者社区> 杰克.陈> 正文

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

简介: 原文:与众不同 windows phone (46) - 8.0 通信: Socket, 其它 [源码下载] 与众不同 windows phone (46) - 8.0 通信: Socket, 其它 作者:webabcd介绍与众不同 windows phone 8.
+关注继续查看
原文:与众不同 windows phone (46) - 8.0 通信: Socket, 其它

[源码下载]


与众不同 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
[源码下载]

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9490 0
与众不同 windows phone (35) - 8.0 新的启动器: ShareMediaTask, SaveAppointmentTask, MapsTask, MapsDirectionsTask, MapDownloaderTask
原文:与众不同 windows phone (35) - 8.0 新的启动器: ShareMediaTask, SaveAppointmentTask, MapsTask, MapsDirectionsTask, MapDownloaderTask [源码下载] 与众不同 windows phone (35) - 8.
728 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10843 0
与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室
原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 作者:webabcd介绍与众不同 windows phone 7.
753 0
同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同
同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同
365 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13175 0
与众不同 windows phone (33) - Communication(通信)之源特定组播 SSM(Source Specific Multicast)
原文:与众不同 windows phone (33) - Communication(通信)之源特定组播 SSM(Source Specific Multicast) [索引页][源码下载] 与众不同 windows phone (33) - Communication(通信)之源特定组播 SSM...
737 0
与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件
原文:与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件 [源码下载] 与众不同 windows phone (37) - 8.
742 0
与众不同 windows phone (38) - 8.0 关联启动: 使用外部程序打开一个文件或URI, 关联指定的文件类型或协议
原文:与众不同 windows phone (38) - 8.0 关联启动: 使用外部程序打开一个文件或URI, 关联指定的文件类型或协议 [源码下载] 与众不同 windows phone (38) - 8.
769 0
与众不同 windows phone (24) - Input(输入)之软键盘类型, XNA 方式启动软键盘, UIElement 的 Touch 相关事件, 触摸涂鸦
原文:与众不同 windows phone (24) - Input(输入)之软键盘类型, XNA 方式启动软键盘, UIElement 的 Touch 相关事件, 触摸涂鸦 [索引页][源码下载] 与众不同 windows phone (24) - Input(输入)之软键盘类型, XNA 方式...
872 0
+关注
杰克.陈
一个安静的程序猿~
10427
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载