• Windows下使用C#和32feet.NET开发蓝牙传输功能的记录


    引用的第三方Nuget库

    • 32feet.NET 3.5.0
    • MaterialDesignColors
    • MaterialDesignThemes
    • Newtonsoft.Json

    使用到的技术:

    XAML C#

    本实例中使用的蓝牙是作为服务器端等待连接.

    主要流程如下:

    第1步

    初始化相关内容:

    public static void InitSDK()
    {
          Guid mGUID = Guid.Parse("00001101-0000-1000-8000-00805F9B34FB");
          bluetoothListener = new BluetoothListener(mGUID);
    }
    

    其中00001101-0000-1000-8000-00805F9B34FB是蓝牙串口服务的uuid,其他类型的服务uuid各有不同,可以查阅相关资料

    第2步

    声明蓝牙监听对象:
    BluetoothListener bluetoothListener;

    第3步

    等待蓝夜客户端进行连接:
    client = bluetoothListener.AcceptBluetoothClient();

    获取客户端连接对象的信息(类似于TCP连接):

    bluetoothModel.blueAddress = client.RemoteEndPoint.Address;
    bluetoothModel.blueName = client.RemoteMachineName;
    

    通知调用,通知注册的事件已经有蓝牙连接成功:

    public static void Notify(object message)
    {
        NotifyMessage?.Invoke(message);
    }
    
    Notify(bluetoothModel);
    

    接收数据并解析:

     while (true)
                {
                    try
                    {
                        if (peerStream.DataAvailable)
                        {
                            peerStream.ReadAsync(buffer, 0, 1024);
    
                            //peerStream.Read(buffer, 0, 200);
                            string data = Encoding.UTF8.GetString(buffer).ToString().Replace("", "");//去掉后面的字节
    
                            Console.WriteLine("Receiving data: " + data);
                            //if (peerStream.Length > 0)
                            //{
                            //}
                        }
                    }
                    catch (Exception ex)
                    {
                        client.Close();
                        Notify("链接关闭");
                        MessageBox.Show(ex.Message);
                        return;
                    }
                }
    

    作为服务器要一直监听客户端发送的消息,所以进行死循环接收(这种方案比较简单,可以使用异步委托重复调用进行优化)
    缓冲区大小设置为1024的长度,没有做按照标准进行处理,此项目中不接受数据,所以没有展开写.

    发送

    发送数据

     public static void Send(string str)
            {
                if (peerStream != null)
                {
                    if (peerStream.CanWrite)
                    {
                        List<byte> list = new List<byte>();
                        byte header = 0x01;
    
                        list.Add(header);
                        byte[] dataBuffer = Encoding.UTF8.GetBytes(str);
    
                        foreach (var item in dataBuffer)
                        {
                            list.Add(item);
                        }
    
                        try
                        {
                            // Output data to stream
                            peerStream.Write(list.ToArray(), 0, list.Count);
    
                            peerStream.Flush();
                        }
                        catch (Exception ex)
                        {
                            client.Close();
                            Notify("链接关闭");
                            MessageBox.Show(ex.Message);
                        }
                    }
                    else
                    {
                        client.Close();
                        Notify("链接关闭");
                        MessageBox.Show("配对失败内侧");
                    }
                }
                else
                {
                    MessageBox.Show("配对失败外侧");
                }
            }
    

    发送数据遵从一定的协议,超过1024即1K字节长度则分包发送
    其中0x01代表发送字符串,0x02代表发送文件

    发送文件:

            //1 文件类型
            //1 文件子类型
            //4 文件大小
            //4 总包数
            //4 第几包
            //4 本包大小
            public static void SendFile(int type, string filePath)
            {
                if (peerStream != null)
                {
                    int packCount = 512 - 17;
                    byte btype = (byte)type;
    
                    byte[] img = File.ReadAllBytes(filePath);
                    int imgLength = img.Length;
                    Console.WriteLine("图像长度:" + imgLength);
                    byte[] blen = intToBytes(imgLength);
    
                    List<byte> original = new List<byte>(img.ToArray());
    
                    List<List<byte>> targetList = new List<List<byte>>();
    
                    int totalCount = img.Length / packCount + 1;
                    byte[] btotalCount = intToBytes(totalCount);
    for (int i = 0; i < totalCount - 1; i++)
                    {
                        List<byte> curList = new List<byte>();
    
                        curList.Add(0x02);
                        curList.Add(btype);
                        //总文件长度
                        curList.AddRange(blen);
    
                        //总包数
                        curList.AddRange(btotalCount);
    
                        byte[] bForNoCount = intToBytes(i);
    
                        //第几包
                        curList.AddRange(bForNoCount);
    
                        //本包大小
                        byte[] curCount = intToBytes(packCount);
    
                        curList.AddRange(curCount);
    
                        //包内容
                        curList.AddRange(original.GetRange(i * packCount, packCount));
                        targetList.Add(curList);
                    }
                    List<byte> lastList = new List<byte>();
    
                    lastList.Add(0x02);
                    lastList.Add(btype);
                    lastList.AddRange(blen);
                    //总包数
                    lastList.AddRange(btotalCount);
    
                    byte[] bNoCount = intToBytes(totalCount - 1);
    
                    //第几包
                    lastList.AddRange(bNoCount);
                    //包大小
                    byte[] lastCount = intToBytes(imgLength - (totalCount - 1) * packCount);
                    lastList.AddRange(lastCount);
    
                    lastList.AddRange(original.GetRange((totalCount - 1) * packCount, imgLength - (totalCount - 1) * packCount));
                    //lastList.Add((Byte)('
    '));
                    targetList.Add(lastList);
                    if (peerStream.CanWrite)
                    {
                        foreach (var item in targetList)
                        {
                            try
                            {
                                Console.WriteLine("包长:" + item.Count);
                                peerStream.Write(item.ToArray(), 0, item.Count);
    
                                peerStream.Flush();
                            }
                            catch (Exception ex)
                            {
                                //Console.WriteLine(ex);
                                MessageBox.Show(ex.Message);
    
                                return;
                            }
                        }
                    }
                }
            }
    
    文件一般大于1K,所以分包发送.基本协议见方法注释.
    
    代码比较粗糙,毕竟只是一次性项目,没有花很多信息分层,优化,写注释等,看客们请谅解,学习到精髓就可以了
    
    
    详细代码见github链接
    [链接](https://github.com/KleinPan/WpfAppBluetooth)
  • 相关阅读:
    DM7 安装
    LeetCode 第 183 场周赛
    MySQL 源码中的 ut_a 、 ut_ad
    存储领域的会议和研究机构
    LeetCode 第 15 场双周赛
    LeetCode 第 167 场周赛
    值得推荐的C/C++框架和库
    InnoDB 中的锁实现
    LeetCode-第 166 场周赛
    LeetCode 第 165 场周赛
  • 原文地址:https://www.cnblogs.com/KevinBran/p/13841653.html
Copyright © 2020-2023  润新知