WEB开发网
开发学院WEB开发ASP.NET 稳扎稳打Silverlight(55) - 4.0通信之对UDP协议的... 阅读

稳扎稳打Silverlight(55) - 4.0通信之对UDP协议的支持:“源特定多播”

 2010-10-12 12:29:58 来源:WEB开发网   
核心提示: 2、客户端UdpPacketEventArgs.cs代码using System;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using Sy

2、客户端

UdpPacketEventArgs.cs

代码

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;

namespace Silverlight40.Communication
{
    public class UdpPacketEventArgs : EventArgs
    {
        // UDP 包的内容
        public string Message { get; set; }
        // UDP 包的来源的 IPEndPoint
        public IPEndPoint Source { get; set; }

        public UdpPacketEventArgs(byte[] data, IPEndPoint source)
        {
            this.Message = System.Text.Encoding.UTF8.GetString(data, 0, data.Length);
            this.Source = source;
        }
    }
}

UdpSingleSourceMulticastChannel.cs

代码

/*
 * 通过 UdpSingleSourceMulticastClient 实现 SSM(Source Specific Multicast),即“源特定多播”
 * 多播组基于 IGMP(Internet Group Management Protocol),即“Internet组管理协议”
 *
 * UdpSingleSourceMulticastClient - 一个从单一源接收多播信息的客户端,即 SSM 客户端
 *     BeginJoinGroup(), EndJoinGroup() - 加入“源”的异步方法
 *     BeginReceiveFromSource(), EndReceiveFromSource() - 从“源”接收信息的异步方法
 *     BeginSendToSource(), EndSendToSource() - 发送信息到“源”的异步方法
 *     ReceiveBufferSize - 接收信息的缓冲区大小
 *     SendBufferSize - 发送信息的缓冲区大小
 *    
 * 本例为一个通过 UdpSingleSourceMulticastClient 实现 SSM 客户端的帮助类
 */

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 Silverlight40.Communication
{
    public class UdpSingleSourceMulticastChannel : IDisposable
    {
        // 多播源的端口
        private int _serverPort = 3004;

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

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sourceAddress">“源”的地址</param>
        /// <param name="groupAddress">多播组的地址</param>
        /// <param name="port">客户端端口</param>
        /// <param name="maxMessageSize">接收信息的缓冲区大小</param>
        public UdpSingleSourceMulticastChannel(IPAddress sourceAddress, IPAddress groupAddress, int port, int maxMessageSize)
        {
            _sourceAddress = sourceAddress;
            _buffer = new byte[maxMessageSize];
            // 实例化 SSM 客户端,需要指定的参数为:多播源的地址;多播组的地址;客户端端口
            _client = new UdpSingleSourceMulticastClient(sourceAddress, 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);
            }
        }

        public void Close()
        {
            _isJoined = false;
            OnClosing();
            Dispose();
        }

        /// <summary>
        /// 发送信息到“源”
        /// </summary>
        public void Send(string msg)
        {
            if (_isJoined)
            {
                byte[] data = Encoding.UTF8.GetBytes(msg);

                // 需要指定多播源的端口
                _client.BeginSendToSource(data, 0, data.Length, _serverPort,
                    result =>
                    {
                        _client.EndSendToSource(result);
                    }, null);
            }
        }

        /// <summary>
        /// 接收从“源”发过来的广播信息
        /// </summary>
        private void Receive()
        {
            if (_isJoined)
            {
                Array.Clear(_buffer, 0, _buffer.Length);

                _client.BeginReceiveFromSource(_buffer, 0, _buffer.Length,
                    result =>
                    {
                        int sourcePort;
                        // 接收到广播信息后,可获取到“源”的端口
                        _client.EndReceiveFromSource(result, out sourcePort);
                        Deployment.Current.Dispatcher.BeginInvoke(
                            () =>
                            {
                                OnReceived(new IPEndPoint(_sourceAddress, sourcePort), _buffer);
                                Receive();
                            });
                    }, null);
            }
        }

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

上一页  1 2 3 4  下一页

Tags:稳扎稳打 Silverlight 通信

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接