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 版本中完全可以继续工作。
【讨论】:
非常感谢您的帮助。createRfcommSocket
和 Android 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,您可以尝试 createInsecureRfcommSocketToServiceRecord
为 createRfcommSocketToServiceRecord
也不适合我。
【讨论】:
这是一系列关于问题的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,没有这样的文件或目录