与蓝牙 PC 服务器的蓝牙套接字连接失败“ava.io.IOException:读取失败,套接字可能关闭或超时,读取 ret:-1”

Posted

技术标签:

【中文标题】与蓝牙 PC 服务器的蓝牙套接字连接失败“ava.io.IOException:读取失败,套接字可能关闭或超时,读取 ret:-1”【英文标题】:Bluetooth socket connection with Bluetooth PC server fails "ava.io.IOException: read failed, socket might closed or timeout, read ret: -1" 【发布时间】:2017-06-05 02:58:23 【问题描述】:

我正在尝试在 android 智能手机(客户端)与在 PC 上运行的蓝牙应用程序(服务器)之间建立连接。

下面是客户端的sn-p代码

    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private class ConnectThread extends Thread 
    private BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) 
        mmDevice = device;
        BluetoothSocket tmp = null;

        try 
            //tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);

         catch (IOException e) 
            Log.d(TAG, "create() failed", e);
            e.printStackTrace();
        
        mmSocket = tmp;
    


    public void run() 
        mAdapter.cancelDiscovery();

        try 

            mmSocket.connect();
        

        catch (IOException e)   
        //Exception caught 
        //java.io.IOException: read failed, socket might closed or timeout,      read ret: -1
        ...
        
        ...
    

以下是服务器代码(使用 BlueCover jar)

私人无效 waitForConnection() LocalDevice local = null;

    StreamConnectionNotifier notifier;
    StreamConnection connection = null;

    try 
        local = LocalDevice.getLocalDevice();
        local.setDiscoverable(DiscoveryAgent.GIAC);
        String uuidstr = "00001101-0000-1000-8000-00805F9B34FB";
        String uuid_wo_space = uuidstr.replaceAll("-", "");      

        String url = "btspp://localhost:" + uuid_wo_space  + ";authenticate=false;encrypt=false;name=RemoteBluetooth";
        notifier = (StreamConnectionNotifier) Connector.open(url);
    
    catch (Exception e) 
        e.printStackTrace();
        return;
    

    // waiting for connection
    while(true) 
        try 
            connection = notifier.acceptAndOpen();
            Thread processThread = new Thread(new ProcessConnectionThread(connection));
            processThread.start();
        
        catch(Exception e) 
            e.printStackTrace();
            return;
        
    

我已经阅读了几个链接,建议将 UUID 更改为“00001101-0000-1000-8000-00805F9B34FB”,我已经尝试过了。我还尝试使用 createInsecureRfcommSocketToServiceRecord 创建一个不安全的套接字,但仍然失败,结果相同。

下面是 IOException 堆栈跟踪

java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:900)
at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:912)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:531)

【问题讨论】:

当我检查 BluetoothSocket.java 时,我看到打开套接字后的 connect 方法尝试从输入流中读取通道值,在我的情况下它失败了。不知道这个渠道价值是什么,为什么它对我来说失败了。任何有关这方面的建议都会很有用。 【参考方案1】:

很抱歉写了一个新答案,但这样信息比回复更明显。这是我的设备的 UUID 示例列表:

UUID: 0000xxxx-0000-1000-8000-00805f9b34fb          

i   xxxx    Status  Mode
0   110a    N.A.    
1   1105    Connected   Serial Port Protocol (SPP)
2   1106    Connected   File transfer (FTP)
3   1116    N.A.    
4   112d    Connected   Remote SIM mode
5   112f    Connected   Phone book request
6   1112    Connected   
7   111f    Connected   
8   1132    Connected   Message access request

【讨论】:

谢谢,让我在另一台电脑上试试。我会尽快公布结果。 这次我在另一台电脑上试了一下,得到了同样的结果。设备无法连接 (IOException) 并且可用的 UUID 为空,因此它也无法枚举 UUID。我在服务器组件上做错了什么,你能检查一下那部分吗?此外,当我检查 BluetoothSocket.java 时,我看到 connect 方法在打开套接字后尝试从输入流中读取通道值,在我的情况下它失败了。不知道这个渠道价值是什么,为什么它对我来说失败了。 投票并接受这个作为答案,因为我意识到这是连接到 UUID 的正确方法,以防套接字连接失败。还建议,我的问题确实是基础设施问题(在我尝试过的两台 PC 上)。我卸载并重新安装了 Broadcom BCM2070 驱动程序并建立了连接!!感谢您的帮助。 这是一个非常好的消息,我很高兴你被做空了!【参考方案2】:

通常有一组 UUID 表示不同的操作模式,例如文件传输 (FTP)、远程 SIM、电话簿请求等。

您可以像这样查询并尝试界面上的所有 UUID:

device = (from bd in adapter.BondedDevices
            where bd.Name == "YourDeviceName"
            select bd).FirstOrDefault();

Android.OS.ParcelUuid[] parcel = device.GetUuids();

for (int i = 0; i < parcel.Length; i++) 
    socket = device.CreateRfcommSocketToServiceRecord(parcel[i].Uuid);
    try 
        socket.Connect();
        break;
    
    catch 
        throw new Exception("Unsupported UUID");
    

还要确保没有其他设备连接到 PC/Android 并且有一个打开的套接字,因为一次只能服务一个套接字。您可以拥有任意数量的对,但只能运行一个套接字。

【讨论】:

感谢您的快速周转。我已经尝试过使用 device.GetUuids(),在我的情况下它返回 null。另外,PC 和 Phone 上都没有打开的 socket。 当我检查 BluetoothSocket.Java 的代码时,我看到代码在这里失败(无法从 connect() 方法中的输入流中读取通道值。private int readAll(InputStream is, byte[] b) throws IOException int left = b.length; while(left > 0) int ret = is.read(b, b.length - left, left); if(ret @Sumeet 如果没有从device.GetUuids() 返回的 UUID,您可能会遇到接口故障。您可以尝试在不同的设备上运行相同的代码。我以前见过带有不可靠 BT 接口的设备。特别是一台设备使用串行端口协议 (SPP) 所需的特定 UUID 进行响应,但无法建立套接字。

以上是关于与蓝牙 PC 服务器的蓝牙套接字连接失败“ava.io.IOException:读取失败,套接字可能关闭或超时,读取 ret:-1”的主要内容,如果未能解决你的问题,请参考以下文章

489次成功连接后android蓝牙连接失败

蓝牙连接错误:“jnius.jnius.JavaException:发生 JVM 异常:读取失败,套接字可能关闭或超时,读取 ret:-1”

PC端实现蓝牙开发

蓝牙连接;无法正确发送字符串

Android 不安全的蓝牙连接

我应该如何在 Android 中管理蓝牙连接?