【问题标题】:Read data from StreamSocketListener on RFComm bluetooth connected device C#从 RFComm 蓝牙连接设备 C# 上的 StreamSocketListener 读取数据
【发布时间】:2015-08-24 03:26:36
【问题描述】:

我正在开发一个通用应用程序 Win8.1 / WP8.1 我能够发现并连接到配对的蓝牙设备(Stick reader - Rfid)

这就是我的连接方式

变量

    private IAsyncOperation<RfcommDeviceService> connectService;
    private IAsyncAction connectAction;
    private RfcommDeviceService rfcommService;
    private RfcommServiceProvider rfcommProvider;
    private StreamSocketListener listener;
    private DataReader reader;
    private DataWriter writer;

//连接

    public async Task ConnectToServiceAsync(string name)
    {

        DeviceInformation serviceInfo = null;
        foreach (var device in devices)
        {
            if(device.Name == name)
            {
                serviceInfo = device;
                break;
            }
        }

        if (serviceInfo != null)
        {
            this.State = BluetoothConnectionState.Connecting;
            try
            {
                // Initialize the target Bluetooth RFCOMM device service
                connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
                rfcommService = await connectService;
                if (rfcommService != null)
                {
                    rfcommProvider = await RfcommServiceProvider.CreateAsync(rfcommService.ServiceId);

                    // Create a socket and connect to the target 
                    listener = new StreamSocketListener();
                    listener.ConnectionReceived += Listener_ConnectionReceived;

                    connectAction = listener.BindServiceNameAsync(rfcommService.ServiceId.AsString(), SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);


                    await connectAction;//to make it cancellable
                    writer = new DataWriter(socket.OutputStream);
                    reader = new DataReader(socket.InputStream);

                    this.State = BluetoothConnectionState.Connected;
                }
                else
                    OnExceptionOccuredEvent(this, new Exception("Unable to create service.\nMake sure that the 'bluetooth.rfcomm' capability is declared with a function of type 'name:serialPort' in Package.appxmanifest."));
            }
            catch (TaskCanceledException)
            {
                this.State = BluetoothConnectionState.Disconnected;
            }
            catch (Exception ex)
            {
                this.State = BluetoothConnectionState.Disconnected;
                OnExceptionOccuredEvent(this, ex);
            } 


        }
    }

//然后通过监听器等待连接

    private async void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
    {
        DataReader inputreader = new DataReader(args.Socket.InputStream);
        while (true)
        {
            try
            {
                inputreader.InputStreamOptions = InputStreamOptions.Partial;
                // Read first byte (length of the subsequent message, 255 or less). 
                uint sizeFieldCount = await inputreader.LoadAsync(1);
                if (sizeFieldCount != 1)
                {
                    // The underlying socket was closed before we were able to read the whole data. 
                    return;
                }

                // Read the message. 
                uint messageLength = inputreader.ReadByte();
                uint actualMessageLength = await inputreader.LoadAsync(messageLength);
                if (messageLength != actualMessageLength)
                {
                    // The underlying socket was closed before we were able to read the whole data. 
                    return;
                }
                // Read the message and process it.
                string message = inputreader.ReadString(actualMessageLength);
                OnMessageReceivedEvent(this, message);
            }
            catch (Exception ex)
            {
                if (inputreader != null)
                    OnExceptionOccuredEvent(this, ex);
            }
        }
    }

问题是蓝牙棒读卡器从不发送连接请求,它只是读取 rfid 设备 ID 并通过串行端口发送。
所以,我可以连接到设备,但我不知道如何主动监听或读取传入的数据。
任何帮助将不胜感激。

【问题讨论】:

    标签: c# bluetooth windows-runtime rfcomm


    【解决方案1】:

    RFCOMM 通信是客户端/服务器模型。您需要定义一个用于广播服务的服务器和一个连接到该服务的客户端。

    正如我从您发布的代码中看到的那样,它仅包含提供服务的服务器端代码,但没有客户端连接到服务。只有当客户端连接到服务时,才会触发 ConnectionReceived 事件。 我已经编写了一个示例,它在控制台应用程序中托管 RFCOMM 服务,并在之前在 Windows 运行时应用程序中使用该服务 (Code Sample)。

    客户端代码如下:

    rfcommServiceInfoCollection = await DeviceInformation.FindAllAsync(
                    RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));
    
                var count = rfcommServiceInfoCollection.Count;
    
                Debug.WriteLine("Count of RFCOMM Service: " + count);
    
                if(count > 0)
                {
                    lock (this)
                    {
                        streamSocket = new StreamSocket();
                    }
    
                    var defaultSvcInfo = rfcommServiceInfoCollection.FirstOrDefault();
    
                    rfcommDeviceService = await RfcommDeviceService.FromIdAsync(defaultSvcInfo.Id);
    
                    if(rfcommDeviceService == null)
                    {
                        Debug.WriteLine("Rfcomm Device Service is NULL, ID = {0}", defaultSvcInfo.Id);
    
                        return;
                    }
    
                    Debug.WriteLine("ConnectionHostName: {0}, ConnectionServiceName: {1}", rfcommDeviceService.ConnectionHostName, rfcommDeviceService.ConnectionServiceName);
    
                    await streamSocket.ConnectAsync(rfcommDeviceService.ConnectionHostName, rfcommDeviceService.ConnectionServiceName);
    

    顺便说一句,不要忘记在您的 appxmanifest 中添加 RFCOMM 功能。

    例如:

    <m2:DeviceCapability Name="bluetooth.rfcomm">
      <m2:Device Id="any">
        <m2:Function Type="name:obexObjectPush" />
      </m2:Device>
    </m2:DeviceCapability
    

    【讨论】:

    • 嗨,杰弗里,感谢您抽出宝贵时间。它对客户端-服务器模型有意义
    【解决方案2】:

    正如 Jeffrey 所说,这是一个客户端/服务器模型,但在我的情况下,客户端没有任何逻辑,也无法请求任何连接。

    感谢您的样品,它帮助很大。

    在尝试了几件事后,我得到了一些代码,并且“服务器”在 rfcomm 服务中运行和监听:

        public async Task ConnectToServiceAsync(string name)
        {
            lock(this.interlock)
            {
                readBuffer = String.Empty;
            }
            DeviceInformation serviceInfo = null;
            foreach (var device in devices)
            {
                if(device.Name == name)
                {
                    serviceInfo = device;
                    break;
                }
            }
    
            if (serviceInfo != null)
            {
                DeviceName = serviceInfo.Name;
    
                this.State = BluetoothConnectionState.Connecting;
                try
                {
                    // Initialize the target Bluetooth RFCOMM device service
                    connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
    
                    rfcommService = await connectService;
                    if (rfcommService != null)
                    {
                        // Create a socket and connect to the target 
                        socket = new StreamSocket();
                        connectAction = socket.ConnectAsync(rfcommService.ConnectionHostName, rfcommService.ConnectionServiceName, SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
    
                        await connectAction;//to make it cancellable
                        writer = new DataWriter(socket.OutputStream);
                        reader = new DataReader(socket.InputStream);
                        State = BluetoothConnectionState.Connected;
    
                        Task taskReceive = Task.Run(async () => { ListenForMessagesAsync(socket); });
                        taskReceive.ConfigureAwait(false);
    
                    }
                    else
                        OnExceptionOccuredEvent(this, new Exception("Unable to create service.\nMake sure that the 'bluetooth.rfcomm' capability is declared with a function of type 'name:serialPort' in Package.appxmanifest."));
                }
                catch (TaskCanceledException)
                {
                    this.State = BluetoothConnectionState.Disconnected;
                }
                catch (Exception ex)
                {
                    this.State = BluetoothConnectionState.Disconnected;
                    OnExceptionOccuredEvent(this, ex);
                } 
    
    
            }
        }
    

    以及

    中的监听器
        private async Task ListenForMessagesAsync(StreamSocket localsocket)
        {
            while (socket != null)
            {
                try
                {
                    string message = String.Empty;
                    DataReader dataReader = new DataReader(localsocket.InputStream);
                    dataReader.InputStreamOptions = InputStreamOptions.Partial;
    
                    // Read the message and process it.
                    lock (this.interlock)
                    {
                        if (!message.Contains("\r\n"))
                            readBuffer = readBuffer + message;
                        else
                        {
                            var data = message.Split('\r');
                            readBuffer = readBuffer + data[0];
                        }
                        if (readBuffer.Length == 15)
                        {
                            readBuffer = readBuffer.Replace("\r\n", "");
                            OnMessageReceivedEvent(this, readBuffer);
                            readBuffer = String.Empty;
                        }
                        if (readBuffer.Length > 15 || (readBuffer.Length < 15 && readBuffer.Contains("\r\n")))
                            readBuffer = String.Empty;
                    }
    
    
                }
                catch (Exception ex)
                {
                    if (socket != null)
                        OnExceptionOccuredEvent(this, ex);
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-23
      • 1970-01-01
      • 2012-06-09
      • 2015-10-25
      • 2012-01-07
      • 1970-01-01
      • 2012-06-22
      相关资源
      最近更新 更多