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

方法: Windows Phone の TCP ソケット クライアント アプリケーションを作成して使用する

2012/02/09

このトピックでは、Windows Phone 用のシンプルな TCP ソケット クライアント アプリケーションを作成するのに必要な手順について説明します。一般的なシナリオでは、クライアント アプリケーションが TCP ソケット接続を介してサーバーと通信します。単純にするため、また、このトピックを単独で利用できるように、この通信のサーバー側として、ユーザーのコンピューター上の組み込み簡易 TCP/IP サービスを使用します。UDP ソケットを使用して同様のクライアント アプリケーションを作成する場合は、「方法: Windows Phone の UDP ソケット クライアント アプリケーションを作成して使用する」を参照してください。

重要な注重要な注:

このトピックでは、クライアント通信で TCP ソケット サーバーを使用する必要があります。この例では、Windows の簡易 TCP/IP サービス機能をサーバー コンポーネントとして使用しています。次の手順は、コンピューター上で簡易 TCP/IP サービス機能を有効にする方法を示しています。独自のソケット サーバー実装を使用することもできます。

次の手順は、Visual Studio 2010 Express for Windows Phone 向けです。 Visual Studio 2010 Professional や Visual Studio 2010 Ultimate のアドインを使用している場合は、メニュー コマンドやウィンドウのレイアウトが多少異なる場合があります。

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

このセクションでは、TCP ソケット クライアントの機能を示すための UI を作成します。

TCP ソケット クライアントの UI を作成するには

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

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

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

  4. [OK] をクリックします。Windows Phone の [プラットフォームの選択] ウィンドウが表示されます。[対象の Windows Phone バージョン] の [Windows Phone 7.1] を選択します。

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

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

    
            <!--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="TCP Socket Application" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="Client" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
    
    

    この XAML コードは、2 つの TextBlock 要素をアプリケーションに追加します。1 つは "ApplicationTitle" というアプリケーション タイトル用、もう 1 つは "PageTitle" というページ タイトル用です。

  7. MainPage.xaml で、"ContentPanel" という名前のグリッドの XAML コードを削除し、次のコードに置き換えます。

    
            <!--ContentPanel - place additional content here-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,-8,12,8">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>    <!-- Fit to content -->
                    <ColumnDefinition Width="Auto"/>    <!-- Fit to content -->
                    <ColumnDefinition Width="Auto"/>    <!-- Fit to content -->
                    <ColumnDefinition Width="*"/>       <!-- Take up remaining space -->
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>      <!-- Fit to content -->
                    <RowDefinition Height="Auto"/>      <!-- Fit to content -->
                    <RowDefinition Height="Auto"/>      <!-- Fit to content -->
                    <RowDefinition Height="*"/>         <!-- Take up remaining space -->
                </Grid.RowDefinitions>
                
                <!-- Grid Row 0: Remote Host Input Field >-->
                <TextBlock Grid.Row="0" Grid.Column="0" Text="Host Name:"  
                           VerticalAlignment="Center" HorizontalAlignment="Center" 
                           FontSize="{StaticResource PhoneFontSizeNormal}" />
                <TextBox x:Name="txtRemoteHost" Grid.Row="0" Grid.Column="1"  Height="70" Width="200" 
                         VerticalAlignment="Top" HorizontalAlignment="Left" 
                         FontSize="{StaticResource PhoneFontSizeNormal}"  />
                
                <!-- Grid Row 1: Echo >-->
                <!-- TextBlock for Echo command label-->
                <TextBlock Grid.Row="1" Grid.Column="0" Text="Text To Echo:" 
                           VerticalAlignment="Center" HorizontalAlignment="Center" 
                           FontSize="{StaticResource PhoneFontSizeNormal}" />
                
                <!-- TextBox for Echo command text input-->
                <TextBox x:Name="txtInput" Grid.Row="1" Grid.Column="1" Height="70" Width="200"  
                         VerticalAlignment="Top" HorizontalAlignment="Left" 
                         FontSize="{StaticResource PhoneFontSizeNormal}" />
                
                <!-- Button to the right of the input textbox for the Echo command >-->
                <Button x:Name="btnEcho" Grid.Row="1" Grid.Column="2" Height="70"  Width="120" 
                        Content="Echo" 
                        FontSize="{StaticResource PhoneFontSizeNormal}" Click="btnEcho_Click"/>
                
                <!-- Grid Row 2: Quote of the Day-->
                <!-- Button for the Quote command >-->
                <Button x:Name="btnGetQuote" Grid.Row="2" Grid.ColumnSpan="4" Height="70" 
                        Content="Get Quote of the Day" 
                        FontSize="{StaticResource PhoneFontSizeNormal}" Click="btnGetQuote_Click"/>
    
                <!-- Grid Row 3: Output-->
                <!-- Output TextBox named 'txtOutput' >-->
                <TextBox x:Name="txtOutput" Grid.Row="3" Grid.ColumnSpan="4" Background="Black" BorderBrush="Green" 
                         AcceptsReturn="False" Foreground="LightGray" FontFamily="Courier New"  
                         IsHitTestVisible="False" FontSize="{StaticResource PhoneFontSizeSmall}" TextWrapping="Wrap" />
            </Grid>
    
    

    この XAML コードは、その他すべての要素を含めるための Grid 要素を作成します。最初に、3 つの行と 3 つの列を持つ Grid を定義します。次に、XAML はリモート ホスト名のデータ入力のための TextBox を定義し、TextBlock をこのフィールドのラベルとして定義します。Grid の次の行は、ユーザーによるさらなるデータ入力用のもう 1 つの TextBox と、Click イベント ハンドラーを割り当てた 2 つの Button 要素で構成されます。最後に、アプリケーションからの出力を表示するためのもう 1 つの TextBox を定義します。以降のセクションで、btnEcho_Click メソッドおよび btnGetQuote_Click メソッドを実装します。デザイナーでのレイアウトは次のようになります。

    ソケットのサンプル スクリーンショット

このセクションでは、ソケットを作成し、System.Net.Sockets API を使用してサーバーに接続します。わかりやすくするために、System.Net.Sockets API への呼び出しは、SocketClient クラス内にカプセル化されています。

TCP ソケット サーバーに接続するには

  1. 新しいクラスを作成します。そのためには、ソリューション エクスプローラー ウィンドウでプロジェクトを選択し、プロジェクトを右クリックして、[追加]、[クラス] の順にクリックします。クラス テンプレートが選択された [新しい項目の追加] ダイアログ ボックスが表示されます。[名前] フィールドでクラスの名前を "SocketClient" に変更し、[追加] をクリックします。プロジェクトに "SocketClient" という名前の新しいクラスが作成されます。

  2. SocketClient.cs を開き、次の using ディレクティブをページの一番上に追加します。

    
    using System.Net.Sockets;
    using System.Threading;
    using System.Text;
    
    
  3. SocketClient クラスの先頭に次の変数を定義します。

    
    // Cached Socket object that will be used by each call for the lifetime of this class
            Socket _socket = null;
    
            // Signaling object used to notify when an asynchronous operation is completed
            static ManualResetEvent _clientDone = new ManualResetEvent(false);
    
            // Define a timeout in milliseconds for each asynchronous call. If a response is not received within this 
            // timeout period, the call is aborted.
            const int TIMEOUT_MILLISECONDS = 5000;
    
            // The maximum size of the data buffer to use with the asynchronous socket methods
            const int MAX_BUFFER_SIZE = 2048;
    
    

    _socket 変数は、作成した Socket オブジェクトを格納するために使用されます。_clientDone 変数は ManualResetEvent であり、Sockets API で呼び出される非同期呼び出しの調整に使用されます。詳細については、「ManualResetEvent クラス」を参照してください。

  4. SocketClient.cs で、次メソッドを追加します。これにより、TCP ソケットが作成され、非同期接続要求がサーバーに送信されます。このアクションの応答は、インライン コールバックによって処理されます。

    
            /// <summary>
            /// Attempt a TCP socket connection to the given host over the given port
            /// </summary>
            /// <param name="hostName">The name of the host</param>
            /// <param name="portNumber">The port number to connect</param>
            /// <returns>A string representing the result of this connection attempt</returns>
            public string Connect(string hostName, int portNumber)
            {
                string result = string.Empty;
    
                // Create DnsEndPoint. The hostName and port are passed in to this method.
                DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber);
    
                // Create a stream-based, TCP socket using the InterNetwork Address Family. 
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                
                // Create a SocketAsyncEventArgs object to be used in the connection request
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = hostEntry;
    
                // Inline event handler for the Completed event.
                // Note: This event handler was implemented inline in order to make this method self-contained.
                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                {
                    // Retrieve the result of this request
                    result = e.SocketError.ToString();
    
                    // Signal that the request is complete, unblocking the UI thread
                    _clientDone.Set();
                });
    
                // Sets the state of the event to nonsignaled, causing threads to block
                _clientDone.Reset();
    
                // Make an asynchronous Connect request over the socket
                _socket.ConnectAsync(socketEventArg);
    
                // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
                // If no response comes back within this time then proceed
                _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
    
                return result;
            }
    
    
    

    このメソッドは、次の概念を示します。

    • エンドポイントの作成: DnsEndPoint クラスには、アプリケーションがホスト上のサービスに接続するために必要とするホスト名、または IP アドレスとリモート ポートの情報が格納されます。

    • ソケットの作成: Socket オブジェクトは AddressFamily.InterNetwork に設定された AddressFamily パラメーターを使用してインスタンス化されます。SocketType パラメーターは SocketType.Stream に設定され、ProtocolType パラメーターは ProtocolType.Tcp に設定されます。AddressFamily パラメーターは、ソケットがアドレスを解決するために使用するアドレッシング スキームを指定します。たとえば、InterNetwork は、ソケットをエンド ポイントに接続する場合に、IP version 4 アドレスが必要であることを示します。ソケット接続はまだ確立されていないことに注意してください。使用するソケットを TCP プロトコルを使用するストリームベースのソケットに設定しているだけです。サーバーへの実際の接続は、ConnectAsync の呼び出しで行われます。

      重要な注重要な注:

      Windows Phone 7.1 では、AddressFamily.InterNetwork は Socket コンストラクターの AddressFamily パラメーターの唯一の有効値です。AddressFamily 列挙値の他のいずれかのメンバーを選択すると、エラーが発生します。

    • コンテキスト オブジェクトの作成: このオブジェクトは呼び出されている非同期メソッド (この場合は ConnectAsync) のコンテキスト オブジェクトです。データ バッファー、コールバック メソッド、およびその他さまざまなコンテキスト固有データが、このオブジェクトに設定されて、非同期呼び出しに渡されます。呼び出しが完了したら、このオブジェクトを調べることで完了ステータスおよび操作の結果を確認できます。

    • Completed イベントのコールバックの定義: このメソッドは、ConnectAsync メソッドからの Completed イベントを処理するためにデリゲートを使用します。

    • 呼び出しが完了するまで待機する: この例で、WaitOne メソッドは、Completed イベントが発生するか呼び出しがタイムアウトするまで UI スレッドをブロックします。

    注注:

    アプリケーションが休止状態から再アクティブ化された場合、ソケットの新しいインスタンスを作成する必要はありません。接続を再確立するには、Socket.ConnectAsync を呼び出します。ソケットに接続の優先順位や要件が定義されている場合、休止状態の間、それらが維持されます。実行モデルとアプリケーションの状態の詳細については、「Windows Phone の実行モデルの概要」を参照してください。

このセクションでは、データをサーバーに送信するために、Send メソッドを SocketClient クラスに追加します。

TCP ソケット サーバーにデータを送信するには

  • SocketClient.cs に次のメソッドを追加します。

       
            /// <summary>
            /// Send the given data to the server using the established connection
            /// </summary>
            /// <param name="data">The data to send to the server</param>
            /// <returns>The result of the Send request</returns>
            public string Send(string data)
            {
                string response = "Operation Timeout";
    
                // We are re-using the _socket object that was initialized in the Connect method
                if (_socket != null)
                {
                    // Create SocketAsyncEventArgs context object
                    SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
    
                    // Set properties on context object
                    socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
                    socketEventArg.UserToken = null;
    
                    // Inline event handler for the Completed event.
                    // Note: This event handler was implemented inline in order to make this method self-contained.
                    socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                    {
                        response = e.SocketError.ToString();
    
                        // Unblock the UI thread
                        _clientDone.Set();
                    });
    
                    // Add the data to be sent into the buffer
                    byte[] payload = Encoding.UTF8.GetBytes(data);
                    socketEventArg.SetBuffer(payload, 0, payload.Length);
    
                    // Sets the state of the event to nonsignaled, causing threads to block
                    _clientDone.Reset();
    
                    // Make an asynchronous Send request over the socket
                    _socket.SendAsync(socketEventArg);
    
                    // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
                    // If no response comes back within this time then proceed
                    _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
                }
                else
                {
                    response = "Socket is not initialized";
                }
    
                return response;
            }
    
    

    このメソッドは次の概念を説明しています。

    • コンテキスト オブジェクトの作成: このオブジェクトは呼び出されている非同期メソッド (この場合は SendAsync) のコンテキスト オブジェクトです。データ バッファー、コールバック メソッド、およびその他さまざまなコンテキスト固有データが、このオブジェクトに設定されて、非同期呼び出しに渡されます。呼び出しが完了したら、このオブジェクトの完了ステータスと操作の結果を調べることができます。

    • コンテキスト オブジェクトにバッファーを設定する: サーバーに送信するデータは、バイトの配列として SocketAsyncEventArgs オブジェクトのバッファー内に配置されます。

    • Completed イベントのコールバックの定義: このメソッドは、SendAsync 呼び出しの Completed イベントを処理するためにデリゲートを使用します。

    • 呼び出しが完了するまで待機する: この例で、WaitOne メソッドは、Completed イベントが発生するか呼び出しがタイムアウトするまで UI スレッドをブロックします。

このセクションでは、データをサーバーに送信するために、Receive メソッドを SocketClient クラスに追加します。

TCP ソケット サーバーからデータを受信するには

  • SocketClient.cs に次のコードを追加します。

    
            /// <summary>
            /// Receive data from the server using the established socket connection
            /// </summary>
            /// <returns>The data received from the server</returns>
            public string Receive()
            {
                string response = "Operation Timeout";
    
                // We are receiving over an established socket connection
                if (_socket != null)
                {
                    // Create SocketAsyncEventArgs context object
                    SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                    socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
    
                    // Setup the buffer to receive the data
                    socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
    
                    // Inline event handler for the Completed event.
                    // Note: This even handler was implemented inline in order to make this method self-contained.
                    socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
                    {
                        if (e.SocketError == SocketError.Success)
                        {
                            // Retrieve the data from the buffer
                            response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
                            response = response.Trim('\0');
                        }
                        else
                        {
                            response = e.SocketError.ToString();
                        }
    
                        _clientDone.Set();
                    });
    
                    // Sets the state of the event to nonsignaled, causing threads to block
                    _clientDone.Reset();
    
                    // Make an asynchronous Receive request over the socket
                    _socket.ReceiveAsync(socketEventArg);
    
                    // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
                    // If no response comes back within this time then proceed
                    _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
                }
                else
                {
                    response = "Socket is not initialized";
                }
    
                return response;
            }
    
            /// <summary>
            /// Closes the Socket connection and releases all associated resources
            /// </summary>
            public void Close()
            {
                if (_socket != null)
                {
                    _socket.Close();
                }
            }
    
    
    

    このメソッドは次の概念を説明しています。

    • コンテキスト オブジェクトの作成: このオブジェクトは呼び出されている非同期メソッド (この場合は ReceiveAsync) のコンテキスト オブジェクトです。データ バッファー、コールバック メソッド、およびその他さまざまなコンテキスト固有データが、このオブジェクトに設定されて、非同期呼び出しに渡されます。呼び出しが完了したら、このオブジェクトを調べることで完了ステータスおよび操作の結果を確認できます。

    • コンテキスト オブジェクトにバッファーを設定する: サーバーから受信するデータは、バイトの配列として SocketAsyncEventArgs オブジェクトのバッファー内に配置されます。

    • Completed イベントのコールバックの定義: このメソッドは、ReceiveAsync 呼び出しの Completed イベントを処理するためにデリゲートを使用します。

    • 呼び出しが完了するまで待機する: この例で、Connect メソッドは、Completed イベントが発生するか呼び出しがタイムアウトするまでブロックします。

    • Close メソッド: クライアント アプリケーションで、作成されたソケットを明示的に閉じるには、Close メソッドを SocketClient クラスに追加します。

前のセクションでは、ストリームベースの TCP ソケットを介してサーバーとの通信するのに必要なすべての操作をカプセル化するために、SocketClient クラスが実装されました。次に、クライアント アプリケーションに戻り、この SocketClient クラスを使用するために必要な機能を追加します。このアプリケーションはコンピューター上の Echo サービスおよび Quote of the Day (QOTD) サービスと通信します。Echo サービスは、このサービスが受信したデータをエコーで返します。Quote of the Day サービスは、メッセージ内の 1 行以上のテキストとして引用を返します。btnEcho ボタンおよび btnGetQuote ボタンからの Click イベント用のイベント ハンドラーを追加します。また、txtOutput TextBox への出力を実行するメソッドと、txtRemoteHost 要素および txtInput TextBox 要素からの入力を検証するためのメソッドを追加します。

アプリケーションで SocketClient クラスを使用するには

  1. MainPage.xaml.cs クラスの先頭に次の定数を定義します。

    
    // Constants
    const int ECHO_PORT = 7;  // The Echo protocol uses port 7 in this sample
    const int QOTD_PORT = 17; // The Quote of the Day (QOTD) protocol uses port 17 in this sample
    
    
  2. MainPage.xaml.cs に次のコードを追加します。

    
            /// <summary>
            /// Handle the btnEcho_Click event by sending text to the echo server and outputting the response
            /// </summary>
            private void btnEcho_Click(object sender, RoutedEventArgs e)
            {
                // Clear the log 
                ClearLog();
    
                // Make sure we can perform this action with valid data
                if (ValidateRemoteHost() && ValidateInput())
                {
                    // Instantiate the SocketClient
                    SocketClient client = new SocketClient();
                    
                    // Attempt to connect to the echo server
                    Log(String.Format("Connecting to server '{0}' over port {1} (echo) ...", txtRemoteHost.Text, ECHO_PORT), true);
                    string result = client.Connect(txtRemoteHost.Text, ECHO_PORT);
                    Log(result, false);
    
                    // Attempt to send our message to be echoed to the echo server
                    Log(String.Format("Sending '{0}' to server ...", txtInput.Text), true);
                    result = client.Send(txtInput.Text);
                    Log(result, false);
    
                    // Receive a response from the echo server
                    Log("Requesting Receive ...", true);
                    result = client.Receive();
                    Log(result, false);
    
                    // Close the socket connection explicitly
                    client.Close();
                }
    
            }
    
            /// <summary>
            /// Handle the btnEcho_Click event by receiving text from the Quote of the Day (QOTD) server and outputting the response
            /// </summary>
            private void btnGetQuote_Click(object sender, RoutedEventArgs e)
            {
                // Clear the log 
                ClearLog();
    
                // Make sure we can perform this action with valid data
                if (ValidateRemoteHost())
                {
                    // Instantiate the SocketClient object
                    SocketClient client = new SocketClient();
    
                    // Attempt connection to the Quote of the Day (QOTD) server
                    Log(String.Format("Connecting to server '{0}' over port {1} (Quote of the Day) ...", txtRemoteHost.Text, QOTD_PORT), true);
                    string result = client.Connect(txtRemoteHost.Text, QOTD_PORT);
                    Log(result, false);
    
                    // Note: The QOTD protocol is not expecting data to be sent to it. So we omit a
                    // send call in this example.
    
                    // Receive response from the QOTD server
                    Log("Requesting Receive ...", true);
                    result = client.Receive();
                    Log(result, false);
    
                    // Close the socket conenction explicitly
                    client.Close();
                }
            }
    
            #region UI Validation
            /// <summary>
            /// Validates the txtInput TextBox
            /// </summary>
            /// <returns>True if the txtInput TextBox contains valid data, False otherwise</returns>
            private bool ValidateInput()
            {
                // txtInput must contain some text
                if (String.IsNullOrWhiteSpace(txtInput.Text))
                {
                    MessageBox.Show("Please enter some text to echo");
                    return false;
                }
    
                return true;
            }
    
            /// <summary>
            /// Validates the txtRemoteHost TextBox
            /// </summary>
            /// <returns>True if the txtRemoteHost contains valid data, False otherwise</returns>
            private bool ValidateRemoteHost()
            {
                // The txtRemoteHost must contain some text
                if (String.IsNullOrWhiteSpace(txtRemoteHost.Text))
                {
                    MessageBox.Show("Please enter a host name");
                    return false;
                }
    
                return true;
            }
            #endregion
    
            #region Logging
            /// <summary>
            /// Log text to the txtOutput TextBox
            /// </summary>
            /// <param name="message">The message to write to the txtOutput TextBox</param>
            /// <param name="isOutgoing">True if the message is an outgoing (client to server) message, False otherwise</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)
            {
                string direction = (isOutgoing) ? ">> " : "<< ";
                txtOutput.Text += Environment.NewLine + direction + message;
            }
    
            /// <summary>
            /// Clears the txtOutput TextBox
            /// </summary>
            private void ClearLog()
            {
                txtOutput.Text = String.Empty;
            }
            #endregion
     
    

    Echo 操作は、前に示したコードで次のように実装されます。

    • btnEcho ボタンの Click イベントを処理する: Echo 操作は、btnEcho_Click イベントで実装されています。Echo 操作は、ソケット上での ConnectSend、および Receive 操作で構成されます。これは、Connect 操作と Receive 操作のみを使用する GetQuote 操作と異なります。

    • SocketClient オブジェクトのスコープをメソッドにする: これは、単純化するため、および Echo 呼び出しと GetQuote 呼び出しを単体で使用できるようにするために行います。SocketClient クラスのインスタンスは、クラス スコープに格納して、再利用することもできます。

    • 定数としてのポート番号: クライアントは、既知のポート番号 7 を使用してこのサンプルの Echo プロトコルに接続します。このポート番号は、MainPage.xaml.cs クラスで ECHO_PORT として定義されます。

    • 接続: これは、SocketClientConnect メソッドの呼び出しを通じて実行され、txtRemoteHost で受信したホスト名と ECHO_PORT 定数で定義されたポート番号を渡します。入力は検証され、この操作からのフィードバックが Log メソッドを使用して txtOutput に書き込まれます。

    • 送信: txtInput フィールド内のテキストは、SocketClient オブジェクトで Send メソッドを使用してサーバーに送信されます。入力は検証され、この操作からのフィードバックが Log メソッドを使用して txtOutput に書き込まれます。

    • 受信: 次に、SocketClient オブジェクトで Receive メソッドを呼び出すことによってエコー サーバーからデータを受信します。これは Log メソッドを使用して txtOutput に書き込まれます。

    • 閉じる: 最後に、SocketClient オブジェクトの Close メソッドを明示的に呼び出してソケットを閉じます。

    GetQuote 操作は上記のコードで、次のように実装されます。

    • btnGetQuote ボタンの Click イベントを処理する: GetQuote 操作は、btnGetQuote_Click イベントで実装されています。GetQuote 操作は、ソケット上での Connect および Receive 操作で構成されます。これは、ConnectSend、および Receive の操作を使用する Echo 操作と異なります。

    • SocketClient オブジェクトのスコープをメソッドにする: これは、単純化するため、および Echo 呼び出しと GetQuote 呼び出しを単体で使用できるようにするために行います。SocketClient クラスのインスタンスは、クラス スコープに格納して、再利用することもできます。

    • 定数としてのポート番号: クライアントは、既知のポート番号 17 を使用してこのサンプルの Quote of the Day (QOTD) プロトコルに接続します。このポート番号は、MainPage.xaml.cs クラスで QOTD_PORT として定義されます。

    • 接続: これは、SocketClientConnect メソッドの呼び出しを通じて実行され、txtRemoteHost で受信したホスト名と QOTD_PORT 定数で定義されたポート番号を渡します。入力は検証され、この操作からのフィードバックが Log メソッドを使用して txtOutput に書き込まれます。

    • 送信: Quote of the Day の場合、送信要求は作成されません。サンプルでは、単純に、Receive 要求を使用してサーバーから引用を取得します。

    • 受信: 次に、SocketClient オブジェクトで Receive を呼び出すことによって Quote of the Day サーバーからデータを受信します。これは、Log メソッドを使用して txtOutput に書き込まれます。

    • 閉じる: 最後に、SocketClient オブジェクトの Close メソッドを明示的に呼び出してソケットを閉じます。

このトピックでは、すべての Windows コンピューターで使用可能な Echo サービスと Quote of the Day サービスを使用します。簡易 TCP/IP サービスは、すべてのバージョンの Windows で使用可能な機能です。この機能は次のサービスを提供します。Character GeneratorDaytimeDiscardEcho、および Quote of the Day。それぞれのサービスは TCP 経由でアクセス可能で、それぞれに通信に使用する既定のポートが割り当てられています。ポート マッピングに対する既定のサービスは次のとおりです。

サービス名

説明

ポート

Echo

このサーバー ポートで受信したすべてのメッセージのデータをエコーで返します。ネットワークのデバッグや監視を行うツールとして役立ちます。

7

Quote of the Day

メッセージ内の 1 行以上のテキストとして、引用を返します。引用は、%SYSTEMROOT%\System32\Drivers\Etc\Quotes ファイルからランダムに取得されます。簡易 TCP/IP サービスと共にサンプルの引用ファイルがインストールされます。このファイルがない場合、引用サービスは失敗します。

17

Daytime

曜日、月、日、年、現在の時刻 (hh:mm:ss 形式)、およびタイム ゾーン情報を含むメッセージを返します。プログラムによっては、システム クロックの時差や異なるホスト上での差異をデバッグまたは監視する場合に、このサービスの出力を使用できます。

13

Character Generator

印刷可能な 95 個の ASCII 文字のセットで構成されたデータを送信します。ライン プリンターのテストとトラブルシューティングを行うためのデバッグ ツールとして役立ちます。

19

Discard

応答や確認応答を返すことなく、このポートで受信したすべてのメッセージを破棄します。ネットワークのセットアップや構成中にテスト メッセージの受信やルーティングを行うための null ポートとして使用できます。また場合によっては、プログラムでメッセージの破棄機能として試用できます。

9

コンピューター上で簡易 TCP/IP サービスを有効にするには

  1. コントロール パネルの [プログラムと機能] を開きます。

  2. [Windows の機能の有効化または無効化] をクリックします。

  3. [Windows の機能] ダイアログで、[簡易 TCP/IP サービス] チェック ボックスをオンにしてこの機能を有効にし、[OK] をクリックします。

    重要な注重要な注:

    この手順を実行するには、ローカル コンピューター上の Administrators グループまたは Network Configuration Operators グループのメンバーである必要があります。

  4. 使用しているコンピューター上のサービス一覧で、[簡易 TCP/IP サービス] というサービスが開始されていることを確認します。開始されていない場合は、サービスを手動で開始します。サービスの開始の詳細については、「サービス開始方法の構成」を参照してください。

このセクションでは、このトピックで生成されたアプリケーションを実行する方法について説明します。

TCP ソケット クライアント アプリケーションを実行するには

  1. デバイスで、[デバッグ] メニューの [デバッグ開始] をクリックしてアプリケーションを実行します。

  2. Echo 機能を試すには:

    1. [ホスト名] フィールドにホスト名を追加します。

    2. [エコーするテキスト] フィールドに、送信するテキストを追加します。

    3. [エコー] をクリックします。

    出力ウィンドウに、端末上のクライアントとサーバー間の通信のラウンドトリップが、発生したエラーがあればエラーも含めて表示されます。

  3. Quote of the Day 機能を試すには:

    1. [ホスト名] フィールドにホスト名を追加します。

    2. [引用の取得] をクリックします。

    出力ウィンドウに、端末上のクライアントとサーバー間の通信のラウンドトリップが、発生したエラーがあればエラーも含めて表示されます。

この情報は役に立ちましたか。
(残り 1500 文字)
フィードバックをいただき、ありがとうございました
表示:
© 2014 Microsoft. All rights reserved.