エクスポート (0) 印刷
すべて展開

方法: Windows Phone のソケットに関する接続の優先順位を設定する

2012/02/09

Windows Phone OS 7.1 では、ネットワーク通信で使用するネットワーク インターフェイスの種類の優先順位を設定できます。指定できるのは Cellular または NonCellular で、それぞれ携帯ネットワーク技術を使用するネットワーク インターフェイスか携帯ネットワーク技術を使用しないネットワーク インターフェイスかを表します。NonCellular 技術には、Wi-Fi やイーサネットなどがあります。アプリケーションの優先設定を満たすことができる場合は、その設定がネットワーク通信に使用されます。優先設定を満たすことができない場合は、利用可能な別のネットワーク インターフェイスを使用してネットワーク通信が行われます。このトピックでは、ソケットでネットワーク インターフェイスの優先設定を指定し、ソケットが接続された後で現在のインターフェイスを確認する方法について説明します。

Microsoft.Phone.Net.NetworkInformation 名前空間には、ソケット クラスの拡張メソッドがあります。SetNetworkPreference(Socket, NetworkSelectionCharacteristics) メソッドを使用すると、ソケットでネットワーク インターフェイスの優先設定を指定できます。

注注:

拡張メソッドの詳細については、「方法: 拡張メソッドを呼び出す (Visual Basic)」または「拡張メソッド (C# プログラミング ガイド)」を参照してください。

次の手順では、テストの目的でのみボタン クリック イベントにコードを配置します。次の手順では、button1 という名前のボタンを持つ Windows Phone アプリケーションがあることを前提としています。

ソケットで接続の優先順位を設定するには

  1. ページの分離コード ファイルの先頭に、次のステートメントを追加します。

    
    using System.Net.Sockets;
    using Microsoft.Phone.Net.NetworkInformation;
    using System.Text;
    
    
  2. ボタン クリック イベントに次のコードを追加します。これにより、ソケットが作成され、そのソケットで SetNetworkPreference 拡張メソッドが呼び出され、ソケットで使用する優先ネットワーク インターフェイスが Cellular に設定されます。その後、接続が開始されます。接続されていないソケットでは SetNetworkPreference を呼び出すことができます。ここでは接続を試みるため、現在のネットワーク インターフェイス情報を取得することができます。ソケットの現在のネットワーク インターフェイスの取得には、GetCurrentNetworkInterface(Socket) 拡張メソッドを使用します。これは次の手順に示されています。

    重要な注重要な注:

    この例を実行するには、次のコードで serverNameportNumber を変更し、この TCP ソケットで通信できるサービスとそのポートを参照します。そうしないと、接続要求に対してタイムアウトを受信します。

    ヒントヒント:

    以下のコードの DnsEndPoint コンストラクター内で、サーバー名やホスト名を指定する代わりに IP アドレスの文字列表現を使用することができます。また、SocketAsyncEventArgs の RemoteEndPoint プロパティに、DnsEndPoint でなく IPEndpoint を使用することもできます。

    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
    
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                // Set the preferred network interface to be an interface that uses cellular technology. 
                socket.SetNetworkPreference(NetworkSelectionCharacteristics.Cellular);
                
    
                // To run this application, you should specify the name of a server on your network that is running
                // the required service. Replace the following "Placeholder" text with the name of the server.
                string serverName = "Placeholder";
    
                // This identifies the port over which to communicate. In this sample, we need to just
                // supply the Echo port number, but you are free to select your own.
                int portNumber = 7;
    
                // Create DnsEndPoint. 
                DnsEndPoint hostEntry = new DnsEndPoint(serverName, portNumber);
    
                // Create a SocketAsyncEventArgs object to be used in the connection request.
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = hostEntry;
                socketEventArg.UserToken = socket;
                socketEventArg.Completed += ShowNetworkInterfaceInformation;
    
                // // Make an asynchronous Connect request over the socket.
                socket.ConnectAsync(socketEventArg);
            }
    
    

    上記のメソッドでは、ShowNetworkInterfaceInformation に Completed イベント ハンドラーを割り当てます。これは、非同期ソケット接続要求が完了するかタイムアウトするときに呼び出されるコールバックです。接続が成功した場合、ソケットのすべてのネットワーク インターフェイス情報の取得は、このメソッドで行われます。この例では、この情報を使用してソケットで実際に使用されているネットワーク インターフェイスを表示するため、SetNetworkPreference の呼び出しで、上記のコードで設定した優先順位と比較することができます。

    注注:

    アプリケーションで特定のネットワーク インターフェイス技術が必要な場合は、拡張メソッド SetNetworkRequirement(Socket, NetworkSelectionCharacteristics) を使用して、Cellular または NonCellular ネットワーク インターフェイスを指定することができます。

  3. 同じ分離コード ページで、次のメソッドを追加します。

    
            /// <summary>
            /// Display the network information using the GetCurrentNetworkInterface extension method on the socket.
            /// </summary>
            /// <remarks>This is the callback from the ConnectAsync method.</remarks>
            void ShowNetworkInterfaceInformation(object s, SocketAsyncEventArgs e)
            {
                // When ConnectAsync was called, it was passed the socket object in
                // the UserToken field of the socketEventArg. This context is retrieved once
                // the ConnectAsync has completed.
                Socket socket = e.UserToken as Socket;
    
                // Call GetCurrentNetworkInterface only if the connection was successful.
                if (e.SocketError == SocketError.Success)
                {
                    NetworkInterfaceInfo netInterfaceInfo = socket.GetCurrentNetworkInterface();
    
                    // Use a StringBuilder to efficiently build up an information text about this
                    // NetworkInterfaceInfo.
                    StringBuilder sb = new StringBuilder();
    
                    // For clarity, append a timestamp so that we can see when this information was gathered.
                    sb.AppendLine("Last Updated: " + DateTime.Now.ToString());
    
                    sb.Append("Interface Name: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceName);
    
                    sb.Append("Interface State: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceState.ToString());
    
                    sb.Append("Interface Type: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceType.ToString());
    
                    sb.Append("Interface SubType: ");
                    sb.AppendLine(netInterfaceInfo.InterfaceSubtype.ToString());
    
                    DisplayMessage(sb.ToString(), "Network Interface Information", MessageBoxButton.OK);
                }
                else
                {
                    DisplayMessage(e.SocketError.ToString(), "Error Getting Interface Information", MessageBoxButton.OK);
                }
    
                // Close our socket since we no longer need it. 
                // The scope of this socket instance is this method. It is created every time the method is called. 
                // This was done purely to keep this method as self-contained as possible for this sample. 
                socket.Close();
            }
    
    

    上記のメソッドで、接続要求の可否は SocketAsyncEventArgsSocketError プロパティを参照して判断されます。接続に成功した場合は、ソケット オブジェクトで GetCurrentNetworkInterface 拡張メソッドの呼び出しが行われます。単純なテキスト出力は、NetworkInterfaceInfo オブジェクトの多様なプロパティ値を組み合わせて生成されます。最後に、次のコードで説明する DisplayMessage の呼び出しが行われます。

  4. 同じ分離コード ページで、次のメソッドを追加します。

    
            /// <summary>
            /// This helper method ensures that MessageBox.Show() is called on the UI thread.
            /// </summary>
            void DisplayMessage(string text, string caption, MessageBoxButton buttonConfiguration)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show(text, caption, buttonConfiguration);
                });
            }
    
    
  5. ソリューションをビルドして実行すると、次のような MessageBox が表示されます。

    「方法: 接続情報の取得」のスクリーンショット
    注注:

    上記のイメージで、Interface SubType の値は Unknown です。ただし、携帯ネットワークに接続する場合、Wi-Fi でつないだり接続したりする代わりに、このフィールドには 2G や 3G などの携帯ネットワークの種類が表示されます。

表示:
© 2014 Microsoft