信息
您所需的主题如下所示。但此主题未包含在此库中。

如何创建和使用 Windows Phone 8 的 UDP 套接字客户端应用

2014/6/18

适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

 

本主题介绍为 Windows Phone 创建简单 UDP 套接字客户端应用所需的步骤。典型方案是客户端应用通过 UDP 套接字与服务器进行通信。为了简便起见,同时也为了保持此主题的独立性,我们将使用计算机上的内置简单 TCP/IP 服务来作为本通信的服务器端。若要创建使用 TCP 套接字的类似客户端应用,请参见如何创建和使用 Windows Phone 8 的 TCP 套接字客户端应用

重要说明重要说明:

本主题要求使用 UDP 套接字服务器进行客户端通信。在本示例中,将 Windows 的简单 TCP/IP 服务功能用作为服务器组件。下列过程提供了在您的计算机上启用简单 TCP/IP 服务功能的说明。您可能更喜欢使用自己的套接字服务器实现。

本主题包括以下部分。

 

在本节中,创建用于演示 UDP 套接字客户端功能的 UI。

创建 UDP 套接字客户端 UI

  1. 在 Visual Studio 中,通过选择“文件” | “新建项目”菜单命令创建新的项目。

  2. 将显示“新建项目”窗口。展开“Visual C#”模板,然后选择“Windows Phone”模板。

  3. 选择 Windows Phone 应用  模板。用您选择的名称填写“名称”

  4. 单击“确定”。将显示 Windows Phone 平台选择对话框。选择面向的版本或接受默认版本。

  5. 单击“确定”。将创建一个新的项目,并且“MainPage.xaml”将在 Visual Studio 设计器窗口中打开。

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

    XAML 代码向应用添加了两个 TextBlock 元素,一个用于名为“ApplicationTitle”的应用标题,另一个用于名为“PageTitle”的页面标题。

  7. “MainPage.xaml”中,删除名为“ContentPanel”的 Grid 的 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 元素,用来包含所有其他元素。首先,定义 Grid 拥有三行和三列。接着,XAML 定义了 TextBox(用于远程主机名称数据输入)和 TextBlock(作为该字段的标签)。下一行 Grid 包含另一个 TextBox(用于来自用户的更多数据输入)和两个分配了 Click 事件处理程序的 Button 元素。最后,XAML 定义了另外一个 TextBox,用来显示应用中的输出。在以下几节中将实现 btnEcho_ClickbtnGetQuote_Click 方法。设计器中的布局应与下图类似。

    Screenshot of Basic UDP Socket Client Application

在本节中,将使用 System.Net.Sockets API 创建套接字并连接到服务器。为了清楚起见,对 System.Net.Sockets API 的调用被封装在 SocketClient 类中。

连接到 UDP 套接字服务器的步骤

  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,用于协调通过 System.Net.Sockets API 调用的异步调用。

  4. SocketClient.cs 中,添加以下构造函数,该构造函数将创建 UDP 套接字。

            /// <summary>
            /// SocketClient Constructor
            /// </summary>
            public SocketClient()
            {
                // The following creates a socket with the following properties:
                // AddressFamily.InterNetwork - the socket will use the IP version 4 addressing scheme to resolve an address
                // SocketType.Dgram - a socket that supports datagram (message) packets
                // PrototcolType.Udp - the User Datagram Protocol (UDP)
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            }
    
    重要说明重要说明:

    在 Windows Phone OS 7.1 中的 Socket 构造函数中,AddressFamily 参数的唯一有效值是 AddressFamily.InterNetwork。选择 AddressFamily 枚举的任何其他成员都将会导致错误。

在本节中,将向 SocketClient 类添加 Send 方法,以便向服务器发送数据。

向 UDP 套接字服务器发送数据的步骤

  • SocketClient.cs 中,添加以下方法。

           /// <summary>
            /// Send the given data to the server using the established connection
            /// </summary>
            /// <param name="serverName">The name of the server</param>
            /// <param name="portNumber">The number of the port over which to send the data</param>
            /// <param name="data">The data to send to the server</param>
            /// <returns>The result of the Send request</returns>
            public string Send(string serverName, int portNumber, 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 = new DnsEndPoint(serverName, portNumber);
                    // 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.SendToAsync(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;
            }
    

    本方法会说明以下概念:

    • 创建上下文对象:该对象是对其调用异步方法的任何上下文对象(在本例中为 SendToAsync)。将会在该对象上设置数据缓冲区、回调方法和各种其他特定于上下文的数据,然后将这些数据传递到异步调用。在调用完成后,可以检查该对象的完成状态和操作结果。

    • 在上下文对象上设置 RemoteEndpoint:此属性设置数据发送目标远程终结点。在此示例中,将其定义为一个由 serverNameportNumber 参数构造的 DnsEndPoint

    • 在上下文对象上设置缓冲区:要发送到服务器的数据将作为字节数组放置在 SocketAsyncEventArgs 对象的缓冲区中。

    • 定义 Completed 事件的回调:该方法使用委托处理 SendToAsync 调用中的 Completed 事件。

    • 等待直到调用完成:在本示例中,WaitOne 方法将会阻止 UI 线程,直到 Completed 事件引发或调用超时。

在本节中,将向 SocketClient 类添加 Receive 方法,以便从服务器接收数据。

接收来自 UDP 套接字服务器的数据的步骤

  • SocketClient.cs 中,添加以下代码。

            /// <summary>
            /// Receive data from the server
            /// </summary>
            /// <param name="portNumber">The port on which to receive data</param>
            /// <returns>The data received from the server</returns>
            public string Receive(int portNumber)
            {
                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 = new IPEndPoint(IPAddress.Any, portNumber);
                    // 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.ReceiveFromAsync(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();
                }
            }
    

    本方法会说明以下概念:

    • 创建上下文对象:该对象是对其调用异步方法的任何上下文对象(在本例中为 ReceiveFromAsync)。将会在该对象上设置数据缓冲区、回调方法和各种其他特定于上下文的数据,然后将这些数据传递到异步调用。在调用完成后,可以检查该对象的完成状态和操作结果。

    • 在上下文对象上设置 RemoteEndpoint:此属性设置数据接收源远程终结点。在本示例中,将其定义为一个使用 IPAddress.Any 指定客户端应侦听所有网络接口并将端口号设置为 portNumber 参数的 IPEndPoint

    • 在上下文对象上设置缓冲区:要从服务器接收的数据将作为字节数组放置在 SocketAsyncEventArgs 对象的缓冲区中。

    • 定义 Completed 事件的回调:该方法使用委托处理 ReceiveFromAsync 调用中的 Completed 事件。

    • 等待直到调用完成:在本示例中,Connect 方法将会阻止,直到 Completed 事件引发或调用超时。

    • 关闭方法:为了使客户端应用程序可以显式关闭创建的 Socket,向 SocketClient 类添加了 Close 方法。

在上几节中,实现了一个 SocketClient 类,用来封装通过 UDP 套接字与服务器进行通信所需的全部操作。现在,我们将返回到客户端应用,并添加使用此 SocketClient 类所需的功能。本应用将与计算机上的 Echo 服务和 Quote of the Day (QOTD) 服务进行通信。无论向 Echo 服务发送任何数据,Echo 服务都会回显。Quote of the Day 服务在消息中以一行或多行文本的形式返回报价。我们为 btnEchobtnGetQuote 按键的 Click 事件添加事件处理程序。我们还将添加一些方法来执行 txtOutput TextBox 的输出,并验证来自 txtRemoteHosttxtInput 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 send our message to be echoed to the echo server
                    Log(String.Format("Sending '{0}' to server ...", txtInput.Text), true);
                    string result = client.Send(txtRemoteHost.Text, ECHO_PORT,txtInput.Text);
                    Log(result, false);
                    // Receive a response from the echo server
                    Log("Requesting Receive ...", true);
                    result = client.Receive(ECHO_PORT);
                    Log(result, false);
                    // Close the socket connection explicitly
                    client.Close();
                }
            }
    
            /// <summary>
            /// Handle the btnGetQuote_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();
                    // Quote of the Day (QOTD) sends a short message (selected by the server’s administrator) to a client device.
                     // For UDP, the message is sent for each incoming UDP message, so here we send a "dummy" message to solicit
                     // a response. The message cannot be empty, so the message below consists of one whitespace.
                    Log(String.Format("Requesting a quote from server '{0}' ...", txtInput.Text), true);
                    string dummyMessage = " ";
                    string result = client.Send(txtRemoteHost.Text, QOTD_PORT, dummyMessage);
                    Log(result, false);
                    // Receive response from the QOTD server
                    Log("Requesting Receive ...", true);
                    result = client.Receive(QOTD_PORT);
                    Log(result, false);
                    // Close the socket connection 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 事件中实现。由于 UDP 无连接,因而在向服务器发送数据前无需建立连接。UDP 上的 Echo 操作由套接字上的 SendReceive 操作组成。

    • SocketClient 对象的作用域被限制在方法中:这样做的目的是出于简便和保持 EchoGetQuote 调用的独立性。还可以在类作用域内存储和重新使用 SocketClient 类的实例。

    • 端口号被设置为常量:在本示例中,客户端使用熟知的端口号 7 连接到 Echo 协议。在 MainPage.xaml.cs 类中,此端口号被定义为 ECHO_PORT

    • 连接:此操作通过调用 SocketClientConnect 方法完成,传递了 txtRemoteHost 中接收的主机名和 ECHO_PORT 常量中定义的端口号。验证输入,并使用 Log 方法将该操作的反馈写入到 txtOutput

    • 发送:使用 SocketClient 对象上的 Send 方法将 txtInput 字段中的文本发送到服务器。验证输入,并使用 Log 方法将该操作的反馈写入到 txtOutput

    • 接收:接着,通过调用 SocketClient 对象上的 Receive 方法接收来自回显服务器的数据。该数据通过 Log 方法写入 txtOutput

    • 关闭:最后,通过显示调用 SocketClient 对象的 Close 方法关闭套接字。

    在上述代码中按如下方式实现了 GetQuote 操作:

    • 处理 btnGetQuote 按键上的 Click 事件: GetQuote 操作在 btnGetQuote_Click 事件中实现。由于 UDP 无连接,因而在向服务器发送数据前无需建立连接。UDP 上的 GetQuote 操作由在套接字上的 SendReceive 操作组成。由于 UDP 上的 QOTD 为其接收的每个传入消息发送报价消息,因而需要 send。在前面的示例中,我们向 QOTD 服务发送了一个虚拟消息以发起回应。

    • SocketClient 对象的作用域被限制在方法中:这样做的目的是出于简便和保持 EchoGetQuote 调用的独立性。还可以在类作用域内存储和重新使用 SocketClient 类的实例。

    • 端口号被设置为常量:在本示例中,客户端使用熟知的端口号 17 连接到 Quote of the Day (QOTD) 协议。在 MainPage.xaml.cs 类中,此端口号被定义为 QOTD_PORT

    • 连接:此操作通过调用 SocketClientConnect 方法完成,传递了 txtRemoteHost 中接收的主机名和 QOTD_PORT 常量中定义的端口号。验证输入,并使用 Log 方法将该操作的反馈写入到 txtOutput

    • 发送:对于 Quote of the Day,没有发出发送请求。我们只是通过使用“接收”请求提取了来自服务器的报价。

    • 接收:接着,通过调用 SocketClient 对象上的 Receive 方法接收来自 Quote of the Day 服务器的数据。该数据通过 Log 方法写入 txtOutput

    • 关闭:最后,通过显示调用 SocketClient 对象的 Close 方法关闭套接字。

本主题使用每台 Windows 计算机上提供的 EchoQuote of the Day 服务。在所有 Windows 版本中都提供了简单 TCP/IP 服务功能。该功能会提供了以下服务:Character GeneratorDaytimeDiscardEchoQuote of the Day。每个服务都可以通过 UDP 访问,并且都分配了一个用于通信的默认端口。默认服务与端口的映射如下所示。

服务名称

描述

端口

Echo

回显在该服务器端口上接收到的任何消息中的数据。Echo 作为网络调试和监视工具可能非常有用。

7

Quote of the Day

在消息中以一行或多行文本的形式返回报价。报价从以下文件中随机提取:%SYSTEMROOT%\System32\Drivers\Etc\Quotes。示例报价文件会与简单的 TCP/IP 服务一起安装。如果该文件丢失,则报价服务会失败。

17

Daytime

返回包含星期几、月、天、年、当前时间(以 hh:mm:ss 格式表示)和时区信息的消息。某些程序可能会将该服务的输出用于调试或监视系统时钟时间中或不同主机上的变化。

13

Character Generator

所发送数据包含一组 95 个可打印的 ASCII 字符。作为测试或解决行打印机问题的调试工具非常有用。

19

Discard

放弃该端口上接收到的所有消息,而不响应或确认。在网络设置和配置过程中,可以用作空端口来接收和路由 TCP/IP 测试消息,或者在某些情况下,程序可将其用作为消息放弃函数。

9

在您的计算机上启用简单 TCP/IP 服务的步骤

  1. 在“控制面板”中,打开“程序和功能”

  2. 单击“打开或关闭 Windows 功能”

  3. “Windows 功能”对话框中,选中“简单 TCP/IP 服务”复选框以启用此功能,然后单击“确定”

    重要说明重要说明:

    若要执行此过程,您必须是本地计算机上 Administrators 组或 Network Configuration Operators 组的成员。

  4. 在计算机上的“服务”列表中,验证“简单 TCP/IP 服务”服务是否已经启动。如果没有启动,请手动启动该服务。有关启动服务的更多信息,请参见配置服务启动方式

本节介绍如何运行本主题中生成的应用。

运行 UDP 套接字客户端应用的步骤

  1. 在设备上,通过选择“调试 | 启动调试”菜单命令来运行应用。

  2. 尝试 Echo 功能的步骤:

    1. “主机名”字段中添加主机名。

    2. “Echo 文本”字段中添加您希望发送的文本。

    3. 单击“Echo”按键。

    在输出窗口中,应会看到手机上的客户端与服务器间的通信往返过程,包括可能发生的任何错误。

  3. 尝试 Quote of the Day 功能的步骤:

    1. “主机名”字段中添加主机名。

    2. 单击“获得配额”按键。

    在输出窗口中,应会看到手机上的客户端与服务器间的通信往返过程,包括可能发生的任何错误。

显示: