C# 32feet.Net: Handling two bluetooth connections in seperate threads, gives SocketException

喜欢而已 提交于 2019-12-07 22:57:00

问题


I'm writing a C# console application using the 32feet.Net library that creates two threads to search for and connect to different Bluetooth devices and then open up TCP sockets so that data can be passed to the devices via a network connection. I know this situation sounds completely bizarre, but I've been asked to do this by a senior colleague.

My code seems to work OK with only one device connected, although the Bluetooth connection does sometimes drop out after a couple of messages have been passed backwards and forwards. However, sometimes as soon as the second device connects I get an error saying System.net.sockets.socketexception a connection attempt failed because the connected party did not properly respond, other times the code just exits without throwing any exceptions.

I was wondering what is causing this, I've seen that the 32feet.Net library can support multiple connections. I'm wondering if I've made some errors, as I'm new to C#, .Net, and even Windows, and have never written any Bluetooth based code before.

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:


I am using Sockets in order to communicate with the Bluetooth device. Its very important to release any resources when disconnecting.

In order to find your COM port you can use this link

Your stream is located here:

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

Example to how to connect and find your device.

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;

        }

    }


来源:https://stackoverflow.com/questions/25379705/c-sharp-32feet-net-handling-two-bluetooth-connections-in-seperate-threads-give

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!