C#中实现串口通讯和网口通讯(使用SerialPort和Socket类)

仅作自己学习使用


1 准备部份

串口通讯需要两个调试软件commix和Virtual Serial Port Driver,分别用于监视串口和创造虚拟串口。网口通讯需要一个网口调试助手,网络上有很多资源,我在这里采用的是微软商店中的TCP/UDP网络调试助手,其中也有和commix一样功能的串口调试模块。

第一个软件是这样的:

资源在这里:免费下载:Commix

也可以前往官网下载:Bwsensing--- Attitude is everything

点击Download即可


第二个软件是这样的:

官方下载链接:Virtual Serial Port Driver


第三个软件是这样的:

可以看到其实这个软件也有串口通讯调试的功能。

官方下载链接:TCP UDP网络调试助手

2 串口通讯

2.1 Xaml代码

界面做得很丑,能用就行,关键是原理:

html 复制代码
<Window x:Class="WPF_ZhaoXi_0205.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_ZhaoXi_0205"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="textBox_receive" Grid.Row="0" Grid.Column="0" FontSize="15" Margin="10" Text="接收窗口"/>
        <TextBox x:Name="textBox_send" Grid.Row="0" Grid.Column="1" FontSize="15" Margin="10" Text="发送窗口"/>
        <Button x:Name="button_open" Grid.Row="1" Grid.Column="0" Content="打开串口" Margin="10" Click="button_open_Click"/>
        <Button x:Name="button_recisive" Grid.Row="1" Grid.Column="1" Content="接收数据" Margin="10" Click="button_recisive_Click"/>
        <Button x:Name="button_send" Grid.Row="2" Grid.Column="0" Content="发送数据" Margin="10" Click="button_send_Click"/>
    </Grid>
</Window>

2.2 cs代码

csharp 复制代码
using System.IO.Ports;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF_ZhaoXi_0205
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // 声明一个串口对象
        SerialPort sp = null;

        public MainWindow()
        {
            InitializeComponent();

            // 实例化串口对象
            //sp = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            sp = new SerialPort();
           
            // 设置通讯的属性
            sp.PortName = "COM2";       // 串口名称
            sp.BaudRate = 9600;         // 波特率
            sp.Parity = Parity.None;    // 校验位
            sp.DataBits = 8;            // 数据位  
            sp.StopBits = StopBits.One; // 停止位 

            // 第二种接收数据的方式,被动接收,如称重,扫码枪等 
            sp.DataReceived += Sp_DataReceived;
        }

        /// <summary>
        /// 第二种数据接收的方式
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] bt1 = new byte[sp.BytesToRead];
            sp.Read(bt1, 0, bt1.Length);
            // 这里在异步线程处理了UI控件,而UI控件必须在主线程处理,因此要报错
            //textBox_recsive.Text = Encoding.ASCII.GetString(bt1);
            // 因此把这个语句放在UI线程(主线程进行)
            this.Dispatcher.Invoke(() =>
            { 
                textBox_receive.Text = Encoding.ASCII.GetString(bt1); 
            });
        }

        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_open_Click(object sender, RoutedEventArgs e)
        {
            // 打开动作
            try
            {
                // 串口的一端只能同时被一个用户打开,否则报错,所以看是否串口已经被占用
                sp.Open();
                MessageBox.Show(sp.PortName+"串口已打开", "提示");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message,"提示");
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_send_Click(object sender, RoutedEventArgs e)
        {
            // 发送动作(与打开动作操作同一个串口对象)
            // sp.Write();
            string str_send = textBox_send.Text;
            
            byte[] bt1 = Encoding.ASCII.GetBytes(str_send);
            byte[] bt2 = new byte[] { 0x01, 0x02, 0x03 };
            sp.Write(bt1, 0, bt1.Length);  // 在bytes中从位置0开始发送bytes.Length个字节
        }

        /// <summary>
        /// 接收数据(第一种接收方式,主动请求接收方式)
        /// 我要你再给
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_recisive_Click(object sender, RoutedEventArgs e)
        {
            // 长度是串口能够读到的最大的字节数量
            byte[] bt1 = new byte[sp.BytesToRead];
            sp.Read(bt1, 0, bt1.Length); // 从当前串口中的位置0处开始读取bt1.Length个字节到bt1中
            textBox_receive.Text = Encoding.ASCII.GetString(bt1);
        }
    }
}

3 网口通讯

3.1 Xaml代码

html 复制代码
<Window x:Class="WPF_ZhaoXi_0205.window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_ZhaoXi_0205"
        mc:Ignorable="d"
        Title="window1" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="textBox_receive" Grid.Row="0" Grid.Column="0" FontSize="15" Margin="10" Text="接收窗口"/>
        <TextBox x:Name="textBox_send" Grid.Row="0" Grid.Column="1" FontSize="15" Margin="10" Text="发送窗口"/>
        <Button x:Name="button_connect" Grid.Row="1" Grid.Column="0" Content="链接服务器" Margin="10" Click="button_connect_Click"/>
        <Button x:Name="button_receive" Grid.Row="1" Grid.Column="1" Content="接收数据" Margin="10" Click="button_receive_Click"/>
        <Button x:Name="button_send" Grid.Row="2" Grid.Column="0" Content="发送数据" Margin="10" Click="button_send_Click" />
    </Grid>
</Window>

3.2 cs代码

csharp 复制代码
using System.IO;
using System.IO.Ports;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF_ZhaoXi_0205
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class window1 : Window
    {
        // 声明一个对象
        Socket socket = null;

        public window1()
        {
            InitializeComponent();

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// 链接数据库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_connect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                socket.Connect("127.0.0.1", 6666);
                Task.Run(() =>
                {
                // 异步线程
                while (true)
                {
                    byte[] datb = new byte[50];
                    socket.Receive(datb);
                    this.Dispatcher.Invoke(() => {
                        textBox_receive.Text = Encoding.UTF8.GetString(datb);
                    });    
                    }
                });
                MessageBox.Show("服务器已链接", "提示");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示");
            }
            
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_send_Click(object sender, RoutedEventArgs e)
        {
            // byte[] data = new byte[] { 0x32 };
            byte[] data = Encoding.UTF8.GetBytes("[abc] hello 牛犇!123");
            socket.Send(data);

            // 接收数据(主动响应)
            //byte[] datb = new byte[50];
            //socket.Receive(datb);
            //textBox_receive.Text = Encoding.UTF8.GetString(datb);
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_receive_Click(object sender, RoutedEventArgs e)
        {
            byte[] datb = new byte[50];
            socket.Receive(datb);
            textBox_receive.Text = Encoding.UTF8.GetString(datb);
        }
    }
}
相关推荐
可峰科技8 分钟前
斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)
开发语言·qt
全栈开发圈12 分钟前
新书速览|Java网络爬虫精解与实践
java·开发语言·爬虫
面试鸭16 分钟前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
小白学大数据17 分钟前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
Python大数据分析@20 分钟前
python操作CSV和excel,如何来做?
开发语言·python·excel
上海_彭彭1 小时前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
334554321 小时前
element动态表头合并表格
开发语言·javascript·ecmascript
沈询-阿里1 小时前
java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl
java·开发语言
残月只会敲键盘1 小时前
面相小白的php反序列化漏洞原理剖析
开发语言·php