與眾不同 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
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM