java.io.IOException: 读取失败,套接字可能关闭或超时,在 Android 5.0.1 Lollipop 版本上读取 ret: -1

Posted

技术标签:

【中文标题】java.io.IOException: 读取失败,套接字可能关闭或超时,在 Android 5.0.1 Lollipop 版本上读取 ret: -1【英文标题】:java.io.IOException: read failed, socket might closed or timeout, read ret: -1 on Android 5.0.1 Lollipop version 【发布时间】:2015-05-22 12:20:52 【问题描述】:

我正在与蓝牙设备建立蓝牙套接字连接,并想从设备中读取字节。

我已正确建立连接:

 try 
         Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[]  int.class );
          temp = (BluetoothSocket) m.invoke(mmDevice, 1);
  catch (Exception e) 
 

我正在从蓝牙设备正确读取字节。

我遇到了异常:

java.io.IOException: 读取失败,socket 可能关闭或超时,读取 回复:-1

因此,连接中断,我的设备和蓝牙设备之间的通信也结束了。

这个问题尤其出现在 android 5.0.1 Lollipop 上

谁能有解决方法?

【问题讨论】:

你为什么要为此使用 Java 反射? 我只使用反射来连接蓝牙设备。 我知道,我看到了你的代码,我在问为什么?为什么不使用 Android SDK 提供的 API? 非常有趣。但它适用于反射? 是的,它有效,我们可以进一步使用temp 对象来调用connect() 方法,即temp.connect(); 【参考方案1】:

使用createRfcommSocketToServiceRecord 代替createRfcommSocket

createRfcommSocketToServiceRecord 获取您传递的 UUID 并使用 SDP 来决定用于连接的无线电频道。它还检查以确保服务器正在侦听具有相同 UUID 的远程端点。这样,获得连接是最可靠的方式:它总是使用正确的通道,如果打开连接成功,你知道另一端的东西可以理解你的协议。

相比之下,createRfcommSocket 只是连接到您告诉它的频道。无法知道远程端点上是否有任何东西在监听:您只知道设备在那里。此外,您选择的无线电频道可能完全不合适。这就是为什么这个函数没有在API中发布,而另一个函数是首选。

createRfcommSocket 一开始可能看起来更可靠,但这是因为它没有检查另一个端点是否存在侦听器:它忽略了一些错误情况。这对于试验来说可能没问题,但对于生产系统来说没有用,因为用户经常忘记在另一个端点上启动服务器,你的应用程序会以令人困惑的方式失败。

当然,由于createRfcommSocket 未在 API 中发布,因此您无法保证它在未来的 Android 版本中完全可以继续工作。

【讨论】:

非常感谢您的帮助。createRfcommSocketAndroid 5.0.1 Lollipop 有什么具体问题吗?我在Lollipop 中更多地遇到了这个错误 我不确定,但我提供的方法因为UUID更可靠 诸如“createRfcommSocket...”之类的函数仅用于为客户端创建套接字。但是,我在服务器端遇到了这个问题。 (我使用 serversocket 制作了套接字)。你知道如何在服务器端修复它吗? 来自文档:“要创建用于连接到已知设备的 BluetoothSocket,请使用 BluetoothDevice.createRfcommSocketToServiceRecord()。然后调用 connect() 以尝试连接到远程设备。此调用将阻塞,直到连接已建立或连接失败。要将 BluetoothSocket 创建为服务器(或“主机”),请参阅 BluetoothServerSocket 文档。”【参考方案2】:

我在 6.0.1 上遇到过同样的问题,在阅读了各种线程/论坛/博客上的相关内容后,我了解到这是因为缺少回退。您可以通过捕获异常并创建所需的回退来处理它。

更具体地说,BluetoothManager 返回一个 默认值 -1,这是不可接受的状态,因此会出现错误。这将引发一个异常,可以处理该异常以创建一个 fallback 来通过替换 -1 的错误来解决问题。

这是帮助我的链接:

https://github.com/don/BluetoothSerial/issues/89

参考: IOException: read failed, socket might closed - Bluetooth on Android 4.3

【讨论】:

【参考方案3】:

我只在 Lollipop 上遇到过类似问题(正在使用以前的版本),将“createRfcommSocket”替换为“createInsecureRfcommSocket”解决了这个问题。

如果您选择官方 API,您可以尝试 createInsecureRfcommSocketToServiceRecordcreateRfcommSocketToServiceRecord 也不适合我。

【讨论】:

这是一系列关于问题的cmets;请尽可能发布它们。 即使使用不安全的方法,同样的错误仍然存​​在。【参考方案4】:

我遇到了与 Lollipop 类似的问题(在本例中为 5.0.2)。运行 Kitkat 时我没有看到任何问题。我一直在使用 createInsecureRfcommSocketToServiceRecord。我尝试了一些使用反射的建议方法,但似乎没有帮助(我认为该解决方案与旧版本的 Android 有关)。不过需要明确的是,当我连接到多个 SPP 设备(条形码阅读器和带有流动网络蓝牙无线电的 I/O 板)时,通常会发生这种情况。我正在努力寻找解决方案,并认为可能没有解决方案,因为如果您连接到具有相同 UUID 的两台设备(在本例中为通用 SPP 设备),Lollipop 中可能存在问题。

【讨论】:

不要添加这样的“cmets”作为答案。

以上是关于java.io.IOException: 读取失败,套接字可能关闭或超时,在 Android 5.0.1 Lollipop 版本上读取 ret: -1的主要内容,如果未能解决你的问题,请参考以下文章

java.io.IOException: 读取失败,套接字可能关闭或超时,在 Android 5.0.1 Lollipop 版本上读取 ret: -1

任务 ':app:compileDebugKotlin' java.io.IOException 执行失败

Hive tez 查询失败并出现 java.io.IOException

Gradle 构建失败 java.io.IOException:输出 jar 为空

使用自定义字体 [java.io.IOException:读取字体数据时出错。]

ant jar 错误:执行失败:java.io.IOException:无法运行程序...$aapt":错误=2,没有这样的文件或目录