Windows 8 Store Apps学习(62) 通信: Socket TCP, Socket UDP2014-03-09 cnblogs webabcd介绍重新想象 Windows 8 Store Apps 之 通信Socket - Tcp DemoSocket - 实现一个自定义的 http serverSocket - Udp Demo示例1、演示 socket tcp 的应用(本例既做服务端又做客户端)Communication/Socket/TcpDemo.xaml
<Pagex: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个字节代表实际数据的长度,之后的实际数据为一个字符串数据// 读取 headeruint sizeFieldCount = await reader.LoadAsync(sizeof(uint));if (sizeFieldCount != sizeof(uint)){// 在获取到合法数据之前,socket 关闭了return;}// 读取 bodyuint 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,并连接到服务端 socketprivate 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{// 连接到指定的服务端 socketawait _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 发送一个字符串数据到服务端 socketprivate 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 和服务端 socketprivate 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;}}}}