zoukankan      html  css  js  c++  java
  • C#编程之串口(三)

    这一章我将继续上一章内容进一步完善我们的串口通信,并添加对话框的美观设计。

    首先我们说一下双向通讯,上一章我们实现了单向接收功能,这里将说一下发射功能:

    数据发送,总共有三种形式,发送字符串类,发送byte类,发送char类。要实现这三种,都必须调用串口写操作方法 SerialPort.Write() ,该方法对于不同类型的发送,通过方法重载的方式定义了相应的方法:

    1.  public void Write (string str); 发送字符串
    2.  public void Write (byte[] buffer, int offset, int count); 发送byte类型
    3.  public void Write (char[] buffer, int offset, int count); 发送char类型

    本例程发送的是加密后的序列号码,所以只需调用 myPort.Write(output,0,output.Length); 方法即可。此外我们添加一个清空按键:

           private void Btn2_Click(object sender, RoutedEventArgs e)
            {
                m_textBox1.Text = "";
                m_textBox2.Text = "";
            }
    <Button Content="Clear" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="51" Margin="0,0,22,80" Click="Btn2_Click" Height="58"/>

    同时为了美观对话框,我们加入之前定义好的按键动态效果模板来实现按键的动态效果,和加入对label字体格式,textbox背景颜色,以及对话框背景修改:

      1 <Window.Resources>
      2         <!--define glass gradient stop resource-->
      3         <GradientStopCollection x:Key="myGradientStopResource">
      4             <GradientStop Color="WhiteSmoke" Offset="0.2"/>
      5             <GradientStop Color="Transparent" Offset="0.4"/>
      6             <GradientStop Color="WhiteSmoke" Offset="0.5"/>
      7             <GradientStop Color="Transparent" Offset=" 0.75"/>
      8             <GradientStop Color="WhiteSmoke" Offset="0.9"/>
      9             <GradientStop Color="Transparent" Offset=" 1.0"/>
     10         </GradientStopCollection>
     11 
     12         <!--define gradient brush resource-->
     13         <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75"
     14                              GradientStops="{StaticResource myGradientStopResource }"/>
     15 
     16         <!--background brush resource-->
     17         <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1">
     18             <GradientStop Color="Gray" Offset="0"/>
     19             <GradientStop Color="Cyan" Offset="0.5"/>
     20             <GradientStop Color="Gold" Offset="1.0"/>
     21         </LinearGradientBrush>
     22 
     23         <!--define button options-->
     24         <Style TargetType="Button">
     25             <!--define button background-->
     26             <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/>
     27             <!--define button template-->
     28             <Setter Property="Template">
     29                 <Setter.Value>
     30                     <!--target type is button-->
     31                     <ControlTemplate TargetType="{x:Type Button}">
     32                         <Grid Margin="-1,0,-10,1">
     33                             <!--outline rectangle-->
     34                             <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch"
     35                                        VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}"
     36                                        RadiusX="10" RadiusY="10" StrokeThickness="5" Fill="Transparent"/>
     37                             <!--inner rectangle-->
     38                             <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"
     39                                        VerticalAlignment="Stretch" Stroke="Transparent"
     40                                        StrokeThickness="5" Fill="{TemplateBinding Background}"
     41                                        RadiusX="10" RadiusY="10"/>
     42                             <!--glass rectangle-->
     43                             <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"
     44                                        VerticalAlignment="Stretch" StrokeThickness="1"
     45                                        RadiusX="5" RadiusY="5" Opacity="0" 
     46                                        Fill="{StaticResource myGlassBrushResource}"
     47                                        RenderTransformOrigin="0.5,0.5">
     48                                 <!--rectangle stroke-->
     49                                 <Rectangle.Stroke>
     50                                     <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1">
     51                                         <LinearGradientBrush.GradientStops>
     52                                             <GradientStop Color="LightBlue" Offset="0.0"/>
     53                                             <GradientStop Color="Gray" Offset="1.0"/>
     54                                         </LinearGradientBrush.GradientStops>
     55                                     </LinearGradientBrush>
     56                                 </Rectangle.Stroke>
     57                                 <!--glass rectangle render transform-->
     58                                 <Rectangle.RenderTransform>
     59                                     <TransformGroup>
     60                                         <!--To stretch or contact horizontally or vertially-->
     61                                         <ScaleTransform/>
     62                                         <!--rotate transform by angles-->
     63                                         <RotateTransform/>
     64                                     </TransformGroup>
     65                                 </Rectangle.RenderTransform>
     66                             </Rectangle>
     67                             <!--dock panel-->
     68                             <DockPanel Name="myContentPresenterDockPanel">
     69                                 <ContentPresenter x:Name="myContentPresent" HorizontalAlignment="Center" Margin="0,20"
     70                                                   Content="{TemplateBinding Content}" TextBlock.Foreground="Black" TextBlock.FontWeight="Bold"/>
     71                             </DockPanel>
     72                         </Grid>
     73                         <!--control template-->
     74                         <ControlTemplate.Triggers>
     75                             <!--mouse over trigger-->
     76                             <Trigger Property="IsMouseOver" Value="True">
     77                                 <!--rectangle stroke-->
     78                                 <Setter Property="Rectangle.Stroke" TargetName="outerRectangle"
     79                                         Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
     80                                 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/>
     81                             </Trigger>
     82                             <!--Mouse focused trigger-->
     83                             <Trigger Property="IsFocused" Value="True">
     84                                 <Setter Property="Rectangle.Stroke" TargetName="innerRectangle"
     85                                         Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
     86                                 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/>
     87                             </Trigger>
     88                             <!--Event trigger mouse enter-->
     89                             <EventTrigger RoutedEvent="Mouse.MouseEnter">
     90                                 <!--actions-->
     91                                 <EventTrigger.Actions>
     92                                     <!--begin story board-->
     93                                     <BeginStoryboard Name="mouseEnterBeginStoryboard">
     94                                         <Storyboard>
     95                                             <!--animation-->
     96                                             <DoubleAnimation Storyboard.TargetName="glassCube"
     97                                                              Storyboard.TargetProperty=
     98                                                              "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
     99                                                              By="-0.2" Duration="0:0:0.5" />
    100                                             <DoubleAnimation Storyboard.TargetName="glassCube"
    101                                                              Storyboard.TargetProperty=
    102                                                              "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
    103                                                              By="-0.2" Duration="0:0:0.5" />
    104                                         </Storyboard>
    105                                     </BeginStoryboard>
    106                                 </EventTrigger.Actions>
    107                             </EventTrigger>
    108                             <!--event trigger mouse leave-->
    109                             <EventTrigger RoutedEvent="Mouse.MouseLeave">
    110                                 <EventTrigger.Actions>
    111                                     <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/>
    112                                 </EventTrigger.Actions>
    113                             </EventTrigger>
    114                             <!--event trigger button click-->
    115                             <EventTrigger RoutedEvent="Button.Click">
    116                                 <EventTrigger.Actions>
    117                                     <BeginStoryboard>
    118                                         <Storyboard>
    119                                             <DoubleAnimation Storyboard.TargetName="glassCube"
    120                                                              Storyboard.TargetProperty=
    121                                                              "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)"
    122                                                              By="360" Duration="0:0:0.5"/>
    123                                         </Storyboard>
    124                                     </BeginStoryboard>
    125                                 </EventTrigger.Actions>
    126                             </EventTrigger>
    127                         </ControlTemplate.Triggers>
    128                     </ControlTemplate>
    129                 </Setter.Value>
    130             </Setter>
    131         </Style>
    132 
    133         <Style TargetType="Label">
    134             <Setter Property="FontWeight" Value="Bold"/>
    135         </Style>
    136         <Style TargetType="TextBox">
    137             <Setter Property="Background" Value="LightCyan"/>
    138         </Style>
    139     </Window.Resources>
    140     
    View Code

    因为我们之前定义好的模板,我们直接调用即可,这些方法我们也可以运用到其他的设计中。这样做的目的是大大的缩短了我们设计的时间。

    最后完整码如下:

    XAML:

      1 <Window x:Class="SearilPort.MainWindow"
      2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4         Title="MainWindow" Height="350" Width="525" Background="LightSkyBlue">
      5     <Window.Resources>
      6         <!--define glass gradient stop resource-->
      7         <GradientStopCollection x:Key="myGradientStopResource">
      8             <GradientStop Color="WhiteSmoke" Offset="0.2"/>
      9             <GradientStop Color="Transparent" Offset="0.4"/>
     10             <GradientStop Color="WhiteSmoke" Offset="0.5"/>
     11             <GradientStop Color="Transparent" Offset=" 0.75"/>
     12             <GradientStop Color="WhiteSmoke" Offset="0.9"/>
     13             <GradientStop Color="Transparent" Offset=" 1.0"/>
     14         </GradientStopCollection>
     15 
     16         <!--define gradient brush resource-->
     17         <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75"
     18                              GradientStops="{StaticResource myGradientStopResource }"/>
     19 
     20         <!--background brush resource-->
     21         <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1">
     22             <GradientStop Color="Gray" Offset="0"/>
     23             <GradientStop Color="Cyan" Offset="0.5"/>
     24             <GradientStop Color="Gold" Offset="1.0"/>
     25         </LinearGradientBrush>
     26 
     27         <!--define button options-->
     28         <Style TargetType="Button">
     29             <!--define button background-->
     30             <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/>
     31             <!--define button template-->
     32             <Setter Property="Template">
     33                 <Setter.Value>
     34                     <!--target type is button-->
     35                     <ControlTemplate TargetType="{x:Type Button}">
     36                         <Grid Margin="-1,0,-10,1">
     37                             <!--outline rectangle-->
     38                             <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch"
     39                                        VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}"
     40                                        RadiusX="10" RadiusY="10" StrokeThickness="5" Fill="Transparent"/>
     41                             <!--inner rectangle-->
     42                             <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"
     43                                        VerticalAlignment="Stretch" Stroke="Transparent"
     44                                        StrokeThickness="5" Fill="{TemplateBinding Background}"
     45                                        RadiusX="10" RadiusY="10"/>
     46                             <!--glass rectangle-->
     47                             <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"
     48                                        VerticalAlignment="Stretch" StrokeThickness="1"
     49                                        RadiusX="5" RadiusY="5" Opacity="0" 
     50                                        Fill="{StaticResource myGlassBrushResource}"
     51                                        RenderTransformOrigin="0.5,0.5">
     52                                 <!--rectangle stroke-->
     53                                 <Rectangle.Stroke>
     54                                     <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1">
     55                                         <LinearGradientBrush.GradientStops>
     56                                             <GradientStop Color="LightBlue" Offset="0.0"/>
     57                                             <GradientStop Color="Gray" Offset="1.0"/>
     58                                         </LinearGradientBrush.GradientStops>
     59                                     </LinearGradientBrush>
     60                                 </Rectangle.Stroke>
     61                                 <!--glass rectangle render transform-->
     62                                 <Rectangle.RenderTransform>
     63                                     <TransformGroup>
     64                                         <!--To stretch or contact horizontally or vertially-->
     65                                         <ScaleTransform/>
     66                                         <!--rotate transform by angles-->
     67                                         <RotateTransform/>
     68                                     </TransformGroup>
     69                                 </Rectangle.RenderTransform>
     70                             </Rectangle>
     71                             <!--dock panel-->
     72                             <DockPanel Name="myContentPresenterDockPanel">
     73                                 <ContentPresenter x:Name="myContentPresent" HorizontalAlignment="Center" Margin="0,20"
     74                                                   Content="{TemplateBinding Content}" TextBlock.Foreground="Black" TextBlock.FontWeight="Bold"/>
     75                             </DockPanel>
     76                         </Grid>
     77                         <!--control template-->
     78                         <ControlTemplate.Triggers>
     79                             <!--mouse over trigger-->
     80                             <Trigger Property="IsMouseOver" Value="True">
     81                                 <!--rectangle stroke-->
     82                                 <Setter Property="Rectangle.Stroke" TargetName="outerRectangle"
     83                                         Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
     84                                 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/>
     85                             </Trigger>
     86                             <!--Mouse focused trigger-->
     87                             <Trigger Property="IsFocused" Value="True">
     88                                 <Setter Property="Rectangle.Stroke" TargetName="innerRectangle"
     89                                         Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
     90                                 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/>
     91                             </Trigger>
     92                             <!--Event trigger mouse enter-->
     93                             <EventTrigger RoutedEvent="Mouse.MouseEnter">
     94                                 <!--actions-->
     95                                 <EventTrigger.Actions>
     96                                     <!--begin story board-->
     97                                     <BeginStoryboard Name="mouseEnterBeginStoryboard">
     98                                         <Storyboard>
     99                                             <!--animation-->
    100                                             <DoubleAnimation Storyboard.TargetName="glassCube"
    101                                                              Storyboard.TargetProperty=
    102                                                              "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
    103                                                              By="-0.2" Duration="0:0:0.5" />
    104                                             <DoubleAnimation Storyboard.TargetName="glassCube"
    105                                                              Storyboard.TargetProperty=
    106                                                              "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
    107                                                              By="-0.2" Duration="0:0:0.5" />
    108                                         </Storyboard>
    109                                     </BeginStoryboard>
    110                                 </EventTrigger.Actions>
    111                             </EventTrigger>
    112                             <!--event trigger mouse leave-->
    113                             <EventTrigger RoutedEvent="Mouse.MouseLeave">
    114                                 <EventTrigger.Actions>
    115                                     <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/>
    116                                 </EventTrigger.Actions>
    117                             </EventTrigger>
    118                             <!--event trigger button click-->
    119                             <EventTrigger RoutedEvent="Button.Click">
    120                                 <EventTrigger.Actions>
    121                                     <BeginStoryboard>
    122                                         <Storyboard>
    123                                             <DoubleAnimation Storyboard.TargetName="glassCube"
    124                                                              Storyboard.TargetProperty=
    125                                                              "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)"
    126                                                              By="360" Duration="0:0:0.5"/>
    127                                         </Storyboard>
    128                                     </BeginStoryboard>
    129                                 </EventTrigger.Actions>
    130                             </EventTrigger>
    131                         </ControlTemplate.Triggers>
    132                     </ControlTemplate>
    133                 </Setter.Value>
    134             </Setter>
    135         </Style>
    136 
    137         <Style TargetType="Label">
    138             <Setter Property="FontWeight" Value="Bold"/>
    139         </Style>
    140         <Style TargetType="TextBox">
    141             <Setter Property="Background" Value="LightCyan"/>
    142         </Style>
    143     </Window.Resources>
    144     <Grid Margin="0,-2,0,2">
    145         <TextBox HorizontalAlignment="Left" VerticalAlignment="Top" VerticalScrollBarVisibility="Auto" 
    146                  Width="324" Height="119" Name="m_textBox1" Margin="10,40,0,0"/>
    147         <TextBox Name="m_textBox2" HorizontalAlignment="Left" VerticalScrollBarVisibility="Auto" 
    148                  Height="106" Margin="10,195,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="324"/>
    149 
    150         <ComboBox Name="myCOM" Margin="0,58,38,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="90" Height="22"/>
    151         <ComboBox Name="myBaudRate" Margin="0,116,38,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="90" Height="22"/>
    152 
    153         <Label Content="COM" HorizontalAlignment="Left" Margin="389,27,0,0" VerticalAlignment="Top" Width="62"/>
    154         <Label Content="BaudRate" HorizontalAlignment="Left" Margin="389,85,0,0" VerticalAlignment="Top"/>
    155         <Label Content="Received Data" HorizontalAlignment="Left" Margin="15,10,0,0" VerticalAlignment="Top" Width="97"/>
    156         <Label Content="Transmit Data" HorizontalAlignment="Left" Margin="15,164,0,0" VerticalAlignment="Top" Width="97"/>
    157 
    158         <Button Content="Clear" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="51" Margin="0,0,22,80" Click="Btn2_Click" Height="58"/>
    159         <Button Content="Open" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="51" Margin="0,0,95,81" Click="Btn1_Click" 
    160                 Name="myBtn" RenderTransformOrigin="0.5,0.5" Height="57"/>
    161 
    162     </Grid>
    163 </Window>
    XAML

    CS:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading.Tasks;
      6 using System.Windows;
      7 using System.Windows.Controls;
      8 using System.Windows.Data;
      9 using System.Windows.Documents;
     10 using System.Windows.Input;
     11 using System.Windows.Media;
     12 using System.Windows.Media.Imaging;
     13 using System.Windows.Navigation;
     14 using System.Windows.Shapes;
     15 using System.IO.Ports;
     16 using System.Security.Cryptography;
     17 
     18 namespace SearilPort
     19 {
     20     /// <summary>
     21     /// Interaction logic for MainWindow.xaml
     22     /// </summary>
     23     public partial class MainWindow : Window
     24     {
     25         SerialPort myPort = new SerialPort();
     26         bool serialState;
     27         public MainWindow()
     28         {
     29             InitializeComponent();
     30             myComboxs();
     31         }
     32         private void myComboxs()
     33         {
     34             myCOM.Items.Add("COM0");
     35             myCOM.Items.Add("COM1");
     36             myCOM.Items.Add("COM2");
     37             myCOM.Items.Add("COM3");
     38             myCOM.Items.Add("COM4");
     39             myCOM.SelectedIndex = myCOM.Items.IndexOf("COM1");
     40             myBaudRate.Items.Add("2400");
     41             myBaudRate.Items.Add("4800");
     42             myBaudRate.Items.Add("9600");
     43             myBaudRate.Items.Add("38400");
     44             myBaudRate.Items.Add("115200");
     45             myBaudRate.SelectedIndex = myBaudRate.Items.IndexOf("9600");
     46             serialState = false;
     47             myPort.DataReceived += DataReceived;
     48         }
     49         private void Btn1_Click(object sender, RoutedEventArgs e)
     50         {
     51             try
     52             {
     53                 if (serialState == false)
     54                 {
     55                     if(myPort.IsOpen)
     56                     {
     57                         myPort.Close();
     58                     }
     59                     myPort.BaudRate = int.Parse(myBaudRate.Text);
     60                     myPort.DataBits = 8;
     61                     myPort.PortName = myCOM.Text;
     62                     myPort.Open();
     63                     serialState = true;
     64                     m_textBox1.Text = "Serial Port is Opened...
    ";
     65                     myBtn.Content = "Closed";
     66                 }
     67                 else
     68                 {
     69                     if (myPort.IsOpen)
     70                     {
     71                         myPort.Close();
     72                     }
     73                     serialState = false;
     74                     m_textBox1.Text = "Serial Port is Closed...
    ";
     75                     m_textBox2.Text = "";
     76                     myBtn.Content = "Open";
     77                 }
     78             }
     79             catch(Exception ex)
     80             {
     81                 MessageBox.Show(ex.Message);
     82             }
     83         }
     84         private void Btn2_Click(object sender, RoutedEventArgs e)
     85         {
     86             m_textBox1.Text = "";
     87             m_textBox2.Text = "";
     88         }
     89         private void DataReceived(object sender,SerialDataReceivedEventArgs e)
     90         {
     91             try
     92             {
     93                 byte[] inbuf = new byte[8];
     94                 byte[] output = new byte[16];
     95                 myPort.Read(inbuf, 0, inbuf.Length);
     96                 string str = System.Text.Encoding.Default.GetString(inbuf);
     97                 this.Dispatcher.Invoke(new Action(() =>
     98                     {
     99                         foreach (byte i in inbuf)
    100                         {
    101                             m_textBox1.Text += i.ToString("X2");
    102                         }
    103                         m_textBox1.Text += "
    ";
    104                         using (var aes = new RijndaelManaged())
    105                         {
    106                             aes.Key = new byte[] { 0x1F, 0x54, 0x52, 0x6A, 0x73, 0x93, 0x58, 0x9E, 0x4B, 0xCF, 0xFB, 0xAE, 0xFC, 0x97, 0x59, 0x3E };
    107                             aes.IV = new byte[16];
    108                             aes.Padding = PaddingMode.None;
    109                             for (int i = 0; i < 8; i++)
    110                             {
    111                                 output[i] = inbuf[i];
    112                             }
    113                             for (byte i = 8; i < 16; i++)
    114                             {
    115                                 output[i] = (byte)(output[i - 8] ^ output[i - 4]);
    116                             }
    117                             m_textBox1.Text += "16 byte ids:
    ";
    118                             foreach (byte i in output)
    119                                 m_textBox1.Text += i.ToString("X2");
    120                             m_textBox1.Text += "
    ";
    121                             var cryptoTransform = aes.CreateEncryptor();
    122                             byte[] resultBuffer = cryptoTransform.TransformFinalBlock(output, 0, output.Length);
    123                             m_textBox2.Text += "SerialNo.=
    ";
    124                             foreach (byte i in resultBuffer)
    125                             {
    126                                 m_textBox2.Text += i.ToString("X2");
    127                             }
    128                             m_textBox2.Text += "
    ";
    129                         }
    130                         myPort.Write(output,0,output.Length);
    131                         m_textBox1.ScrollToEnd();
    132                         m_textBox2.ScrollToEnd();
    133                     }));
    134             }
    135             catch(Exception ex)
    136             {
    137                 MessageBox.Show(ex.Message);
    138             }
    139         }
    140     }
    141 }
    CS

    编译运行:

    End.

    谢谢.

  • 相关阅读:
    管理者应有意识地提高以下八项能力
    weblogic调优
    嵌入式软件的基本测试方法
    LoadRunner Interview Questions
    测试类型概念解析
    要是下次他们放手机时戴了手套怎么办?
    外企面试智力题
    贴张我家养的狗狗们的照片!
    一样一句
    软件测试工程师面试英语
  • 原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/12015181.html
Copyright © 2011-2022 走看看