Communication(通訊)之任意源組播 ASM(Any Source Multicast)
介紹
與眾不同 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(); } } }