稳扎稳打Silverlight(54) - 4.0通信之对UDP协议的支持: 通过 UdpAnySourceMulticastClIEnt 实现 ASM(Any Source Multicast),即“任意源多播”
作者: webabcd
介绍
Silverlight 4.0 对 UDP 协议的支持:
UdpAnySourceMulticastClIEnt - 一个发送信息到多播组并从任意源接收多播信息的客户端,即 ASM 客户端
在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
演示如何通过 UdpAnySourceMulticastClIEnt 实现 ASM
1、服务端
Form1.cs
代码 // 启动多播的安全策略服务
private voID LaunchMulticastPolicyServer()
{
/*
* Silverlight 程序加入多播组之前,会通过 UDP 端口 9430 发送初始消息到多播组,然后服务端返回相应的安全策略(详见文档)
* 为了方便下发安全策略,可以引用 Microsoft.Silverlight.PolicyServers.dll 程序集,其封装了相关的方法
*/
// 本例的安全策略配置结果为:授权通过 UDP 端口 3003 问多播组 224.0.0.1,授权通过 UDP 端口 3006 问多播组 224.0.0.1
MulticastPolicyConfiguration config = new MulticastPolicyConfiguration();
config.AnySourceConfiguration.Add( " * " , new MulticastResource(IPAddress.Parse( " 224.0.0.1 " ), 3006 )); // 配置 ASM 的安全策略
MulticastPolicyServer server = new MulticastPolicyServer(config);
server.Start();
ShowMessage( " 多播的安全策略服务已启动 " );
}
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;
}
}
}
UdpAnySourceMulticastChannel.cs 代码 /*
* 通过 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 - 发出的信息是否需要传给自己
*
* 本例为一个通过 UdpAnySourceMulticastClIEnt 实现 ASM 客户端的帮助类
*/
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 UdpAnySourceMulticastChannel : Idisposable
{
private UdpAnySourceMulticastClIEnt _clIEnt;
// 接收信息的缓冲区
private byte [] _buffer;
// 此客户端是否加入了多播组
private bool _isJoined;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="groupAddress"> 多播组地址 </param>
/// <param name="port"> 客户端端口 </param>
/// <param name="maxMessageSize"> 接收信息的缓冲区大小 </param>
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 );
}
}
public voID Close()
{
_isJoined = false ;
OnClosing();
dispose();
}
/// <summary>
/// 发送信息到多播组,即发送信息到多播组内的所有成员
/// </summary>
public voID Send( string msg)
{
if (_isJoined)
{
byte [] data = EnCoding.UTF8.GetBytes(msg);
_clIEnt.BeginSendToGroup(data, data.Length,
result =>
{
_clIEnt.EndSendToGroup(result);
}, null );
}
}
/// <summary>
/// 从多播组接收信息,即接收多播组内所有成员发送的信息
/// </summary>
private voID Receive()
{
if (_isJoined)
{
Array.Clear(_buffer, _buffer.Length);
_clIEnt.BeginReceiveFromGroup(_buffer, _buffer.Length,
result =>
{
IPEndPoint source;
_clIEnt.EndReceiveFromGroup(result, out source);
Deployment.Current.dispatcher.BeginInvoke(
() =>
{
OnReceived(source, _buffer);
Receive();
});
}, null );
}
}
public voID dispose()
{
if (_clIEnt != null )
_clIEnt.dispose();
}
}
}
UdpAnySourceMulticastClIEntDemo.xaml 代码 < navigation:Page x:Class ="Silverlight40.Communication.UdpAnySourceMulticastClIEntDemo"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/Expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation ="clr-namespace:System.windows.Controls;assembly=System.windows.Controls.Navigation"
Title ="UdpAnySourceMulticastClIEntDemo Page" >
< GrID x:name ="LayoutRoot" >
< GrID.ColumnDeFinitions >
< ColumnDeFinition WIDth ="80" />
< ColumnDeFinition WIDth ="*" />
< ColumnDeFinition WIDth ="60" />
</ GrID.ColumnDeFinitions >
< GrID.RowDeFinitions >
< RowDeFinition Height ="*" />
< RowDeFinition Height ="40" />
</ GrID.RowDeFinitions >
< ListBox name ="lstAllMsg" GrID.ColumnSpan ="3" margin ="6" />
< TextBox name ="txtUsername" GrID.Row ="1" GrID.Column ="0" margin ="6" />
< TextBox name ="txtSendMsg" GrID.Row ="1" GrID.Column ="1" textwrapPing ="Wrap" margin ="6" KeyDown ="txtMsg_KeyDown" />
< button name ="btnSend" GrID.Row ="1" GrID.Column ="2" margin ="6" Content ="发送" Click ="btnSend_Click" />
</ GrID >
</ navigation:Page >
UdpAnySourceMulticastClIEntDemo.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 System.windows.Navigation;
namespace Silverlight40.Communication
{
public partial class UdpAnySourceMulticastClIEntDemo : Page
{
private UdpAnySourceMulticastChannel _channel;
public UdpAnySourceMulticastClIEntDemo()
{
InitializeComponent();
}
protected overrIDe voID OnNavigatedTo(NavigationEventArgs e)
{
txtUsername.Text = " 匿名 " + new Random().Next( 1000 , 9999 ).ToString();
_channel = new UdpAnySourceMulticastChannel(IPAddress.Parse( " 224.0.0.1 " ), 3006 , 2048 );
_channel.opening += new EventHandler(_channel_opening);
_channel.Received += new EventHandler < UdpPacketEventArgs > (_channel_Received);
_channel.Closing += new EventHandler(_channel_Closing);
Application.Current.Exit += new EventHandler(Current_Exit);
_channel.open();
}
voID _channel_opening( object sender, EventArgs e)
{
_channel.Send( string .Format( " {0}: 进来了 - [{1}] " , txtUsername.Text, DateTime.Now.ToString( " HH:mm:ss " )));
}
voID _channel_Received( object sender, UdpPacketEventArgs e)
{
// 因为已经指定了接收信息的缓冲区大小是 2048 ,所以如果信息不够 2048 个字节的的话,空白处均为“ ”
string message = string .Format( " {0} - 来自:{1} " , e.Message.TrimEnd( ' ' 0 voID ), e.source.ToString());
lstAllMsg.Items.Insert( _channel_Closing( , message);
}
object string .Format( sender, EventArgs e)
{
_channel.Send( " {0}: 离开了 - [{1}] " , DateTime.Now.ToString( " HH:mm:ss " voID Current_Exit( )));
}
object private sender, EventArgs e)
{
_channel.dispose();
}
voID btnSend_Click( object private sender, RoutedEventArgs e)
{
SendMsg();
}
voID txtMsg_KeyDown( object if (e.Key sender, KeyEventArgs e)
{
== private Key.Enter)
SendMsg();
}
voID string .Format( SendMsg()
{
_channel.Send( " {0}: {1} - [{2}] " , txtSendMsg.Text, DateTime.Now.ToString( " HH:mm:ss " = )));
txtSendMsg.Text "" ;
}
}
}
OK
[源码下载] 总结
以上是内存溢出为你收集整理的稳扎稳打Silverlight(54) - 4.0通信之对UDP协议的支持: 通过 UdpAnySourceMulticastClient 实现 ASM(Any Source Multicast),即全部内容,希望文章能够帮你解决稳扎稳打Silverlight(54) - 4.0通信之对UDP协议的支持: 通过 UdpAnySourceMulticastClient 实现 ASM(Any Source Multicast),即所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)