Windows 8 Store Apps学习(62) 通信: Socket TCP, Socket UDP

介绍

重新想象 Windows 8 Store Apps 之 通信

Socket - Tcp Demo

Socket - 实现一个自定义的 http server

Socket - Udp Demo

示例

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

Communication/Socket/TcpDemo.xaml

<Page
    x:Class="XamlDemo.Communication.Socket.TcpDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.Communication.Socket"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="120 0 0 0" Orientation="Horizontal">

            <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" FontSize="14.667" TextWrapping="Wrap" Margin="20 0 0 0" />

        </StackPanel>
    </Grid>
</Page>

Communication/Socket/TcpDemo.xaml.cs

/*
 * 演示 socket tcp 的应用(本例既做服务端又做客户端)
 *
 * 通过 StreamSocketListener 实现 tcp 通信的服务端的 socket 监听
 * 通过 StreamSocket 实现 tcp 通信的客户端 socket
 *
 * 注:需要在 Package.appxmanifest 中增加配置 <Capability 

Name="privateNetworkClientServer" />
 */

using System;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace XamlDemo.Communication.Socket
{
    public sealed partial class TcpDemo : Page
    {
        /// <summary>
        /// 服务端 socket
        /// </summary>
        private StreamSocketListener _listener;

        /// <summary>
        /// 客户端 socket
        /// </summary>
        private StreamSocket _client;

        /// <summary>
        /// 客户端向服务端发送数据时的 DataWriter
        /// </summary>
        private DataWriter _writer;

        public TcpDemo()
        {
            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);

            await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                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;
                    }

                    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        // 显示客户端发送过来的数据
                        lblMsg.Text += "接收到数据: " + reader.ReadString(actualStringLength);
                        lblMsg.Text += Environment.NewLine;
                    });
                }
            }
            catch (Exception ex)
            {
                var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    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;
            }
        }
    }
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索客户端
, socket
, 数据
, text
, tostring
, environment
, readuint16()
windows socket
,以便于您获取更多的相关知识。

时间: 2024-11-05 06:25:36

Windows 8 Store Apps学习(62) 通信: Socket TCP, Socket UDP的相关文章

Windows 8 Store Apps学习(63) 通信: WebSocket

介绍 重新想象 Windows 8 Store Apps 之 通信 Socket - 与 WebSocket 服务端做 Text 通信 Socket - 与 WebSocket 服务端做 Stream(Binary) 通信 示例 WebSocket 的服务端 WebServer/WebSocketServer.ashx.cs /* * WebSocket 协议的服务端 * * 需要在 iis 启用 WebSocket 协议:控制面板 -> 程序和功能 -> 启用或关闭 Windows 功能 -

Windows 8 Store Apps学习(61) 通信: http, oauth

介绍 重新想象 Windows 8 Store Apps 之 通信 HttpClient 概述 http get string http get stream http post string http post stream OAuth 2.0 验证的客户端 示例 用于演示 http 通信的服务端 WebServer/HttpDemo.aspx.cs /* * 用于响应 http 请求 */ using System; using System.IO; using System.Threadi

Windows 8 Store Apps学习(60) 通信: 获取网络信息, 序列化和反序列化

介绍 重新想象 Windows 8 Store Apps 之 通信 获取网络信息 序列化 - json 序列化 - xml 序列化 - rss atom 示例 1.演示如何获取网络的相关信息 Communication/NetworkInfo.xaml.cs /* * 演示如何获取网络的相关信息 */ using System; using System.Collections.Generic; using Windows.Networking.Connectivity; using Windo

Windows 8 Store Apps学习(68) 后台任务:控制通道(ControlChannel)

介绍 重新想象 Windows 8 Store Apps 之 后台任务 控制通道(ControlChannel) 示例 1.客户端与服务端做 ControlChannel 通信的关键代码 ControlChannelHelper/AppContext.cs /* * 本例通过全局静态变量来实现 app 与 task 的信息共享,以便后台任务可以获取到 app 中的相关信息 * * 注: * 也可以通过 Windows.ApplicationModel.Core.CoreApplication.P

Windows 8 Store Apps学习(66) 后台任务: 下载和上传

介绍 重新想象 Windows 8 Store Apps 之 后台任务 后台下载任务 后台上传任务 示例 扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知 BackgroundTask/TransferModel.cs /* * 扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知 */ using System; using System.ComponentModel; usin

Windows 8 Store Apps学习(41) 打印

介绍 重新想象 Windows 8 Store Apps 之 打印 示例 1.需要打印的文档 Print/PrintPage.xaml <Page x:Class="XamlDemo.Print.PrintPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xam

Windows 8 Store Apps学习(21) 动画: ThemeTransition(过渡效果)

介绍 重新想象 Windows 8 Store Apps 之 动画 ThemeTransition 的概述 EntranceThemeTransition - 页面间跳转时的过渡效果 ContentThemeTransition - 内容改变时的过渡效果 RepositionThemeTransition - 位置改变时的过渡效果 PopupThemeTransition - 弹出时的过渡效果 AddDeleteThemeTransition - 添加项或删除项时的过渡效果 ReorderThe

Windows 8 Store Apps学习(39) 契约: Share Contract

介绍 重新想象 Windows 8 Store Apps 之 契约 Share Contract - 右侧边栏称之为 Charm,其 中的"共享"称之为 Share Contract 示例 1.演示如何开发共享源 Contracts/ShareContract/ShareSource.xaml <Page x:Class="XamlDemo.Contracts.ShareContract.ShareSource" xmlns="http://sche

Windows 8 Store Apps学习(71)

作者:webabcd 介绍 重新想象 Windows 8 Store Apps 之 其它 C# 中调用 Windows Runtime Component(C++) 让 Windows Runtime Component(C++) 作为代理以调用 DLL(C++) 通过 C++ 和 D3D 获取屏幕分辨率 示例 一.演示如何在 C# 中调用 Windows Runtime Component(C++),以及 Windows Runtime Component(C++) 如何作为代理调用 DLL(