与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)

简介: 原文:与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)[索引页][源码下载] 与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any ...
原文: 与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)

[索引页]
[源码下载]


与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)



作者:webabcd


介绍
与众不同 windows phone 7.5 (sdk 7.1) 之通信

  • 实现“任意源多播” - ASM(Any Source Multicast)



示例
实现 ASM 信道
UdpAnySourceMulticastChannel.cs

/*
 * 实现一个 ASM 信道(即 ASM 帮助类),供外部调用
 * 
 * 
 * 通过 UdpAnySourceMulticastClient 实现 ASM(Any Source Multicast),即“任意源多播”
 * 多播组基于 IGMP(Internet Group Management Protocol),即“Internet组管理协议”
 * 
 * UdpAnySourceMulticastClient - 一个发送信息到多播组并从任意源接收多播信息的客户端,即 ASM 客户端
 *     BeginJoinGroup(), EndJoinGroup() - 加入多播组的异步方法
 *     BeginReceiveFromGroup(), EndReceiveFromGroup() - 从多播组接收信息的异步方法(可以理解为接收多播组内所有成员发送的信息)
 *     BeginSendToGroup(), EndSendToGroup() - 发送信息到多播组的异步方法(可以理解为发送信息到多播组内的全部成员)
 *     ReceiveBufferSize - 接收信息的缓冲区大小
 *     SendBufferSize - 发送信息的缓冲区大小
 *     
 *     BeginSendTo(), EndSendTo() - 发送信息到指定目标的异步方法
 *     BlockSource() - 阻止指定源,以便不再接收该源发来的信息
 *     UnblockSource() - 取消阻止指定源
 *     MulticastLoopback - 发出的信息是否需要传给自己
 * 
 */

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Text;
using System.Net.Sockets;

namespace Demo.Communication.SocketClient
{
    public class UdpAnySourceMulticastChannel : IDisposable
    {
        // ASM 客户端
        private UdpAnySourceMulticastClient _client;

        // 接收信息的缓冲区
        private byte[] _buffer;
        // 此客户端是否加入了多播组
        private bool _isJoined;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="groupAddress">多播组地址</param>
        /// <param name="port">多播组的端口</param>
        /// <param name="maxMessageSize">接收信息的缓冲区大小</param>
        /// <remarks>
        /// 注:udp 报文(Datagram)的最大长度为 65535(包括报文头)
        /// </remarks>
        public UdpAnySourceMulticastChannel(IPAddress groupAddress, int port, int maxMessageSize)
        {
            _buffer = new byte[maxMessageSize];
            // 实例化 ASM 客户端,需要指定的参数为:多播组地址;多播组的端口
            _client = new UdpAnySourceMulticastClient(groupAddress, port);
        }

        // 收到多播信息后触发的事件
        public event EventHandler<UdpPacketEventArgs> Received;
        private void OnReceived(IPEndPoint source, byte[] data)
        {
            var handler = Received;
            if (handler != null)
                handler(this, new UdpPacketEventArgs(data, source));
        }

        // 加入多播组后触发的事件
        public event EventHandler Opening;
        private void OnOpening()
        {
            var handler = Opening;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        // 断开多播组后触发的事件
        public event EventHandler Closing;
        private void OnClosing()
        {
            var handler = Closing;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        /// <summary>
        /// 加入多播组
        /// </summary>
        public void Open()
        {
            if (!_isJoined)
            {
                _client.BeginJoinGroup(
                    result =>
                    {
                        _client.EndJoinGroup(result);
                        _isJoined = true;
                        Deployment.Current.Dispatcher.BeginInvoke(
                            () =>
                            {
                                OnOpening();
                                Receive();
                            });
                    }, null);
            }
        }

        /// <summary>
        /// 发送信息到多播组,即发送信息到多播组内的所有成员
        /// </summary>
        public void Send(string msg)
        {
            if (_isJoined)
            {
                byte[] data = Encoding.UTF8.GetBytes(msg);

                _client.BeginSendToGroup(data, 0, data.Length,
                    result =>
                    {
                        _client.EndSendToGroup(result);
                    }, null);
            }
        }

        /// <summary>
        /// 从多播组接收信息,即接收多播组内所有成员发送的信息
        /// </summary>
        private void Receive()
        {
            if (_isJoined)
            {
                Array.Clear(_buffer, 0, _buffer.Length);

                _client.BeginReceiveFromGroup(_buffer, 0, _buffer.Length,
                    result =>
                    {
                        IPEndPoint source;
                        _client.EndReceiveFromGroup(result, out source);
                        Deployment.Current.Dispatcher.BeginInvoke(
                            () =>
                            {
                                OnReceived(source, _buffer);
                                Receive();
                            });
                    }, null);
            }
        }

        // 关闭 ASM 信道
        public void Close()
        {
            _isJoined = false;
            OnClosing();
            Dispose();
        }

        public void Dispose()
        {
            if (_client != null)
                _client.Dispose();
        }
    }
}


演示 ASM
AnySourceMulticast.xaml

<phone:PhoneApplicationPage 
    x:Class="Demo.Communication.SocketClient.AnySourceMulticast"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <StackPanel HorizontalAlignment="Left">

            <ListBox Name="lstAllMsg" MaxHeight="400" />
            <TextBox x:Name="txtName" />
            <TextBox x:Name="txtInput" KeyDown="txtInput_KeyDown" />
            <Button x:Name="btnSend" Content="发送" Click="btnSend_Click" />

        </StackPanel>        
    </Grid>

</phone:PhoneApplicationPage>

AnySourceMulticast.xaml.cs

/*
 * 用于演示 ASM
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

using System.Windows.Navigation;

namespace Demo.Communication.SocketClient
{
    public partial class AnySourceMulticast : PhoneApplicationPage
    {
        // 实例化自定义的 ASM 信道
        private UdpAnySourceMulticastChannel _channel;

        public AnySourceMulticast()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            txtName.Text = "匿名" + new Random().Next(1000, 9999).ToString();

            // 多播组地址是必须介于 224.0.0.0 到 239.255.255.255 之间的 IP 地址,其中范围介于 224.0.0.0 到 224.0.0.255 之间的多播地址是保留多播地址
            // 比如:224.0.0.0 是基址,224.0.0.1 是代表同一个物理网络中所有系统的多播组地址,而 224.0.0.2 代表同一个物理网络中的所有路由器
            _channel = new UdpAnySourceMulticastChannel(IPAddress.Parse("224.0.1.1"), 3368, 2048); 
            _channel.Opening += new EventHandler(_channel_Opening);
            _channel.Received += new EventHandler<UdpPacketEventArgs>(_channel_Received);
            _channel.Closing += new EventHandler(_channel_Closing);

            _channel.Open();

            // 需要的使用,应该调用 Close()
            // _channel.Close();
        }

        void _channel_Opening(object sender, EventArgs e)
        {
            _channel.Send(string.Format("{0}: 进来了 - [{1}]", txtName.Text, DateTime.Now.ToString("HH:mm:ss")));
        }

        void _channel_Received(object sender, UdpPacketEventArgs e)
        {
            // 因为已经指定了接收信息的缓冲区大小是 2048 ,所以如果信息不够 2048 个字节的的话,空白处均为空字节“\0”
            string message = string.Format("{0} - 来自:{1}", e.Message.TrimEnd('\0'), e.Source.ToString()); 
            lstAllMsg.Items.Insert(0, message); 
        }

        void _channel_Closing(object sender, EventArgs e)
        {
            _channel.Send(string.Format("{0}: 离开了 - [{1}]", txtName.Text, DateTime.Now.ToString("HH:mm:ss")));
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            SendMsg();
        }

        private void txtInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                SendMsg();
                this.Focus();
            }
        }

        private void SendMsg()
        {
            _channel.Send(string.Format("{0}: {1} - [{2}]", txtName.Text, txtInput.Text, DateTime.Now.ToString("HH:mm:ss")));
            txtInput.Text = "";
        }
    }
}



OK
[源码下载]

目录
相关文章
|
8月前
|
监控 编译器 Windows
Qt5实现Windows平台串口通信
Qt5实现Windows平台串口通信
|
SQL 弹性计算 网络协议
ECS使用体验报告(windows sever22,tcp通信)
搭建在云服务器ECS的Windows系统的门禁系统服务器的使用体验报告,包括sql数据库及端口问题解决方法。
ECS使用体验报告(windows sever22,tcp通信)
|
NoSQL 关系型数据库 MySQL
Windows10环境下制作SpringBoot项目的Docker镜像以及与宿主机上MySQL、Redis进行桥接通信
Windows10环境下制作SpringBoot项目的Docker镜像以及与宿主机上MySQL、Redis进行桥接通信
879 0
Windows10环境下制作SpringBoot项目的Docker镜像以及与宿主机上MySQL、Redis进行桥接通信
|
Android开发 iOS开发 Windows
Windows Phone 寿终正寝了,这些经典机型你还记得吗?
不久前,随着最后一家WP手机厂商惠普宣布取消今后Windows Phone的研发计划,以及微软官方声明对WP8.1系统今后所有升级维护的终止,WP手机,作为曾经和安卓手机、苹果手机并驾齐驱的三大智能手机之一,正式寿终正寝。
2141 0
Windows Phone 寿终正寝了,这些经典机型你还记得吗?
|
XML 开发框架 前端开发
Windows Phone快速入门需掌握哪些能力
在此之前,先普及下Windows Phone的概念和开发工具的介绍。 Windows Phone是微软公司开发的手机操作系统,它将微软旗下的Xbox Live游戏、Xbox Music音乐与独特的视频体验集成至手机中。2012年6月21日,微软正式发布Windows Phone 8,采用和Windows 8相同的Windows NT内核,同时也针对市场的Windows Phone 7.5发布Windows Phone 7.8。
431 0
Windows Phone快速入门需掌握哪些能力
|
移动开发 Android开发 开发者
Windows Phone 8.1 新功能汇总 开发者预览版开放下载
在Build 2014大会上,微软正式发布了传闻已久的Windows Phone 8.1系统,所有的Windows Phone 8手机都可以升级,微软这次可谓是十分厚道。虽然并非迭代升级,但WP 8.1还是拥有很多重大更新,对于微软进一步完善移动平台拥有积极的意义。下面,就一起来了解一下WP 8.1的主要新特性。
500 0
Windows Phone 8.1 新功能汇总 开发者预览版开放下载
|
编解码 前端开发 JavaScript
Windows Phone 下开发 LBS 应用
基于位置的服务(Location Based Service,LBS),它是通过电信移动运营商的无线电通讯网络(如GSM网、CDMA网)或外部定位方式(如GPS)获取移动终端用户的位置信息(地理坐标,或大地坐标),在GIS(Geographic Information System,地理信息系统)平台的支持下,为用户提供相应服务的一种增值业务。
505 0
|
Windows 开发工具 IDE
【终极解决方案】为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。
原文:【终极解决方案】为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。
4463 0
|
Linux 开发工具 Python
Ansible Windows通信(转载)
一、前言 近期打算搞搞自动部署,因为是windows服务器,一些工具和系统支持都不是太好。最后发现ansible比较火,最重要的是他支持windows。本文主要就ansible 在windows使用环境搭建过程分享。
1302 0