日期:2014-05-17  浏览次数:20889 次

新时尚Windows8开发(40):StreamSocket的使用
在Windows Store应用程序中使用Stram Socket与桌面客户端进行通信,一直没弄成功,总让俺觉得很震精,怎么会不成功呢。后来经过几回测试发现,原来是在DataReader那里出了问题,总算弄成了。

Stream Socket通常用于传输一些比较长的数据,如文件。但这里为了使演示变得更容易理解,我传输了一段字符。

首先,我们用WinForm做一个服务器端。界面不复杂,目的是侦听连接,收到传入的客户端连接后,向客户端发送一条字符串消息。

处理的逻辑代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace TestServerApp
{
    public partial class Form1 : Form
    {
        TcpListener m_Listener = null;//用于监听链接
        TcpClient m_Client = null;//传入的客户端
        public Form1()
        {
            InitializeComponent();
            this.btnStart.Enabled = true;
            this.btnStop.Enabled = false;
        }

        /// <summary>
        /// 向客户端发送字符串
        /// </summary>
        private void SendMessage(TcpClient client)
        {
            using (var stream = client.GetStream())
            {
                byte[] buffer = Encoding.UTF8.GetBytes("奔,不停地奔,奔向传说中的荒原;飞,不停地飞,飞向天空的那一端。");
                uint len = (uint)buffer.Length;
                // 先发送长度
                stream.Write(BitConverter.GetBytes(len), 0, sizeof(uint));
                // 再发送数据
                stream.Write(buffer, 0, buffer.Length);
                
            }
        }

        private async void btnStart_Click(object sender, EventArgs e)
        {
            if (this.m_Listener == null)
            {
                this.m_Listener = new TcpListener(IPAddress.Parse(this.txtAddr.Text), Convert.ToInt32(this.udPort.Value));
            }
            this.m_Listener.Start();
            this.lblMsg.Text = "监听已开始。";
            this.btnStart.Enabled = false;
            this.btnStop.Enabled = true;
            try
            {
                m_Client = await m_Listener.AcceptTcpClientAsync();
                SendMessage(m_Client);
            }
            catch (SocketException se)
            {
                this.lblMsg.Text = se.Message;
            }
            catch (Exception ex)
            {
                this.lblMsg.Text = ex.Message;
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            if (m_Listener != null)
            {
                m_Listener.Stop();
                this.lblMsg.Text = "监听已停止。";
            }
            this.btnStart.Enabled = true;
            this.btnStop.Enabled = false;
        }
    }
}

 

接着是Win8 App客户端。

因为我们要使用网络连接,在创建项目后,把开清单文件,切换到【功能】选项卡,把和网络连接有关的选项勾上。

 

打开主页MainPage的XAML代码编辑器(设计视图),简单布局一下界面。

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

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0" Margin="3">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <