【Win 10 应用开发】TCP通信过程
基于TCP协议的通信,估计大伙儿都不陌生的,以前玩.net或玩C++的时候应该玩得很多吧。现在老周简单介绍一下在RT中如何用。
TCP是基于连接的,所以,肯定有一方是监听者,通常称服务端或服务器,它负责接受连接请求,但不负责通信;接受连接后得到一个专用于通信的套接字。
1、new一个StreamSocketListener,它用于监听TCP连接。
2、处理StreamSocketListener实例的ConnectionReceived事件,当有新连接传入,会发生该事件,并可以获得用于通信的socket。
3、绑定本地结点。BindEndpointAsync绑定特定本机地址和端口(或服务,如果是蓝牙通信,就是服务名,大多数情况下是端口号)。BindServiceNameAsync方法绑定本地端号或服务,该方法不指定地址,即绑定本机所有地址,如果有需要,你可以指定绑定到哪张网卡。如果所指定的端口是空白字符串("",不能为null),就会自动选择一个随机端口进行绑定。要是绑定的是本地的随机端口,你可以从StreamSocketListener.Information的LocalPort属性中获取已绑定的端口。
4、在StreamSocketListener.ConnectionReceived事件的处理中,访问事件参数的Socket属性得到一个StreamSocket实例,然后你就可以用它来进行通信了。
5、当不需要时调用Dispose方法即可释放。
下面来练习一下。老周发现一个现象,UWP两个应用程序在同一台机器上不能连接,要用两台机器来测试,但在同一个应用中就可以本地测试。
不过,后来想想,其实也无妨,毕竟UWP是通用应用,如果服务器一个应用,客户一个应用,这样反而不合理了,因为这样用户就要安装两个应用,在通用平台而言不太好,把服务器和客户端都放在同一个应用中较好,让用户自行选择是作为服务器端还是客户端来运行。如果用户选择当前应用作为服务器,就开启监听;如果用户选择作为客户端运行,就允许其输入远程设备的IP和端口进行连接。
下面代码开启连接监听并绑定机地端口。
if (listener != null)
{
listener.ConnectionReceived -= OnConnReceived;
listener.Dispose();
listener = null;
} listener = new StreamSocketListener();
listener.ConnectionReceived += OnConnReceived;
await listener.BindServiceNameAsync("");
调用BindServiceNameAsync时传递的是空字符串的参数,表示让应用程序自动选择一个随机端口来监听。为了让客户端知道该连接哪个端口,可以把本地监听端口显示在界面上。
runPort.Text = listener.Information.LocalPort;
处理ConnectionReceived事件,如果接收到连接请求,就向客户端发送一条文本消息:“你好,我是你外公,我叫服务器。”。
private async void OnConnReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
// 获取用于通信的socket
StreamSocket socket = args.Socket;
// 向客户端发送字符串:
// 你好,我是你外公,我叫服务器。
using (DataWriter writer = new DataWriter(socket.OutputStream))
{
string content = "你好,我是你外公,我叫服务器。";
writer.UnicodeEncoding = UnicodeEncoding.Utf8; //注意
// 计算长度
uint len = writer.MeasureString(content);
// 写入长度
writer.WriteUInt32(len);
// 再写内容
writer.WriteString(content);
// 提交数据
await writer.StoreAsync();
}
// 这个socket不要了,扔掉
socket.Dispose();
}
前一文章中,老周给大伙介绍过DataWriter的作用,这时我们用得上,用来把字符串写入网络流。注意,应该设置UnicodeEncoding属性为Utf-8编码,这个编码比较通用,就不会出现乱码。
由于字符串的长度是可变的,客户端并不知道我们要发送的内容有多大,为了让接收者能够准确接收数据,应该先向流中写入数据长度,然后再写内容。接收方在读的时候,可以先读出长度,再读内容,因为表示长度的值是uint,它的值大小是固定的4个字节。
下面代码为客户端发起连接。
StreamSocket socket = new StreamSocket();
try
{
HostName svname = new HostName(txtIp.Text); // 连接
await socket.ConnectAsync(svname, txtPort.Text);
// 接收数据
DataReader reader = new DataReader(socket.InputStream);
reader.UnicodeEncoding = UnicodeEncoding.Utf8; //注意
// 长度
await reader.LoadAsync(sizeof(uint));
uint len = reader.ReadUInt32();
// 读内容
await reader.LoadAsync(len);
string msg = reader.ReadString(reader.UnconsumedBufferLength);
runRecMsg.Text = msg;
// 释放
reader.Dispose();
在读取接收到的数据时,用的是DataReader类,而且记住要统一编码utf-8,然后先加载4个字节,读出内容长度,再加载剩余的字节,最后读出字符串。
好,最后一步就是配置清单文件,打开清单文件,默认用设计器打开,切换到[功能]选项卡,勾选“Internet(客户端与服务器)”与“专用网络(客户端与服务器)”,而“Internet(客户端)”可以取消。

XML代码如下。
<Capabilities>
<Capability Name="internetClientServer" />
<Capability Name="privateNetworkClientServer" />
</Capabilities>
运行结果请看下面的艳图。

啊,今天的话题就扯到这里吧,改天再扯其他话题。
【Win 10 应用开发】TCP通信过程的更多相关文章
- 性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)
TCP通信过程 如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过 ...
- 【Win 10应用开发】认识一下UAP项目
Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- 【Win 10 应用开发】导入.pfx证书
这个功能其实并不常用,一般开发较少涉及到证书,不过,简单了解一下还是有必要的. 先来说说制作测试证书的方法,这里老周讲两种方法,可以生成用于测试的.pfx文件. 产生证书,大家都知道有个makecer ...
- 【Win 10应用开发】延迟共享
延迟共享是啥呢,这么说吧,就是在应用程序打开共享面板选择共享目标时,不会设置要共享的数据,而是等到共享目标请求数据时,才会发送数据,而且,延迟操作可以在后台进行. 这样说似乎过于抽象,最好的诠释方法, ...
- 【Win 10应用开发】Adaptive磁贴模板的XML文档结构
在若干天之前,老周给大家讲了Adaptive Toast通知的XML模板,所以相应地,今天老周给大家介绍一下Adaptive磁贴的新XML模板. 同样道理,你依旧可以使用8.1时候的磁贴模板,在win ...
- 【Win 10 应用开发】RTM版的UAP项目解剖
Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以前预览的时候是一样的,只是版本变成10240罢了,所以大家 ...
- 【Win 10 应用开发】在代码中加载文本资源
记得前一次,老周给大伙,不,小伙伴们介绍了如何填写 .resw 文件,并且在 XAML 中使用 x:Uid 标记来加载.也顺便给大伙儿分析了运行时是如何解析 .resw 文件的. 本来说好了,后续老周 ...
- 【Win 10 应用开发】Toast通知激活应用——前台&后台
老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎哟,这怎么回答呢,从短期来说,加入学生会有点用,至少可以娱乐一下,运气好的话, ...
随机推荐
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- Windows 7上执行Cake 报错原因是Powershell 版本问题
在Windows 7 SP1 电脑上执行Cake的的例子 http://cakebuild.net/docs/tutorials/getting-started ,运行./Build.ps1 报下面的 ...
- .NET Core的日志[2]:将日志输出到控制台
对于一个控制台应用,比如采用控制台应用作为宿主的ASP.NET Core应用,我们可以将记录的日志直接输出到控制台上.针对控制台的Logger是一个类型为ConsoleLogger的对象,Consol ...
- SQL Server-聚焦计算列持久化(二十一)
前言 上一节我们结束了Hash Match Aggregate和Stream Aggregate的讲解,本系列我们来讲讲关于SQL Server中的计算列问题,简短的内容,深入的理解,Always t ...
- Linux 添加新磁盘,在线扩充空间
CentOS 7开发环境中的home 目录空间满了,需要增加空间 到虚拟机上执行"ls /sys/class/scsi_host",然后重新扫描SCSI总线来添加设备.如右图.然后 ...
- 使用NUnit为游戏项目编写高质量单元测试的思考
0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...
- Java 时间类-Calendar、Date、LocalDate/LocalTime
1.Date 类 java.util.Date是一个"万能接口",它包含日期.时间,还有毫秒数,如果你只想用java.util.Date存储日期,或者只存储时间,那么,只有你知道哪 ...
- 开发者最爱的Firebug停止更新和维护
近日,Firebug团队在其官网上宣布,Firebug将不再继续开发和维护,并邀请大家使用Firefox的内置开发工具. Firebug最初是2006年1月由Joe Hewitt编写, ...
- ObserverPattern(观察者模式)
import java.util.ArrayList; import java.util.List; /** * 观察者模式 * @author TMAC-J * 牵一发而动全身来形容观察者模式在合适 ...
- HTML5笔记2——HTML5音/视频标签详解
音视频的发展史 早期:<embed>+<object>+文件 问题:不是所有浏览器都支持,而且embed不是标准. 现状:Realplay.window media.Quick ...