【C#】简单的蓝牙通讯功能实现

简介: 【C#】简单的蓝牙通讯功能实现

利用ESP32来模拟BT蓝牙(BLE低功耗蓝牙后续也会进行测试)

C#利用32feet.NET库来实现蓝牙的使用。

(1)初始化扫描蓝牙设备写入选择框

(2)连接蓝牙设备,连接成功则开启监听线程

(3)监听线程接收到数据设置回调函数将接收到的内容显示在文本框上。

(4)点击发送按钮后将文本框的内容发送给接收端。

private async void Booth_Init()
{
    try
    {
        client = new BluetoothClient();
        // 使用 Task.Run 来在另一个线程中执行 DiscoverDevices
        devices = await Task.Run(() => client.DiscoverDevices());
        BoothChoose.Items.Clear();
        foreach (BluetoothDeviceInfo device in devices)
        {
            // 确保 UI 更新在 UI 线程上执行
            this.Invoke((MethodInvoker)delegate
            {
                BoothChoose.Items.Add(device.DeviceName);
            });

            Console.WriteLine(device.DeviceName);
        }

        // 确保在 UI 线程上修改 SelectedIndex
        this.Invoke((MethodInvoker)delegate
        {
            if (BoothChoose.Items.Count > 0)
            {
                BoothChoose.SelectedIndex = 0;
            }
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine("错误: " + ex.Message);
    }
}

初始化的代码是使用异步的方式扫描设备,并且将设备名称显示在选择控件上,之所以是采用异步的方式原因是不采用异步会占用UI线程导致UI线程无法使用。所以需要单独开线程来初始化,同时该函数也可以用于重新扫描设备。

蓝牙连接

private async void BoothConnect()
{
    try
    {
        if (BoothChoose.Items.Count != 0)
        {
            string selectedDeviceName = BoothChoose.SelectedItem.ToString();

            // 寻找匹配的设备
            BluetoothDeviceInfo deviceToConnect = devices.FirstOrDefault(d => d.DeviceName == selectedDeviceName);
            if (deviceToConnect != null)
            {
                // 连接到设备
                await Task.Run(() => client.Connect(deviceToConnect.DeviceAddress, BluetoothService.SerialPort));
                MessageBox.Show("连接成功", "信息");
                if (client.Connected)
                {
                    stream = client.GetStream();
                    StartListening(OnDataReceived); // 开始监听数据并指定回调
                }
            }
            else
            {
                MessageBox.Show("未找到选定的设备", "警告");
            }
        }
        else
        {
            MessageBox.Show("未检测到设备", "警告");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("蓝牙连接失败: " + ex.Message, "错误");
    }
}

连接蓝牙的代码,根据选择控件选择的蓝牙名称匹配对应的蓝牙设别,接着使用异步的方式来连接蓝牙,防止连接蓝牙的过程中导致UI线程卡顿无法使用。

并且使用一个Stream流变量来接收蓝牙传输的信息,调用StartListening函数来实现蓝牙设备的监听

监听函数

private void StartListening(Action<string> callback)
{
    Task.Run(() =>
    {
        byte[] buffer = new byte[1024]; // 数据缓冲区
        int bytes;

        try
        {
            while (client.Connected)
            {
                bytes = stream.Read(buffer, 0, buffer.Length);
                if (bytes > 0)
                {
                    string receivedData = Encoding.UTF8.GetString(buffer, 0, bytes);
                    this.Invoke((MethodInvoker)delegate
                    {
                        callback(receivedData); // 在UI线程上调用回调
                    });
                }
            }
        }
        catch (IOException ex)
        {
            // 连接丢失或读取错误
            this.Invoke((MethodInvoker)delegate
            {
                MessageBox.Show("读取数据错误: " + ex.Message, "错误");
            });
        }
    });
}

private void OnDataReceived(string data)
{
    if (Receive.InvokeRequired)
    {
        // 如果调用线程不是创建Receive控件的线程,则使用Invoke调用
        Receive.Invoke(new MethodInvoker(delegate
        {
            Receive.AppendText(data);
        }));
    }
    else
    {
        // 如果已经在UI线程,则直接更新
        Receive.AppendText(data);
    }
}

监听函数中我们异步监听数据,并且设置OnDataReceived回调函数处理接收到的数据。

发送数据

private void TransButton_Click(object sender, EventArgs e)
{
    try
    {
        // 获取要发送的文本
        string dataToSend = TransText.Text;
        if (NewLine.Checked)
        {
            dataToSend += Environment.NewLine;
        }
        if (client != null && client.Connected)
        {
            Stream stream = client.GetStream();
            if (stream.CanWrite)
            {
                // 将文本转换为字节数据
                byte[] buffer = Encoding.UTF8.GetBytes(dataToSend);
                // 发送数据
                stream.Write(buffer, 0, buffer.Length);
            }
        }
        else
        {
            MessageBox.Show("Bluetooth is not connected.");
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error sending data: " + ex.Message);
    }
}
目录
相关文章
|
5月前
|
C#
【C#】 如何实现文本框历史记录提示功能
【C#】 如何实现文本框历史记录提示功能
104 0
|
5月前
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
82 0
|
5月前
|
数据采集 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用ForceIP强制修改网口IP功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用ForceIP强制修改网口IP功能(C#)
54 0
|
11天前
|
监控 前端开发 安全
C#一分钟浅谈:文件上传与下载功能实现
【10月更文挑战第2天】在Web应用开发中,文件的上传与下载是常见需求。本文从基础入手,详细讲解如何在C#环境下实现文件上传与下载。首先介绍前端表单设计及后端接收保存方法,使用`&lt;input type=&quot;file&quot;&gt;`与`IFormFile`接口;接着探讨错误处理与优化策略,如安全性验证和路径管理;最后讲解文件下载的基本步骤,包括确定文件位置、设置响应头及发送文件流。此外,还提供了进阶技巧,如并发处理、大文件分块上传及进度监控,帮助开发者构建更健壮的应用系统。
52 15
|
10天前
|
开发框架 Cloud Native .NET
10 个 C# 关键字和功能
10 个 C# 关键字和功能
37 8
|
10天前
|
C#
如何使用c# 实现断点续传功能
如何使用c# 实现断点续传功能
11 0
|
10天前
|
网络协议 C#
C#:简化版的实现断点续传功能
C#:简化版的实现断点续传功能
17 0
|
5月前
|
编译器 C# 开发工具
C# 12 中新增的几大功能你都知道吗?
C# 12 中新增的几大功能你都知道吗?
|
2月前
|
编译器 API C#
C# 12 新增功能实操!
C# 12 新增功能实操!
|
2月前
|
C# 图形学
小功能⭐️C#控制小数点后位数的方法
小功能⭐️C#控制小数点后位数的方法