C#应用程序将不会接收串行数据流

C#应用程序将不会接收串行数据流,c#,bluetooth,serial-port,C#,Bluetooth,Serial Port,我正在开发一个C#Windows窗体应用程序,通过蓝牙连接与Raspberry Pi Model 3进行通信。通过客户端计算机上的虚拟串行端口模拟此连接。我可以在C#程序中启动蓝牙连接,但无法从该程序接收任何数据。当我使用Putty程序时,我可以看到数据以我希望的方式在COM端口上传输 我还发现了一个奇怪的C#程序故障。如果我在Putty上打开COM端口,然后启动C#程序,则Port.open()命令会出错,因为端口是保留的。因此,如果我关闭Putty并继续C#应用程序,数据将完美地流到程序中。

我正在开发一个C#Windows窗体应用程序,通过蓝牙连接与Raspberry Pi Model 3进行通信。通过客户端计算机上的虚拟串行端口模拟此连接。我可以在C#程序中启动蓝牙连接,但无法从该程序接收任何数据。当我使用Putty程序时,我可以看到数据以我希望的方式在COM端口上传输

我还发现了一个奇怪的C#程序故障。如果我在Putty上打开COM端口,然后启动C#程序,则Port.open()命令会出错,因为端口是保留的。因此,如果我关闭Putty并继续C#应用程序,数据将完美地流到程序中。以前有人遇到过这个问题吗?这几天我有点不知所措。我的程序中的代码如下所示:

using System;
using System.IO.Ports;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using InTheHand.Net;
using InTheHand.Net.Sockets;
using InTheHand.Net.Bluetooth;
using System.Threading;

namespace GUIfromPI
{

    static class Program
    {
        //PC BT USB adapter
        private static BluetoothEndPoint EP = new BluetoothEndPoint(BluetoothAddress.Parse("##:##:##:##:##:##"), BluetoothService.BluetoothBase); //addressing the usb adapter used on the PC (endpoint)
        private static BluetoothClient BC = new BluetoothClient(EP);

        //Pi BT Adapter
        private static BluetoothDeviceInfo BTDevice = new BluetoothDeviceInfo(BluetoothAddress.Parse("##:##:##:##:##:##")); //addressing the BT adapter on the Rasperry Pi
       // private static NetworkStream stream = null;
        public static SerialPort mySerialPort = new SerialPort(); //Bluetooth module mimics serial protocol by streaming data through the COM5 port in the host80 computer
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        public static void Main(string[] args)
        {
            Console.WriteLine("Executing Program...");
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (BluetoothSecurity.PairRequest(BTDevice.DeviceAddress, "1234"))//MY_PAIRING_CODE))
            {
                Console.WriteLine("PairRequest: OK");

                if (BTDevice.Authenticated)
                {
                    Console.WriteLine("Authenticated: OK");
                    BC.SetPin("1234");//pairing code
                    //BC.BeginConnect(BTDevice.DeviceAddress, BluetoothService.SerialPort, new AsyncCallback(Connect), BTDevice);
                }
                else
                {
                    Console.WriteLine("Authenticated:No");
                }
            }
            else
            {
                Console.WriteLine("PairRequest: No");
            }
            //mySerialPort = new SerialPort("COM5");

            SerialThreadFunction();
        }


        public static void SerialThreadFunction()
        {
            mySerialPort.PortName = "COM10";
            mySerialPort.BaudRate = 9600;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.DtrEnable = true;
            mySerialPort.RtsEnable = true;
            mySerialPort.ReadTimeout = 100000;
            mySerialPort.Open();
            //mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            string mydata = "hello";
            while (true)
            {
                Console.WriteLine(mySerialPort.ReadLine());
                mydata = mySerialPort.ReadLine();
            }
            mySerialPort.Close();
        } 


        private static void DataReceivedHandler(
                            object sender,
                            SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            Console.WriteLine("Data Received: ");
            Console.Write(indata);
        }
    }
}
使用系统;
使用System.IO.Ports;
使用System.IO;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用inthand.Net;
使用inthand.Net.Sockets;
使用inthand.Net.Bluetooth;
使用系统线程;
命名空间GUIfromPI
{
静态类程序
{
//PC BT USB适配器
私有静态BluetoothEndPoint EP=new BluetoothEndPoint(BluetoothAddress.Parse(“##:#:#:##:##:#:##########,BluetoothService.BluetoothBase)//寻址PC上使用的usb适配器(endpoint)
私有静态BluetoothClient BC=新BluetoothClient(EP);
//Pi-BT适配器
私有静态BluetoothDeviceInfo BTDevice=new BluetoothDeviceInfo(BluetoothAddress.Parse(“##:#:#:#:##:#:##:#####”)//寻址Rasperry Pi上的BT适配器
//私有静态NetworkStream=null;
public static SerialPort mySerialPort=new SerialPort();//蓝牙模块通过host80计算机中的COM5端口传输数据来模拟串行协议
/// 
///应用程序的主要入口点。
/// 
[状态线程]
公共静态void Main(字符串[]args)
{
Console.WriteLine(“执行程序…”);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if(BluetoothSecurity.PairRequest(BTDevice.DeviceAddress,“1234”)//我的配对码)
{
Console.WriteLine(“PairRequest:OK”);
if(BTDevice.Authenticated)
{
Console.WriteLine(“已验证:确定”);
BC.SetPin(“1234”);//配对代码
//BC.BeginConnect(BTDevice.DeviceAddress、BluetoothService.SerialPort、新的异步回调(Connect)、BTDevice);
}
其他的
{
Console.WriteLine(“已验证:否”);
}
}
其他的
{
Console.WriteLine(“PairRequest:No”);
}
//mySerialPort=新串行端口(“COM5”);
SerialThreadFunction();
}
公共静态void SerialThreadFunction()
{
mySerialPort.PortName=“COM10”;
mySerialPort.BaudRate=9600;
mySerialPort.Parity=奇偶校验.None;
mySerialPort.StopBits=StopBits.One;
mySerialPort.DataBits=8;
mySerialPort.Handshake=Handshake.None;
mySerialPort.DtrEnable=true;
mySerialPort.RtsEnable=true;
mySerialPort.ReadTimeout=100000;
mySerialPort.Open();
//mySerialPort.DataReceived+=新的SerialDataReceivedEventHandler(DataReceivedHandler);
字符串mydata=“hello”;
while(true)
{
Console.WriteLine(mySerialPort.ReadLine());
mydata=mySerialPort.ReadLine();
}
mySerialPort.Close();
} 
私有静态无效DataReceivedHandler(
对象发送器,
SerialDataReceivedEventArgs(e)
{
SerialPort sp=(SerialPort)发送方;
字符串indata=sp.ReadExisting();
Console.WriteLine(“接收到的数据:”);
Console.Write(indata);
}
}
}

更新:我刚刚发现声明我的蓝牙端点、客户端和设备会干扰串行端口的读取。由于蓝牙连接之前已经初始化,所以我能够看到端口上的数据。现在说说为什么会这样做?

好吧,看来你没有做错什么。NET无法处理同一端口的多个所有权。当您声明您的
SerialPort
实例并连接到say。。。通信11。。。您已将COM11的所有权完全授予您的
SerialPort
实例。为了访问COM11,您现在需要提供对拥有COM11所有权的特定
SerialPort
对象的引用

在您的情况下,您打开PuTTY,然后运行程序。一旦PuTTY获得对端口的访问权,您的程序将无法这样做。这在.NET框架中是完全标准的。现在,有其他方法可以获得对COM端口的多个访问,但我认为这超出了这个问题的范围。这里有一个软件,可以让你运行一个应用程序,同时嗅探端口上的流量。你可以免费得到这个,并且有一个更好的版本可以购买,它可以产生各种各样的魔力

这里有一个小算法来确保您的端口被正确打开,您可能想要采取这个。。。稍微修改一下。。。并将其用作
BluetoothClient
类上的
Connect
方法

SerialPort port = null;
string error = string.Empty;
bool success = false;
int tries = 5;

foreach(var name in System.IO.Ports.SerialPort.GetPortNames())
{
    // try each port until you find an open one
    port.Name = name;

    // there is always a chance that the port is open
    // if trying some operations back-to-back
    // give it a few extra tries if necessary
    for (int i = tries; i > 0; --i)
    {
        try
        {
            // avoid the exception by testing if open first
            if (!port.IsOpen)
            {
                port.Open();
                success = true;
                return;
            }
        }
        catch (UnauthorizedAccessException e)
        {
            // sometimes the exception happens anyway, especially
            // if you have multiple threads/processes banging on the
            // ports
            error += e.Message;
        }
    }
}
除此之外,您可能还需要注意,当您需要读取端口时,
Bluetooth
类没有声明端口的所有权。这可能是干扰读取端口的原因。Y