• Windows Phone学习笔记(9) — — 多播套接字


      本次我们来做一个多播套接字的示例。首先是页面的效果图。

    页面由一个ListBox、一个文本框和按钮构成。代码如下:

    View Code
        <!--LayoutRoot 是包含所有页面内容的根网格-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel 包含应用程序的名称和页标题-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="BasicUDPMulticastClient" 
                           Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="messages" Margin="9,-7,0,0" 
                           Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel - 在此处放置其他内容-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="500"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <ListBox x:Name="lbLog" Height="500" 
                         BorderBrush="{StaticResource PhoneForegroundBrush}" BorderThickness="5" 
                         Background="{StaticResource PhoneDisabledBrush}" />
                <StackPanel Grid.Row="1" Orientation="Horizontal">
                    <TextBlock Text="Text To Send" VerticalAlignment="Center"/>
                    <TextBox x:Name="txtInput" Width="200"/>
                    <Button x:Name="btnSend" Width="150" Content="Send" Click="btnSend_Click"/>
                </StackPanel>
            </Grid>
        </Grid>

    我们通过Send按钮的单击事件把数据发送到多播组:

            private void btnSend_Click(object sender, RoutedEventArgs e)
            {
                if (!String.IsNullOrWhiteSpace(txtInput.Text))
                {
                    Send(txtInput.Text);
                }
            }

    下面是向ListBox控件显示发送和接收数据的消息记录:

    View Code
            private void Log(string message, bool isOutgoing)
            {
                if (string.IsNullOrWhiteSpace(message.Trim('\0')))
                    return;
    
                Deployment.Current.Dispatcher.BeginInvoke(
                () =>
                {
                    string direction = (isOutgoing) ? ">> " : "<< ";
                    string timestamp = DateTime.Now.ToString("HH:mm:ss");
                    message = timestamp + direction + message;
                    lbLog.Items.Add(message);
    
                    lbLog.ScrollIntoView(message);
                });
    
            }

    MainPage.xaml.cs文件的顶部声明一下几个变量:

    View Code
            // 多播组加入的地址。
            // 地址的范围必须在从224.0.0.0到239.255.255.255之间
            private const string GROUP_ADDRESS = "224.0.1.1";
    
            //在多播组上通信的端口
            private const int GROUP_PORT = 52274;
    
            //从任何来源接收多播流量的客户端
            UdpAnySourceMulticastClient _client = null;
    
            //如果我们确实已经加入了组播组,则为true,否则为false
            bool _joined = false;
    
            //缓冲传入的数据
            private byte[] _receiveBuffer;
    
            //最大的消息通信数量
            private const int MAX_MESSAGE_SIZE = 512;

    这里用到了UdpAnySourceMulticastClient类,UdpAnySourceMulticastClient封装了通过 UDP 与多播组通信所需的逻辑。

    View Code
            /// <summary>
            /// 重写OnNavigatedTo方法
            /// </summary>
            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
    
                //创建一个新的UdpAnySourceMulticastClient实例和加入这个多播组。
                Join();
            }
    
    
            /// <summary>
            /// 创建一个新的UdpAnySourceMulticastClient实例和加入这个多播组。
            /// </summary>
            private void Join()
            {
                //初始化接收缓冲区
                _receiveBuffer = new byte[MAX_MESSAGE_SIZE];
    
                //创建UdpAnySourceMulticastClient实例使用定义的组地址和组端口常量。 
                //UdpAnySourceMulticastClient是一个客户端接收机的多播流量从任何来源,也被称为任何源多播(ASM)
                _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT);
    
                //请求加入该多播组。
                _client.BeginJoinGroup(
                    result =>
                    {
                        //完成加入
                        _client.EndJoinGroup(result);
    
                        //这个MulticastLoopback属性控制你是否收到多播包你发送到多播组
                        _client.MulticastLoopback = true;
    
                        //设置一个标志,指示我们现在已经加入多播组
                        _joined = true;
    
                        // 让别人知道我们已经加入了发送消息到一个组。
                        Send("Joined the group");
    
                        //从组中等待数据。这是一个异步进程不会阻碍UI进程
                        Receive();
                    }, null);
            }

    之后是多播组数据的发送和接收:

    View Code
            /// <summary>
            /// 发送特定消息到多播组。
            /// </summary>
            /// <param name="message">要发送的信息</param>
            private void Send(string message)
            {
                //如果你已经加入到这个组中,尝试发送
                if (_joined)
                {
                    byte[] data = Encoding.UTF8.GetBytes(message);
                    _client.BeginSendToGroup(data, 0, data.Length,
                        result =>
                        {
                            _client.EndSendToGroup(result);
    
                            //我们发送的日志
                            Log(message, true);
    
                        },null);
                }
                else
                {
                    Log("Message was not sent since you are not joined to the group", true);
                }
            }
    
    
            /// <summary>
            /// 接收数据组和进行日志记录
            /// </summary>
            private void Receive()
            {
                //只有尝试接收如果你已经加入了这个组
                if (_joined)
                {
                    Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length);
                    _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length,
                        result =>
                        {
                            IPEndPoint source;
                            //完成异步操作。在发送的源字段信息中包含设备的IP地址
                            _client.EndReceiveFromGroup(result, out source);
                            //获得将接收的数据从缓冲。
                            string dataReceived = Encoding.UTF8.GetString(_receiveBuffer, 0, _receiveBuffer.Length);
                            //创建一个日志条目。
                            string message = String.Format("[{0}]: {1}", source.Address.ToString(), dataReceived);
                            //记录日志
                            Log(message, false);
    
                            //调用接收再继续来“听”下一条消息的组
                            Receive();
                        }, null);
                }
                else
                {
                    Log("Cannot receive. You are currently not joined to the group", true);
                }
            }

    虽然是MSDN的一个代码示例,但是也展示了多播组的基本操作。

    参考地址:http://msdn.microsoft.com/zh-cn/library/hh286407(v=vs.92).aspx

  • 相关阅读:
    [转]C# ReportViewer报表 详解
    [转]Java NIO原理图文分析及代码实现
    [转]C#泛型编程
    [转]ASP.NET页面基本对象
    [转]C#中抽象类和接口的异同
    [转]Android进程间通信消息机制及IPC机制实现
    [转]左连接和右连接的区别
    [转]C# 4.0 新特性
    [转]UML类图java代码实现
    [转]Using The Entity Framework With WCF
  • 原文地址:https://www.cnblogs.com/renhao0118/p/2786314.html
Copyright © 2020-2023  润新知