C# 32feet.Net:在单独的线程中处理两个蓝牙连接,给出 SocketException

2024-04-06

我正在编写一个 C# 控制台应用程序,使用32feet.Net该库创建两个线程来搜索并连接到不同的蓝牙设备,然后打开 TCP 套接字,以便可以通过网络连接将数据传递到设备。我知道这种情况听起来很奇怪,但一位资深同事要求我这样做。

我的代码似乎在仅连接一台设备的情况下工作正常,尽管蓝牙连接有时会在来回传递几条消息后断开。但是,有时当第二个设备连接时,我会收到一条错误消息System.net.sockets.socketexception a connection attempt failed because the connected party did not properly respond,其他时候代码只是退出而不抛出任何异常。

我想知道是什么原因造成的,我发现32feet.Net库可以支持多个连接。我想知道我是否犯了一些错误,因为我是新手C#, .Net,甚至 Windows,并且以前从未编写过任何基于蓝牙的代码。

程序.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace BluetoothManager
{
class Program
{
    static void Main(string[] args)
    {

        BTManager rover_btm = new BTManager();
        BTManager base_btm = new BTManager();
        base_btm.Port = 0xba5e;
        rover_btm.Port = 17825;
        base_btm.Name = "Base";
        rover_btm.Name = "Rover";

        base_btm.match = (args.Length >= 1 && args[0] != "") ? args[0] : "dev1";
        rover_btm.match = (args.Length >= 2 && args[1] != "") ? args[1] : "dev2";

        Console.WriteLine("Base Station match: " + base_btm.match);
        Console.WriteLine("Rover match: " + rover_btm.match);
        Thread Base = new Thread(new ThreadStart(base_btm.HandleThread));
        Thread Rover = new Thread(new ThreadStart(rover_btm.HandleThread));

        Base.Start();
        Rover.Start();

        Base.Join();
        Rover.Join();

        Console.Read();

    }
}
} 

BTManager.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Ports;
using InTheHand.Net.Sockets;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using Microsoft.Win32;
using System.IO;


namespace BluetoothManager
{
class BTManager
{
    private static BluetoothDeviceInfo[] peers;
    private BluetoothClient client;
    private bool _isConnected = false;
    private string _match;
    private const string defpin = "0000";
    private TcpListener tcpListener;
    private int _port;
    private string _name = "Not Named";

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public int Port
    {
        get { return _port; }
        set { _port = value; }
    }

    public bool IsConnected
    {
        get { return _isConnected; }
        private set { _isConnected = value; }
    }

    public string match
    {
        get { return _match; }

        set { _match = value; }
    }

    public BTManager()
    {
        client = new BluetoothClient();
    }


    public void HandleThread()
    {

        BluetoothDeviceInfo device;
        while (!this.findDevice(out device)) ;

        Console.WriteLine("About to pair");
        int count = 0;
        int max = 5;
        while ((!(BluetoothSecurity.PairRequest(device.DeviceAddress, defpin))) && count < max)
        {
            Console.WriteLine("Pairing Failed, retrying");
            count++;
            Thread.Sleep(100);
        }

        if (count == max)
        {
            HandleThread();
        }
        else
        {
            Console.WriteLine("Paired..Beginning connect");
            client.BeginConnect(device.DeviceAddress, BluetoothService.SerialPort, this.callback, client);
        }
    }

    private void callback(IAsyncResult result)
    {
        client.EndConnect(result);

        this.tcpListener = new TcpListener(IPAddress.Loopback, _port);
        this.tcpListener.Start();
        TcpClient TcpClient = this.tcpListener.AcceptTcpClient();
        NetworkStream networkStream = TcpClient.GetStream();
        Stream bluetoothStream = client.GetStream();

        byte[] fromNetwork = new byte[1024];
        byte[] fromBluetooth = new byte[1024];
        while (client.Connected && TcpClient.Connected)
        {

            try
            {
                if (networkStream.CanRead)
                {
                    Array.Clear(fromNetwork, 0, 1024);
                    networkStream.Read(fromNetwork, 0, 1024);
                    Console.WriteLine(Encoding.ASCII.GetString(fromNetwork));
                    bluetoothStream.Write(fromNetwork, 0, 1024);
                    bluetoothStream.Flush();

                    while (bluetoothStream.CanRead)
                    {
                        Array.Clear(fromBluetooth, 0, 1024);
                        bluetoothStream.Read(fromBluetooth, 0, 1024);
                        Console.WriteLine(Encoding.ASCII.GetString(fromNetwork));
                        networkStream.Write(fromBluetooth, 0, 1024);
                        networkStream.Flush();
                    }
                }


            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }

        this.HandleThread();
    }

    private bool findDevice(out BluetoothDeviceInfo device)
    {
        peers = client.DiscoverDevicesInRange();
        device = Array.Find(peers, element => element.DeviceName == match);

        foreach (BluetoothDeviceInfo btdi in peers)
        {
            Console.WriteLine(btdi.DeviceName);
        }


        if (device == null)
        {
            Console.WriteLine(Name +": Not Found");
            return false;
        }
        else
        {
            Console.WriteLine(Name +": Found");
            return true;
        }

    }
}
}

我正在使用套接字来与蓝牙设备进行通信。 断开连接时释放所有资源非常重要。

为了找到您的 COM 端口,您可以使用这个链接 https://stackoverflow.com/questions/26439091/how-to-get-bluetooth-device-com-serial-port-in-winform-c/27919129#27919129

您的信息流位于此处:

System.Net.Sockets.NetworkStream stream = bthClient.GetStream();

有关如何连接和查找您的设备的示例。

private InTheHand.Net.Sockets.BluetoothClient _BTClient = null;
private InTheHand.Net.Sockets.BluetoothDeviceInfo[] _clientDevices;



    /// <summary>
    /// Thread function to discover devices
    /// </summary>
    private void DiscoverBluetoothThread()
    {
        try
        {                                
            _BTClient = new InTheHand.Net.Sockets.BluetoothClient();
            _clientDevices = _BTClient.DiscoverDevices(999, _authenticated, _remembered, _unknown);
            _BTClient.Dispose();
            _BTClient = null;
        }
        catch (Exception) { }

    }


    Private void Connect(InTheHand.Net.Sockets.BluetoothDeviceInfo info)
    {
        string addressN = info.DeviceAddress.ToString("N"); //Format Example: "00066606E014"
        string addressC = info.DeviceAddress.ToString("C"); //Format Example: "00:06:66:06:E0:14"
        string addressP = info.DeviceAddress.ToString("P"); //Format Example: "00.06.66.06.E0.14"
        string addressD = info.DeviceAddress.ToString();    //Format Example: "00066606E014"

        string serialPort = FindBluetoothPortName(addressN);
        //https://stackoverflow.com/questions/26439091/how-to-get-bluetooth-device-com-serial-port-in-winform-c/27919129#27919129

        if (string.IsNullOrEmpty(serialPort) == false && serialPort.Trim().Length > "COM".Length)
            bool installed = InstallBluetoothDevice(addressC, passKey, autoConnect);
    }


     public bool InstallBluetoothDevice(string deviceMACAddress, string passKey, bool connect)
     {
        string strDevicePassKey = passKey;
        string BTMac = deviceMACAddress;

        InTheHand.Net.BluetoothAddress BTAddress;
        InTheHand.Net.Sockets.BluetoothClient BTClient = new InTheHand.Net.Sockets.BluetoothClient();
        InTheHand.Net.BluetoothEndPoint BTEndPoint;
        InTheHand.Net.Bluetooth.BluetoothRadio BTRadio;

        BTRadio = InTheHand.Net.Bluetooth.BluetoothRadio.PrimaryRadio;
        BTRadio.Mode = RadioMode.Connectable;

        Guid spguid = BluetoothService.SerialPort;
        BTAddress = InTheHand.Net.BluetoothAddress.Parse(BTMac);
        BTEndPoint = new InTheHand.Net.BluetoothEndPoint(BTAddress, spguid);            
        try
        {
            BluetoothSecurity.PairRequest(BTAddress, strDevicePassKey);
            //Application.DoEvents();
            BTClient = new InTheHand.Net.Sockets.BluetoothClient();

            if (connect)
            {
                BTClient.Connect(BTEndPoint);
                BTEndPoint = new InTheHand.Net.BluetoothEndPoint(BTAddress, spguid);
                _connectedDevices.Add(BTAddress, BTClient);
                return BTClient.Connected;
            }

            return true;
        }
        catch (Exception ex)
        {
            return false;

        }

    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 32feet.Net:在单独的线程中处理两个蓝牙连接,给出 SocketException 的相关文章

  • 更新面板工作速度非常慢

    我正在编写一个用户可以注册的应用程序 注册时 可以选择多个选项 并根据这些注册字段可见或不可见以及是否必需 我想出了一个想法 所有字段都将位于 updatePanel 中 当用户更改注册选项时 我将在服务器端设置这些字段的可见性 它可以工作
  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 在 HKCR 中创建新密钥有效,但不起作用

    我有以下代码 它返回 成功 但使用两种不同的工具使用搜索字符串 3BDAAC43 E734 11D5 93AF 00105A990292 搜索注册表不会产生任何结果 RegistryKey RK Registry ClassesRoot C
  • 按扩展名过滤搜索文件返回太多结果

    我正在开发一个 C 控制台应用程序 它必须管理 Windows 操作系统上的文件 我需要获取具有特定扩展名的文件名 列表 我找到了很多解决方案 最建议的是以下一种 HANDLE hFind WIN32 FIND DATA data hFin
  • Eigen 和 OpenMP:由于错误共享和线程开销而没有并行化

    系统规格 Intel Xeon E7 v3 处理器 4 插槽 16 核 插槽 2 线程 核心 Eigen 系列和 C 的使用 以下是代码片段的串行实现 Eigen VectorXd get Row const int j const int
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • 在 .NET MAUI 中实现 TouchTracking

    我一直致力于将我们的应用程序从 Xamarin Forms 迁移到 NET MAUI 我们的应用程序几乎没有绘图功能 用户可以用手指进行绘图 我们用了TouchTrackingXamarin Forms 中的 nuget 包 但与 NET
  • 不可变类与结构

    以下是类与 C 中的结构的唯一区别 如果我错了 请纠正我 类变量是引用 而结构变量是值 因此在赋值和参数传递中复制结构的整个值 类变量是存储在堆栈上的指针 指向堆上的内存 而结构变量作为值存储在堆上 假设我有一个不可变的结构 该结构的字段一
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se
  • Oauth2中如何同时撤销RefreshToken和使AccessToken失效

    我正在使用 Owin Oauth2 授权和资源服务器相同 开发单页面应用程序 AngularJS Net MVC Json Rest API 的身份验证流程 我选择了 Bearer Token 路由而不是传统的 cookie session
  • 模板类的模板构造函数的 C++ 显式模板特化

    我有一个像这样的课程 template
  • 模板类中的无效数据类型生成编译时错误?

    我正在使用 C 创建一个字符串类 我希望该类仅接受数据类型 char 和 wchar t 并且我希望编译器在编译时使用 error 捕获任何无效数据类型 我不喜欢使用assert 我怎样才能做到这一点 您可以使用静态断言 促进提供一个 ht
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • 没有“对 *this”功能的右值引用的解决方法

    我有一个围绕可移动对象的代理容器类 并希望代理能够隐式生成对底层对象的右值引用 但仅当代理本身被移动时 我相信我将能够按照提案 n2439 实施此行为 将移动语义扩展到 this http www open std org jtc1 sc2
  • 如何在 sql azure 上运行 aspnet_regsql? [复制]

    这个问题在这里已经有答案了 可能的重复 将 ASP NET 成员资格数据库迁移到 SQL Azure https stackoverflow com questions 10140774 migrating asp net membersh
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点
  • MySqlConnectionStringBuilder - 使用证书连接

    我正在尝试连接到 Google Cloud Sql 这是一个 MySql 解决方案 我能够使用 MySql Workbench 进行连接 我如何使用 C 连接MySqlConnectionStringBuilder 我找不到提供这三个证书的

随机推荐