首页 文章

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

提问于
浏览
2

我正在编写一个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的新手,之前从未编写任何基于蓝牙的代码 .

Program.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;
        }

    }
}
}

1 回答

  • 0

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

    为了找到您的COM端口,您可以使用this link

    您的信息流位于此处:

    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;
    
            }
    
        }
    

相关问题