情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 のマルチキャスト グループでデータを送受信する方法

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

 

このトピックでは、マルチキャスト グループで通信する方法について説明します。マルチキャスト トラフィックは、インターネット上の多対多間で通信するための拡張性のある方法です。通信は、それぞれマルチキャスト グループ アドレスとして知られる IP アドレスによって識別されるマルチキャスト グループ内で行われます。デバイスは、マルチキャスト グループ アドレスにサブスクライブします。その後、サブスクライブしたデバイスによってマルチキャスト グループに送信されたパケットは、マルチキャスト アドレスにサブスクライブした他のすべてのデバイスによって受信されます。このトピックでは、System.Net.Sockets 名前空間で使用可能な UdpAnySourceMulticastClient クラスを使用して、Windows Phone OS 7.1 でマルチキャスト グループに参加するために必要な手順について説明します。この機能を示すアプリの完全なサンプルをダウンロードできます。詳細については、「マルチキャスト ソケットのサンプル」を参照してください。

このトピックは、次のセクションで構成されています。

 

このセクションでは、UDP マルチキャスト機能を示すための UI を作成します。これは、Windows Phone アプリです。このアプリは起動するとマルチキャスト グループに参加します。グループに参加した後、マルチキャスト グループに送信されたメッセージを受信したり、マルチキャスト グループへメッセージを送信したりすることもできます。UI にはマルチキャスト グループに送信されたすべてのデータが表示されます。また、メッセージを入力し、それをマルチキャスト グループに送信することもできます。

UI を作成するには

  1. Visual Studio で、[ファイル] メニューの [新しいプロジェクト] をクリックして新しいプロジェクトを作成します。

  2. [新しいプロジェクト] ウィンドウが表示されます。Visual C# のテンプレートを展開し、Windows Phone のテンプレートを選択します。

  3. Windows Phone アプリ のテンプレートを選択します。[名前] に選択した名前を入力します。

  4. [OK] をクリックします。Windows Phone プラットフォームの選択ダイアログ ボックスが表示されます。ターゲット バージョンを選択するか、既定の設定をそのまま使用します。

  5. [OK] をクリックします。新しいプロジェクトが作成され、Visual Studio のデザイナー ウィンドウに MainPage.xaml が表示されます。

  6. MainPage.xaml で、"LayoutRoot" という名前の Grid の XAML コードを削除し、次のコードに置き換えます。

    
         <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel contains the name of the application and page title-->
            <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 - place additional content here-->
            <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>
    
    
    

    上記の XAML コードでは、次のスクリーンショットのような簡単なユーザー インターフェイスが作成されます。

    BasicUDPMulticastClient How To Screenshot

    イベント ハンドラー btnSend_Click については次のセクションで説明します。

  7. データをマルチキャスト グループに送信するため、アプリは TextBox を使用して、ユーザーからのテキストを受け付け、ボタンがクリックされると、TextBox 内のテキストをマルチキャスト グループに送信します。btnSend_Click イベントが発生するため、このイベントを処理するためのイベント ハンドラーを分離コード ファイルに追加します。ソリューション エクスプローラーで、MainPage.xaml を右クリックしてから、[コードの表示] をクリックします。コード エディターに分離コード ファイルが開きます。ページの分離コード ファイルの最上部に、次のメソッドを追加します。

    
            /// <summary>
            /// Send whatever the user has typed into the input textbox to the multicast group.
            /// </summary>
            private void btnSend_Click(object sender, RoutedEventArgs e)
            {
                // Don't send empty messages.
                if (!String.IsNullOrWhiteSpace(txtInput.Text))
                {
                    Send(txtInput.Text);
                }
            }
    
    
    

    このメソッドは、最初に入力テキスト ボックスにテキストが含まれていることを確認し、その後、Send メソッドを呼び出し、送信するテキストを渡して、マルチキャスト グループにデータを送信します。Send メソッドについては、次のセクションで説明します。

  8. マルチキャスト グループ内で送受信されたメッセージを表示するために、ユーザー インターフェイスに lbLog と呼ばれる ListBox が含まれています。次のコードを使用して、受信したメッセージを ListBox に追加します。ソリューション エクスプローラーで、MainPage.xaml を右クリックしてから、[コードの表示] をクリックします。コード エディターに分離コード ファイルが開きます。ページの分離コード ファイルの最上部に、次のメソッドを追加します。

    
            /// <summary>
            /// Log text to the lbLog ListBox.
            /// </summary>
            /// <param name="message">The message to write to the lbLog ListBox</param>
            /// <param name="isOutgoing">True if the message is an outgoing (client to server) message; otherwise, False</param>
            /// <remarks>We differentiate between a message from the client and server 
            /// by prepending each line  with ">>" and "<<" respectively.</remarks>
            private void Log(string message, bool isOutgoing)
            {
                if (string.IsNullOrWhiteSpace(message.Trim('\0')))
                    return;
    
                // Always make sure to do this on the UI thread.
                Deployment.Current.Dispatcher.BeginInvoke(
                () =>
                {
                    string direction = (isOutgoing) ? ">> " : "<< ";
                    string timestamp = DateTime.Now.ToString("HH:mm:ss");
                    message = timestamp + direction + message;
                    lbLog.Items.Add(message);
    
                    // Make sure that the item we added is visible to the user.
                    lbLog.ScrollIntoView(message);
                });
                
            }
    
    

    前のメソッドは、メッセージ文字列と、記録されるメッセージがこのデバイス宛ての受信メッセージか、またはこのデバイスが送信した送信メッセージのいずれと見なされているかを示す値を受け取ります。このメッセージは、方向インジケーターとタイムスタンプを含むように変更されます。その後、リスト ボックスに追加され、ユーザーがいつでも最後に記録されたメッセージを確認できるように、スクロールして表示されます。これらの UI 操作はすべて、常に UI スレッドで実行されるようにするために BeginInvoke にラップされます。これは、この例に UI スレッドとは異なるスレッドで実行される非同期操作が含まれるため、安全対策です。

このセクションでは、マルチキャスト グループ内でデータを送受信できるようにマルチキャスト グループに参加します。

マルチキャスト グループに参加するには

  1. ソリューション エクスプローラーで、MainPage.xaml を右クリックしてから、[コードの表示] をクリックします。コード エディターに分離コード ファイルが開きます。ページの分離コード ファイルの最上部に、次のステートメントを追加します。

    
    using System.Net.Sockets;
    using System.Text;
    
  2. MainPage クラスの最上部で、次のメンバーを定義します。

    
            // The address of the multicast group to join.
            // Must be in the range from 224.0.0.0 to 239.255.255.255
            private const string GROUP_ADDRESS = "224.0.1.1";
    
            // The port over which to communicate to the multicast group
            private const int GROUP_PORT = 52274;
    
            // A client receiver for multicast traffic from any source
            UdpAnySourceMulticastClient _client = null;
    
            // true if we have joined the multicast group; otherwise, false
            bool _joined = false;
    
            // Buffer for incoming data
            private byte[] _receiveBuffer;
    
            // Maximum size of a message in this communication
            private const int MAX_MESSAGE_SIZE = 512;
    
    

    前のコードについて、以下の点に注意してください:

    • GROUP_ADDRESS: マルチキャスト グループはマルチキャスト グループ アドレスによって定義されます。このアドレスは、224.0.0.0239.255.255.255 の範囲の IP アドレスである必要があります。224.0.0.0224.0.0.255 の範囲のマルチキャスト アドレスは、“既知” の予約済みマルチキャスト アドレスです。たとえば、224.0.0.0 はベース アドレスで、224.0.0.1 は同じ物理ネットワーク上のすべてのシステムを表すマルチキャスト グループ アドレスであり、224.0.0.2 は同じ物理ネットワーク上のすべてのルーターを表します。

      メモメモ:

      IANA (Internet Assigned Numbers Authority) がこの予約済みアドレスのリストを管理しています。予約済みアドレス割り当ての詳細については、IANA の Web サイトを参照してください。

    • GROUP_PORT: これは、マルチキャスト グループとのすべての通信が経由するポート番号を定義します。この場合も、この例の値は任意であり自由に選択できます。

    • UdpAnySourceMulticastClient: このクラスは Windows Phone OS 7.1 で使用可能で、UDP を介してマルチキャスト グループと通信するのに必要なロジックをカプセル化します。この例では、このクラスのインスタンスを作成し、それを JoinSend、および Receive メソッドで使用しています。単一ソースからのマルチキャスト トラフィックの受信については、「UdpSingleSourceMulticastClient」を参照してください。

  3. アプリが起動したら、すぐにマルチキャスト グループに参加し、データの受信を開始します。この例では、OnNavigatedTo メソッドでこの参加アクションを実行します。MainPage クラスに、次のメソッドを追加します。

    
            /// <summary>
            /// Override the OnNavigatedTo method.
            /// </summary>
            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
    
                // Create a new UdpAnySourceMulticastClient instance and join the group.
                Join();
            }
    
    
  4. MainPage クラスに、次のメソッドを追加します。

    
            /// <summary>
            /// Create a new UdpAnySourceMulticastClient instance and join the group.
            /// </summary>
            private void Join()
            {
                // Initialize the receive buffer
                _receiveBuffer = new byte[MAX_MESSAGE_SIZE];
    
                // Create the UdpAnySourceMulticastClient instance using the defined 
                // GROUP_ADDRESS and GROUP_PORT constants. UdpAnySourceMulticastClient is a 
                // client receiver for multicast traffic from any source, also known as Any Source Multicast (ASM)
                _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT);
    
                // Make a request to join the group.
                _client.BeginJoinGroup(
                    result =>
                    {
                        // Complete the join
                        _client.EndJoinGroup(result);
    
                        // The MulticastLoopback property controls whether you receive multicast 
                        // packets that you send to the multicast group. Default value is true, 
                        // meaning that you also receive the packets you send to the multicast group. 
                        // To stop receiving these packets, you can set the property following to false
                         _client.MulticastLoopback = true;
    
                        // Set a flag indicating that we have now joined the multicast group 
                        _joined = true;
    
                        // Let others know we have joined by sending out a message to the group.
                        Send("Joined the group");
    
                        // Wait for data from the group. This is an asynchronous operation 
                        // and will not block the UI thread.
                        Receive();
                    }, null);
            }
    
    

    このメソッドは、最初に定義済みのグループ アドレスとポートの値を使用して UdpAnySourceMulticastClient クラスのインスタンスを作成します。この時点では、まだグループに参加していません。参加するには、UdpAnySourceMulticastClient インスタンスで BeginJoinGroup メソッドを呼び出します。これは非同期呼び出しです。前のコードでは、コールバックがインラインで実装されていますが、独自のメソッドが推奨スタイルの場合はそれに移動することができます。このコールバックで参加を完了し、グループに参加したことを示すフラグを設定してから、すぐに Send メソッドを使用してそのグループにメッセージを送信します。また、Receive メソッドを呼び出して、グループ上のトラフィックの “リッスン” も開始します。Sendメソッドと Receive メソッドは MainPage.xaml.cs で実装されます。これらについては、次のセクションで説明します。

マルチキャスト グループにデータを送信するには

  • MainPage クラスに、次のメソッドを追加します。

    
            /// <summary>
            /// Send the given message to the multicast group.
            /// </summary>
            /// <param name="message">The message to send</param>
            private void Send(string  message)
            {
                // Attempt the send only if you have already joined the group.
                if (_joined)
                {
                    byte[] data = Encoding.UTF8.GetBytes(message);
                    _client.BeginSendToGroup(data, 0, data.Length,
                        result =>
                        {
                            _client.EndSendToGroup(result);
    
                            // Log what we just sent
                            Log(message, true);
                            
                        }, null);
                }
                else
                {
                    Log("Message was not sent since you are not joined to the group", true);
                }
            }
    
    

    前のメソッドは、テキスト文字列を入力として取得し、それをマルチキャスト グループに送信します。最初に、グループに参加したことを確認するためのチェックを行います。BeginSendToGroup 非同期メソッドを使用して、データをマルチキャスト グループに送信します。このメソッドのコールバックは、インラインで実装されます。このコールバックは、送信操作を完了し、アプリ UI に送信されたメッセージをログに記録し、グループからのデータのリッスンを続けます。既定では、UdpAnySourceMulticastClientMulticastLoopback プロパティは true です。これは自分でグループに送信したメッセージを受信することを意味します。このプロパティが false に設定されている場合は、自分で送信したメッセージは受信しません。

マルチキャスト グループからデータを受信するには

  • MainPage クラスに、次のメソッドを追加します。

    
            /// <summary>
            /// Receive data from the group and log it.
            /// </summary>
            private void Receive()
            {
                // Only attempt to receive if you have already joined the group
                if (_joined)
                {
                    Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length);
                    _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length,
                        result =>
                        {
                            IPEndPoint source;
    
                            // Complete the asynchronous operation. The source field will 
                            // contain the IP address of the device that sent the message
                            _client.EndReceiveFromGroup(result, out source);
    
                            // Get the received data from the buffer.
                            string dataReceived = Encoding.UTF8.GetString(_receiveBuffer, 0, _receiveBuffer.Length);
    
                            // Create a log entry.
                            string message = String.Format("[{0}]: {1}", source.Address.ToString(), dataReceived);
    
                            // Log it.
                            Log(message, false);
    
                            // Call receive again to continue to "listen" for the next message from the group
                            Receive();
                        }, null);
                }
                else
                {
                    Log("Cannot receive. You are currently not joined to the group", true);
                }
            }
    
    

    前のメソッドでは、BeginReceiveFromGroup 非同期メソッドを使用してマルチキャスト グループからデータを受信します。このメソッドのコールバックは、インラインで実装されます。このコールバックは受信操作を完了します。EndReceiveFromGroup で、ソース IP アドレスが out パラメーターとして返されることに注意してください。これはこのデータをグループに送信したグループ メンバーのアドレスを指定しています。このソース アドレスの用途の 1 つは、ユニキャスト BeginSendTo 非同期メソッドを使用して、このソールと直接通信することです。この例では、単に各メッセージのソースがだれであるか示すためにアドレスをアプリ UI に記録しているだけです。

ここでは、このトピックで作成したアプリを実行する方法について説明します。

UDP マルチキャスト アプリを実行するには

  1. デバイスまたはエミュレーターで、[デバッグ] メニューの [デバッグ開始] をクリックしてアプリを実行します。

  2. アプリが起動すると、メッセージ領域に、マルチキャスト グループに参加したことを通知するテキストが表示されます。

  3. アプリが正常にマルチキャスト グループに参加した場合は、[Text To Send] とラベル付けされた入力テキスト フィールドにテキストを入力し、[Send] ボタンをクリックしてマルチキャスト グループにデータを送信できます。

  4. 送信したメッセージは、メッセージ領域にも送信メッセージ (>> 記号で示される) および受信メッセージ (<< 記号で示される) として表示されます。

  5. アプリをエミュレーター上で動作させた後、別のコンピューターで別のエミュレーターを使用して、または Wi-Fi を介して同じサブネットワークに接続されている他のデバイスを使用して、このアプリをテストする必要があります。

このトピックでは、マルチキャスト グループで通信する方法について説明します。前のコードは、基本的な参加/送信/受信操作を実装しています。マルチキャスト アプリを作成する場合は、次の点を考慮する必要があります。これはすべてを網羅したリストではありません。アプリを製品化するための考慮事項の一部を取り上げています。

マルチキャスト アプリを作成する場合のその他の考慮事項

  • エラー処理: UdpAnySourceMulticastClient上の非同期メソッドへの各呼び出しは、例外をスローする可能性があります。ソケットへのアクセスでエラーが生じると、SocketException 例外が発生します。 これらの例外は適切に処理する必要があります。

  • 高速アプリ切り替え: アプリが再アクティブ化された場合は、もう一度 BeginJoinGroup を呼び出してマルチキャスト グループに再加入します。同じ UdpAnySourceMulticastClient オブジェクトを使用できます。

  • ユニキャストを使用した通信: この例は、マルチキャスト メッセージの送受信によるマルチキャスト グループ内での通信方法を示しています。これはピアツーピア通信を実装するための推奨方法です。前のセクションで説明したとおり、受信した各メッセージのソース endPoint を使用して、指定されたソースと直接通信できます。この機能の例は、ダウンロードにより入手可能です。詳細については、「マルチキャスト ソケットのサンプル」を参照してください。

表示: