C#—串口和网口之间的通信详解

C#---串口和网口之间的通信

串口转网口、网口转串口,就是将网口发送来的数据包发送给串口设备,将串口设备返回的数据转发给网口客户端。

在C#中,将串口数据转换为网络数据并发送到网络,通常涉及以下步骤:

  1. 创建一个TCP/UDP客户端,以连接到远程服务器。

  2. 在串口接收中继站数据时,解析该数据以确定其格式和内容。

  3. 将解析后的数据打包成符合网络协议的格式。

  4. 使用网络客户端发送数据。

实现串口网口的转换实例

接下来就为大家介绍一下本次的实例:

  1. 当串口事件接收到串口设备发来的消息时,将接收到的消息通过tcp进行发出给客户端,并且亮灯。

  2. 当tcp服务器接收到网口客户端的消息时,将接收到的消息通过串口发出给串口设备,并且亮灯。

  3. 项目中还有心跳机制,检测串口设备,将设备参数写入INI格式地址等操作。

提示: 本文中用到的serialPort1是winform的窗体控件

一、读取配置文件并设置串口网口对象

cs 复制代码
public partial class Form1 : Form
{
    IniHelper Ini;
    string[] botlvs = new string[] { "1200", "4800", "9600" ,"13200"};

    TcpListener listen;
    List<TcpClient> lists = new List<TcpClient>(); // 存放所有客户端
    Dictionary<TcpClient, DateTime> HearDic = new Dictionary<TcpClient, DateTime>(); // 存放心跳

    int heartTime=0,heartConnent=0;
    bool whetherHeart;

    public Form1()
    {
        InitializeComponent();

        // 1 读取配置文件
        string dirPath = Path.Combine(Application.StartupPath,"File");
        string filePath = Path.Combine(dirPath, "Setting.ini");
        Ini = new IniHelper(filePath);

        // 2 添加串口
        comboBox1.Items.AddRange(SerialPort.GetPortNames()); // 获取所有串口 拼接在下拉框的items中
        comboBox2.Items.AddRange(botlvs); // 添加波特率数组
        comboBox2.Items.Add("自定义"); // 添加一个
        comboBox3.Items.AddRange(new string[] { "5", "6", "7", "8" });
        comboBox4.Items.AddRange(new string[] {"无","奇校检","偶效验"});
        comboBox5.Items.AddRange(new string[] {"无","1","2","1.5"});

        this.serialPort1.DataReceived += SerialPort1_DataReceived;

        // 3 处理界面默认值
        readSetting();

        // 4 开始串口通信
        startChuanKou();

        // 5 开始网口通信
        startTCP();

    }
}

二、处理界面默认值

cs 复制代码
/// <summary>
/// 配置串口默认值
/// </summary>
void readSetting()
{
    // 配置串口
    comboBox1.SelectedItem = Ini.Read("Serialport", "name");
    string botelv = Ini.Read("Serialport", "botelv", "9601");
    int botelvIndex = Array.IndexOf(botlvs, botelv); // 获取botelv在数组里面的索引值
    if (botelvIndex != -1)
    {
        comboBox2.SelectedIndex = botelvIndex;
        comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
    }
    else
    {
        // 波特率在数组里面 自定义波特率情况
        comboBox2.DropDownStyle = ComboBoxStyle.DropDown; // 可编辑的下拉框
                                                          // DropDownList 不可编辑的下拉框
        comboBox2.Text = botelv;
    }
    // 处理数据位
    comboBox3.SelectedItem = Ini.Read("Serialport", "databit", "8");
    // 处理奇偶校检位
    comboBox4.SelectedIndex = Ini.Read("Serialport", "parity", 0);
    comboBox5.SelectedIndex = Ini.Read("Serialport", "stopbit", 0);

    comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
    comboBox3.DropDownStyle = ComboBoxStyle.DropDownList;
    comboBox4.DropDownStyle = ComboBoxStyle.DropDownList;
    comboBox5.DropDownStyle = ComboBoxStyle.DropDownList;

    // 网口数据的读取
    textBox3.Text = Ini.Read("NetWork", "port", "8080");
    if (Ini.Read("NetWork", "heartOn", false))
    {
        radioButton1.Checked = true;
    }
    else
    {
        radioButton1.Checked = true;
    }
    textBox4.Text = Ini.Read("NetWork", "heartTime", "60000"); 
    textBox5.Text = Ini.Read("NetWork", "heartData", ""); 
    checkBox1.Checked = Ini.Read("NetWork", "heartHex", false);

    heartConnent = int.Parse(textBox5.Text);
    heartTime = int.Parse(textBox4.Text);
    whetherHeart = checkBox1.Checked;
}

三、配置串口数据

cs 复制代码
/// <summary>
/// 配置串口数据
/// </summary>
void startChuanKou()
{
    // 配置串口对象
    try
    {
        this.serialPort1.PortName = comboBox1.Text;
        this.serialPort1.BaudRate = int.Parse(comboBox2.Text);
        this.serialPort1.DataBits = int.Parse(comboBox3.Text);
        this.serialPort1.StopBits = (StopBits)comboBox5.SelectedIndex;
        this.serialPort1.Parity = (Parity)comboBox4.SelectedIndex;

        this.serialPort1.Open();
        // 亮灯
        this.panel1.BackColor = Color.Green;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        if (this.serialPort1.IsOpen)
        {
            serialPort1.Close();
            // 灭灯
            this.panel1.BackColor = Color.DarkGray;
        }
    }
}

四、实现tcp网口通信

cs 复制代码
/// <summary>
/// TCP网口通信
/// </summary>
void startTCP()
{
    if (!int.TryParse(textBox3.Text,out int port) || port<1 || port>65563)
    {
        MessageBox.Show("请输入正确端口号!!!","提示");
    }
    // 开启服务器 接收客户端
    listen = new TcpListener(System.Net.IPAddress.Any, port);
    listen.Start(99); // 开启监听
    panel2.BackColor = Color.Green;

    // 把多个客户端接收到数组里面
    new Task(() =>
    {
        while (true)
        {
            try
            {
                // 接收客户端
                TcpClient c1 = listen.AcceptTcpClient();
                if (!lists.Contains(c1) && !HearDic.ContainsKey(c1))
                {
                    // 把客户端添加到数里面 群发需要
                    if (whetherHeart)
                    {
                        lists.Add(c1);
                        HearDic.Add(c1, DateTime.Now);
                    }
                    else lists.Add(c1);

                    // 接受客户端发来的消息
                    tcpReceive(c1);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                foreach (var c in lists)
                {
                    c.Close();
                }
                panel2.BackColor = Color.Green;
            }
        }
    }).Start();
}

/// <summary>
/// 接收网口消息
/// </summary>
void tcpReceive(TcpClient client)
{
    NetworkStream stream = client.GetStream();
    Task.Run(() =>
    {
        byte[] body = new byte[1024];
        while (client.Connected)
        {
            try
            {
                int count = stream.Read(body, 0, body.Length);
                if (count != 0)
                {
                    if (whetherHeart&& body[0] == heartConnent)
                    {
                        try
                        {
                            if (DateTime.Now - HearDic[client] <= new TimeSpan(0, 0, heartTime))
                            {
                                HearDic[client] = DateTime.Now;
                            }
                            else
                            {
                                HearDic.Remove(client);
                                lists.Remove(client);
                                MessageBox.Show(client.Client.RemoteEndPoint.ToString() + "断开");
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                            break;
                        }
                    }
                    else
                    {
                        serialPort1.Write(body, 0, body.Length);
                        网口接收消息亮灯();
                    }
                }
                else
                {
                    HearDic.Remove(client);
                    lists.Remove(client);
                }
                
            }
            catch (Exception ex)
            {
                listen.Start();
                MessageBox.Show(ex.Message);
                break;
            }
        }
    });
}
/// <summary>
/// 是否设置心跳
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
    if (checkBox1.Checked)
        whetherHeart = true;
    else whetherHeart = false;
}

五、实现接收串口数据发送给网口并且亮灯

cs 复制代码
/// <summary>
/// 接收串口数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        byte[] bs = new byte[serialPort1.WriteBufferSize]; // 定义一个字节数组
        int count = serialPort1.Read(bs, 0, bs.Length); // 读取数据到字节数组里面
        if (count == 0)
        {
            // 关闭串口
            if (this.serialPort1.IsOpen)
            {
                serialPort1.Close();
                // 灭灯
                this.panel1.BackColor = Color.DarkGray;
            }
        }
        // 1 接收到1串口数据 需要让panel3更改颜色(亮灯) 封装方法控制效果
        串口接收消息亮灯();

        // 2 转发给所有客户端数据 串口转网口就是把串口数据通过网络转给其他客户端
        foreach (var item in lists)
        {
            item.GetStream().Write(bs,0,bs.Length);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        if (this.serialPort1.IsOpen)
        {
            serialPort1.Close();
            // 灭灯
            this.panel1.BackColor = Color.DarkGray;
        }
    }
}

/// <summary>
/// 串口消息亮灯
/// </summary>
void 串口接收消息亮灯()
{
    this.Invoke(new Action(async () => 
    {
        this.textBox1.Text = (int.Parse(this.textBox1.Text) + 1).ToString();
        // 亮灯
        panel3.BackColor = Color.Green;
        await Task.Delay(200);
        panel3.BackColor = Color.Gray;

    }));
}

INI格式操作对象

cs 复制代码
public class IniHelper
{
    public string FileName { get; set; }
    public IniHelper(string name)
    {
        this.FileName = name;
    }

    // 1 先导入C语言读取ini文件的方法

    // GetPrivateProfileString() 获取ini配置文件的数据
    // static 静态的变量 只能生命在当前文件中,不能在其他源文件进行使用。
    // extern 用来声明外部的符号 可以跨文件使用。
    [DllImport("Kernel32.dll")] //导入方法所在dll文件
    public static extern Int32 GetPrivateProfileString(
        string sectionName, //段名 
        string keyName,//键名
        string defaultName,//当键不存在默认值。
        StringBuilder returnValue,// 读取到数据
        uint size,// 读取数据的大小
        string fileName// ini文件路径
        );


    // 2 添加加写入ini文件的C方法
    [DllImport("Kernel32.dll")]
    public static extern Int32 WritePrivateProfileString(
      string sectionName, //段名 
      string keyName,//键名
      string value,//设置的值
      string fileName// ini文件路径
      );



    // 不直接使用上面的两个C语言的方法 再封装到方法中
    // 读取ini数据的方法
    // ReadDate("Second","B","Setting.ini") "10"
    public static string ReadDate(string sectionName, string keyName, string fileName)
    {
        StringBuilder sb = new StringBuilder(512); //512是存储的大小
        GetPrivateProfileString(sectionName, keyName, string.Empty, sb, 512, fileName);

        return sb.ToString();

    }

    /// <summary>
    /// 读取数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">键名</param>
    /// <returns>string</returns>
    public string Read(string sectionName, string keyName)
    {
        return ReadDate(sectionName, keyName, this.FileName);

    }


    /// <summary>
    /// 读取数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">键名</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>string</returns>
    public string Read(string sectionName, string keyName, string defaultValue)
    {
        string v = Read(sectionName, keyName);
        if (string.IsNullOrEmpty(v))
        {
            return defaultValue;
        }
        return v;
    }

    /// <summary>
    /// 读取数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">键名</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>int</returns>
    public int Read(string sectionName, string keyName, int defaultValue)
    {
        string v = Read(sectionName, keyName);
        if (int.TryParse(v, out int value))
        {
            return value;
        }
        else
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// 读取数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">键名</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>bool</returns>
    public bool Read(string sectionName, string keyName, bool defaultValue)
    {
        string v = Read(sectionName, keyName);
        if (bool.TryParse(v, out bool value))
        {
            return value;
        }
        else
        {
            // 不能转成bool
            if (v == "1" || v == "OK" || v == "ON" || v == "YES")
            {
                return true;
            }
            else if (v == "0" || v == "NO" || v == "OFF" || v.ToUpper() == "OFF")
            {
                // 如果值为以上几种情况 值为false
                return false;
            }
            else
            {
                return defaultValue;
            }
        }
    }


    /// <summary>
    /// 读取数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">键名</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>double</returns>
    public double Read(string sectionName, string keyName, double defaultValue)
    {
        string v = Read(sectionName, keyName);
        if (double.TryParse(v, out double value))
        {
            return value;
        }
        else
        {
            return defaultValue;
        }
    }



    public static int WriteData(string s1, string k1, string v, string file)
    {
        return WritePrivateProfileString(s1, k1, v, file);
    }

    /// <summary>
    /// 写入数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">健名</param>
    /// <param name="value">值</param>
    /// <returns>int</returns>
    public int Write(string sectionName, string keyName, string value)
    {
        return WriteData(sectionName, keyName, value, this.FileName);
    }

    /// <summary>
    /// 写入数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">健名</param>
    /// <param name="value">值</param>
    /// <returns>int</returns>
    public int Write(string sectionName, string keyName, int value)
    {
        return WriteData(sectionName, keyName, value.ToString(), this.FileName);
    }

    /// <summary>
    /// 写入数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">健名</param>
    /// <param name="value">值</param>
    /// <returns>int</returns>
    public int Write(string sectionName, string keyName, bool value)
    {
        return WriteData(sectionName, keyName, value ? "1" : "0", this.FileName);
    }

    /// <summary>
    /// 写入数据
    /// </summary>
    /// <param name="sectionName">段名</param>
    /// <param name="keyName">健名</param>
    /// <param name="value">值</param>
    /// <returns>int</returns>
    public int Write(string sectionName, string keyName, DateTime value)
    {
        return WriteData(sectionName, keyName, value.ToString("yyyy-MM-dd HH-mm:ss"), this.FileName);
    }

}

完整代码

cs 复制代码
public partial class Form1 : Form
{
    IniHelper Ini;
    string[] botlvs = new string[] { "1200", "4800", "9600" ,"13200"};

    TcpListener listen;
    List<TcpClient> lists = new List<TcpClient>(); // 存放所有客户端
    Dictionary<TcpClient, DateTime> HearDic = new Dictionary<TcpClient, DateTime>(); // 存放心跳

    int heartTime=0,heartConnent=0;
    bool whetherHeart;

    public Form1()
    {
        InitializeComponent();

        // 1 读取配置文件
        string dirPath = Path.Combine(Application.StartupPath,"File");
        string filePath = Path.Combine(dirPath, "Setting.ini");
        Ini = new IniHelper(filePath);

        // 2 添加串口
        comboBox1.Items.AddRange(SerialPort.GetPortNames()); // 获取所有串口 拼接在下拉框的items中
        comboBox2.Items.AddRange(botlvs); // 添加波特率数组
        comboBox2.Items.Add("自定义"); // 添加一个
        comboBox3.Items.AddRange(new string[] { "5", "6", "7", "8" });
        comboBox4.Items.AddRange(new string[] {"无","奇校检","偶效验"});
        comboBox5.Items.AddRange(new string[] {"无","1","2","1.5"});

        this.serialPort1.DataReceived += SerialPort1_DataReceived;

        // 3 处理界面默认值
        readSetting();

        // 4 开始串口通信
        startChuanKou();

        // 5 开始网口通信
        startTCP();

    }

    
    /// <summary>
    /// TCP网口通信
    /// </summary>
    void startTCP()
    {
        if (!int.TryParse(textBox3.Text,out int port) || port<1 || port>65563)
        {
            MessageBox.Show("请输入正确端口号!!!","提示");
        }
        // 开启服务器 接收客户端
        listen = new TcpListener(System.Net.IPAddress.Any, port);
        listen.Start(99); // 开启监听
        panel2.BackColor = Color.Green;

        // 把多个客户端接收到数组里面
        new Task(() =>
        {
            while (true)
            {
                try
                {
                    // 接收客户端
                    TcpClient c1 = listen.AcceptTcpClient();
                    if (!lists.Contains(c1) && !HearDic.ContainsKey(c1))
                    {
                        // 把客户端添加到数里面 群发需要
                        if (whetherHeart)
                        {
                            lists.Add(c1);
                            HearDic.Add(c1, DateTime.Now);
                        }
                        else lists.Add(c1);

                        // 接受客户端发来的消息
                        tcpReceive(c1);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    foreach (var c in lists)
                    {
                        c.Close();
                    }
                    panel2.BackColor = Color.Green;
                }
            }
        }).Start();
    }

    /// <summary>
    /// 接收网口消息
    /// </summary>
    void tcpReceive(TcpClient client)
    {
        NetworkStream stream = client.GetStream();
        Task.Run(() =>
        {
            byte[] body = new byte[1024];
            while (client.Connected)
            {
                try
                {
                    int count = stream.Read(body, 0, body.Length);
                    if (count != 0)
                    {
                        if (whetherHeart&& body[0] == heartConnent)
                        {
                            try
                            {
                                if (DateTime.Now - HearDic[client] <= new TimeSpan(0, 0, heartTime))
                                {
                                    HearDic[client] = DateTime.Now;
                                }
                                else
                                {
                                    HearDic.Remove(client);
                                    lists.Remove(client);
                                    MessageBox.Show(client.Client.RemoteEndPoint.ToString() + "断开");
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                                break;
                            }
                        }
                        else
                        {
                            serialPort1.Write(body, 0, body.Length);
                            网口接收消息亮灯();
                        }
                    }
                    else
                    {
                        HearDic.Remove(client);
                        lists.Remove(client);
                    }
                    
                }
                catch (Exception ex)
                {
                    listen.Start();
                    MessageBox.Show(ex.Message);
                    break;
                }
            }
        });
    }

    /// <summary>
    /// 配置串口数据
    /// </summary>
    void startChuanKou()
    {
        // 配置串口对象
        try
        {
            this.serialPort1.PortName = comboBox1.Text;
            this.serialPort1.BaudRate = int.Parse(comboBox2.Text);
            this.serialPort1.DataBits = int.Parse(comboBox3.Text);
            this.serialPort1.StopBits = (StopBits)comboBox5.SelectedIndex;
            this.serialPort1.Parity = (Parity)comboBox4.SelectedIndex;

            this.serialPort1.Open();
            // 亮灯
            this.panel1.BackColor = Color.Green;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            if (this.serialPort1.IsOpen)
            {
                serialPort1.Close();
                // 灭灯
                this.panel1.BackColor = Color.DarkGray;
            }
        }
    }

    /// <summary>
    /// 配置串口默认值
    /// </summary>
    void readSetting()
    {
        // 配置串口
        comboBox1.SelectedItem = Ini.Read("Serialport", "name");
        string botelv = Ini.Read("Serialport", "botelv", "9601");
        int botelvIndex = Array.IndexOf(botlvs, botelv); // 获取botelv在数组里面的索引值
        if (botelvIndex != -1)
        {
            comboBox2.SelectedIndex = botelvIndex;
            comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
        }
        else
        {
            // 波特率在数组里面 自定义波特率情况
            comboBox2.DropDownStyle = ComboBoxStyle.DropDown; // 可编辑的下拉框
                                                              // DropDownList 不可编辑的下拉框
            comboBox2.Text = botelv;
        }
        // 处理数据位
        comboBox3.SelectedItem = Ini.Read("Serialport", "databit", "8");
        // 处理奇偶校检位
        comboBox4.SelectedIndex = Ini.Read("Serialport", "parity", 0);
        comboBox5.SelectedIndex = Ini.Read("Serialport", "stopbit", 0);

        comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
        comboBox3.DropDownStyle = ComboBoxStyle.DropDownList;
        comboBox4.DropDownStyle = ComboBoxStyle.DropDownList;
        comboBox5.DropDownStyle = ComboBoxStyle.DropDownList;

        // 网口数据的读取
        textBox3.Text = Ini.Read("NetWork", "port", "8080");
        if (Ini.Read("NetWork", "heartOn", false))
        {
            radioButton1.Checked = true;
        }
        else
        {
            radioButton1.Checked = true;
        }
        textBox4.Text = Ini.Read("NetWork", "heartTime", "60000"); 
        textBox5.Text = Ini.Read("NetWork", "heartData", ""); 
        checkBox1.Checked = Ini.Read("NetWork", "heartHex", false);

        heartConnent = int.Parse(textBox5.Text);
        heartTime = int.Parse(textBox4.Text);
        whetherHeart = checkBox1.Checked;
    }

    /// <summary>
    /// 接收串口数据
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            byte[] bs = new byte[serialPort1.WriteBufferSize]; // 定义一个字节数组
            int count = serialPort1.Read(bs, 0, bs.Length); // 读取数据到字节数组里面
            if (count == 0)
            {
                // 关闭串口
                if (this.serialPort1.IsOpen)
                {
                    serialPort1.Close();
                    // 灭灯
                    this.panel1.BackColor = Color.DarkGray;
                }
            }
            // 1 接收到1串口数据 需要让panel3更改颜色(亮灯) 封装方法控制效果
            串口接收消息亮灯();

            // 2 转发给所有客户端数据 串口转网口就是把串口数据通过网络转给其他客户端
            foreach (var item in lists)
            {
                item.GetStream().Write(bs,0,bs.Length);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            if (this.serialPort1.IsOpen)
            {
                serialPort1.Close();
                // 灭灯
                this.panel1.BackColor = Color.DarkGray;
            }
        }
    }

    /// <summary>
    /// 串口消息亮灯
    /// </summary>
    void 串口接收消息亮灯()
    {
        this.Invoke(new Action(async () => 
        {
            this.textBox1.Text = (int.Parse(this.textBox1.Text) + 1).ToString();
            // 亮灯
            panel3.BackColor = Color.Green;
            await Task.Delay(200);
            panel3.BackColor = Color.Gray;

        }));
    }

    /// <summary>
    /// 网口消息亮灯
    /// </summary>
    void 网口接收消息亮灯()
    {
        this.Invoke(new Action(async () =>
        {
            this.textBox2.Text = (int.Parse(this.textBox2.Text) + 1).ToString();
            // 亮灯
            panel4.BackColor = Color.Green;
            await Task.Delay(200);
            panel4.BackColor = Color.Gray;

        }));
    }


    /// <summary>
    /// 是否设置心跳
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void radioButton1_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox1.Checked)
            whetherHeart = true;
        else whetherHeart = false;
    }

    /// <summary>
    /// 重启
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void button1_Click(object sender, EventArgs e)
    {
        // 关闭串口
        if (this.serialPort1.IsOpen)
        {
            serialPort1.Close();
        }
        // 灭灯
        this.panel1.BackColor = Color.Gray;
        // 停掉TCP
        foreach (var c in lists)
        {
            c.Close();
        }
        listen.Stop();
        panel2.BackColor = Color.Gray;

        await Task.Delay(1000);

        // 开启TCP
        startTCP();

        // 开启串口
        startChuanKou();


    }

    /// <summary>
    /// 保存
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button2_Click(object sender, EventArgs e)
    {

    }


    /// <summary>
    /// 波特率下拉框触发变化的时候调用
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (comboBox2.SelectedItem.ToString() == "自定义")
        {
            // 切换到自定义选项上
            comboBox2.DropDownStyle = ComboBoxStyle.DropDown;
        }
        else
        {
            comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
        }
    }
}
相关推荐
天启代理ip29 分钟前
HTTP隧道代理:互联网冲浪的隐形翅膀
服务器·网络·爬虫·网络协议·tcp/ip
6230_32 分钟前
关于HTTP通讯流程知识点补充—常见状态码及常见请求方式
前端·javascript·网络·网络协议·学习·http·html
合宙Luat1 小时前
合宙LuatOS开发板Core_Air780EP使用说明
单片机·嵌入式硬件·物联网·硬件工程·lua
手打猪大屁2 小时前
STM32——串口通信(发送/接收数据与中断函数应用)
经验分享·笔记·stm32·单片机·嵌入式硬件
日记成书2 小时前
【无线通信发展史⑨】1791年路易吉·伽伐尼-关于动物电的研究与1800年亚历山大·伏打伯爵-电池:伏打电池
网络·人工智能·学习·职场和发展·信息与通信
人工智障调包侠2 小时前
Linux 目录介绍
linux·运维·服务器
achirandliu3 小时前
SOME/IP 通信协议详细介绍
网络·网络协议·tcp/ip·some/ip
hakesashou3 小时前
python怎么输入中文
java·服务器·python
我晕死哦3 小时前
Anaconda 中遇到CondaHTTPError: HTTP 404 NOT FOUND for url的问题及解决办法
python·网络协议·http·pycharm
yyqzjw3 小时前
【STM32】cubemx配置GPIO
stm32·单片机·嵌入式硬件