【Win 10 应用开发】UDP广播

我们知道,对于UDP协议的通信,除了可以用来聊天外,可以发送广播数据。只要向广播地址的某个端口发送数据就可以进行广播,子网中只要监听该端口的socket就能收到广播消息。

最简单的方法就是向255.255.255.255发送消息,这样就可以在本地网络中广播了,由于路由器不转发对该地址所发送的内容,所以只能用于本地网络。但这已经够用了,至少连接到同一个路由器的设备都能收到消息。

 

下面,咱们就来演示一下,如何进行广播。

先看接收端的实现。

RT库API提供了一个名为DatagramSocket的类,就是用来实现UDP通信的。对于数据接收者,处理过程如下:

1、new一个实例。

2、处理MessageReceived事件,只要有新的消息收到,就会引发该事件。

3、调用BindServiceNameAsync方法绑定一个本地端口,只要发送到该端口的数据都会被接收;或者调用BindEndpointAsync方法绑定本地结点,此方法需要明确指定一个本机地址。

4、在MessageReceived事件的处理中,通过事件参数可以得到一些基本信息。比如,LocalAddress本机地址,RemotePort远程端口,RemoteAddress远程主机地址。

 

具体如下面代码。

        private async void OnMsgReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
        {
            string remoteaddr = args.RemoteAddress.DisplayName;
            DataReader reader = args.GetDataReader();
            reader.UnicodeEncoding = UnicodeEncoding.Utf8;
            // 读长度
            uint len = reader.ReadUInt32();
            // 读内容
            string msg = reader.ReadString(reader.UnconsumedBufferLength);

            ……
        }

调用事件参数的GetDataStream方法可以得到输入流,用来读取接收到的数据。更好用的是通过GetDataReader方法,直接能得到一个DataReader实例,这样你就可以直接读取需要的内容了。

不过呢,通过GetDataReader方法得到的DataReader对象不知道是不是经过特殊处理了,在读取前不需要调用LoadAsync方法来加载数据了,GetDataReader方法返回的DataReader的UnconsumedBufferLength属性默认就是大于0,即数据已自动加载到Reader中了,我们直接就可以读了。

 

 

随后,再看看如何实现广播消息的发送端。

这个就更TNND简单了,直接把消息发给255.255.255.255就行了,可以从IpAddress类的Broardcast字段得到。

            using (DatagramSocket socket = new DatagramSocket())
            {
                // 广播地址 255.255.255.255
                HostName broardaddr = new HostName(IPAddress.Broadcast.ToString());
                IOutputStream outstream = await socket.GetOutputStreamAsync(broardaddr, "9000");
                DataWriter writer = new DataWriter(outstream);
                // 设置编码格式
                writer.UnicodeEncoding = UnicodeEncoding.Utf8;
                // 处理字符串长度
                uint len = writer.MeasureString(content);
                // 写入长度
                writer.WriteUInt32(len);
                // 写入内容
                writer.WriteString(content);
                // 提交
                await writer.StoreAsync();
                // 释放
                writer.Dispose();
            }

实例化socket后,调用GetOutputStreamAsync方法,并指定目标地址和端口,就可以直接得到一个IOutputStream,表示输出流,向这个流写入数据就可以发送了。

可以通过DataWriter类来简单完成,由于这里发的是字符串,长度不确定,故要先发送长度,再发内容,以便接收方可以确定内容长度。

 

 

测试的时候,最好多弄几台设备来试,我就用笔记本、山寨板、手机三台设备来测试。哦,对了,在手机上运行很简单,用USB连上,直接运行就可以了。平板上测试与远程调试一样,先在板子上安装VS远程调试工具,因为平板就是一台电脑,所以操作和远程调试一样。

 

以下是测试结果:

 

示例代码下载

 

posted @ 2016-03-21 18:45  东邪独孤  阅读(2945)  评论(3编辑  收藏  举报