原文:与众不同 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, , 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);
}
} // 关闭 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(, ).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"), , );
_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(, 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
[源码下载]

与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)的更多相关文章

  1. C#实现任意源组播与特定源组播

    IP组播通信需要一个特殊的组播地址,IP组播地址是一组D类IP地址,范围从224.0.0.0 到 239.255.255.255.其中还有很多地址是为特殊的目的保留的.224.0.0.0到224.0. ...

  2. 与众不同 windows phone (33) - Communication(通信)之源特定组播 SSM(Source Specific Multicast)

    原文:与众不同 windows phone (33) - Communication(通信)之源特定组播 SSM(Source Specific Multicast) [索引页][源码下载] 与众不同 ...

  3. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  4. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  5. 与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信

    原文:与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信 [索引页][源码下载] 与众不同 windows phone (29) - Co ...

  6. 与众不同 windows phone (46) - 8.0 通信: Socket, 其它

    [源码下载] 与众不同 windows phone (46) - 8.0 通信: Socket, 其它 作者:webabcd 介绍与众不同 windows phone 8.0 之 通信 Socket ...

  7. 与众不同 windows phone 8.0 & 8.1 系列文章索引

    [源码下载] [与众不同 windows phone 7.5 (sdk 7.1) 系列文章索引] 与众不同 windows phone 8.0 & 8.1 系列文章索引 作者:webabcd ...

  8. 与众不同 windows phone (39) - 8.0 联系人和日历

    [源码下载] 与众不同 windows phone (39) - 8.0 联系人和日历 作者:webabcd 介绍与众不同 windows phone 8.0 之 联系人和日历 自定义联系人存储的增删 ...

  9. 与众不同 windows phone (44) - 8.0 位置和地图

    [源码下载] 与众不同 windows phone (44) - 8.0 位置和地图 作者:webabcd 介绍与众不同 windows phone 8.0 之 位置和地图 位置(GPS) - Loc ...

随机推荐

  1. Python中的循环与跳出

    --start-- for循环: for i in range(3): user_input = input("Your username:") passwd = int(inpu ...

  2. Java数据流格式转换

    1 字节流InputStream                  ->FileInputStreamOutputStream                 ->FileOutputSt ...

  3. 关于QT的系统总结(非常全面,非常好)

    源地址:http://www.cnblogs.com/wangqiguo/p/4625611.html 阅读目录 编译环境与开发流程 QT项目的构成及原理 QT中的布局 QT中的通用控件 QVaria ...

  4. 分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要)

    原文:分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要) XML文件 <?xml version="1.0"?> <student ...

  5. POJ 3090 Visible Lattice Points 欧拉函数

    链接:http://poj.org/problem?id=3090 题意:在坐标系中,从横纵坐标 0 ≤ x, y ≤ N中的点中选择点,而且这些点与(0,0)的连点不经过其它的点. 思路:显而易见, ...

  6. 基于JSP+SERVLET的新闻发布系统(一)

    本系统使用的是基于JSP+SERVLET+TOMCAT6 数据库使用的是MYSQL IDE是MYECLIPSE8.5,页面编辑使用的是百度的ueditor,比较适合咱国人 采用MVC模式,使用的关键技 ...

  7. Java 获取到配置文件信息

    Java程序将数据库或者服务器IP写入到代码中,难免缺少灵活性. 如果写入到配置文件,部署到不通服务器上,只需要修改配置文 件即可. Java怎么读取配置文件 /** * 获取到配置文件信息 * @p ...

  8. Windows Phone 8初学者开发的翻译终于过半

    从2013年7月19日开始,到2013年12月9日,一共花了143天时间完成了18篇Windows Phone 8初学者开发的翻译,还剩下17篇文章需要翻译,看到了完成的希望! I love Wind ...

  9. 基于visual Studio2013解决C语言竞赛题之1037数组求列和

          题目 解决代码及点评 /* 功能:已知有三个数组A,B,C,A为5行5列的二维数组,B.C为只有5个元素的一维数组,键盘输入数据的顺序如下: 23,45,6,1,- ...

  10. 用WebCollector制作一个爬取《知乎》并进行问题精准抽取的爬虫(JAVA)

    简单介绍: WebCollector是一个无须配置.便于二次开发的JAVA爬虫框架(内核),它提供精简的的API.仅仅需少量代码就可以实现一个功能强大的爬虫. 怎样将WebCollector导入项目请 ...