J2ME,InputStream 在通过蓝牙接收 40K 数据后挂断
Posted
技术标签:
【中文标题】J2ME,InputStream 在通过蓝牙接收 40K 数据后挂断【英文标题】:J2ME, InputStream hangs up after receving 40K of data over Bluetooth 【发布时间】:2009-11-18 11:43:27 【问题描述】:通过蓝牙从 PC 向我的手机 (N73) 发送数据时,输入流似乎挂断了。 InputStream 派生自 StreamConnection。
PC 软件内置于 VB.net。 Java ME 中的移动设备。
InputStream 是否有一个在读取大块数据时需要清空的内部缓冲区? 正在以 10Kb 到 15Kb 范围的块接收数据,并且在接收到第 3 个块后停止读取。 奇怪的是我没有收到任何异常。
我浏览了 InputStream 类 API 文档,找不到任何 InputStream clear 或 empty 方法。 只有一个reset()方法,不知道是干什么用的?
【问题讨论】:
你是如何读取数据的? (即您调用的是哪种“读取”方法?) read(byte[] b, int off, int len) 【参考方案1】:InputStream.reset()
是您在使用 Inpustream.mark()
强制 InputStream 创建一个允许您多次读取相同数据的内部缓冲区后调用的方法,假设 InputStream 通过在调用时返回 true 来支持它InputStream.markSupported()
.
至于数据传输问题,我们谈论的是在 Symbian OS 9.1 之上运行 Series60 第三版的手机。考虑到 JSR-82 的 Symbian 测试范围如此广泛,像 InputStream 上的 40k 限制这样简单的实现错误似乎不太可能。
如果服务器以低得多的比特率发送更小的块,手机的行为会改变吗? 手机在读取更多数据之前是否会处理接收数据? MIDlet 还在做什么?即使在蓝牙 InputStream 阻塞之后,其他一切是否都按预期工作?
我确实记得 JSR-82 实现中的一个相当重要的错误,该错误可能仅在创建初始 N73 固件后才修复:在任何事件调度线程中都不要使用蓝牙(不是来自任何方法,如 MIDlet.startApp()
、Canvas.keyPressed()
、CommandListener.commandAction()
、PlayerListener.playerUpdate()
...)。
您最好只在您自己编写的Thread.run()
方法中使用蓝牙。
【讨论】:
我没有尝试以较低的比特率发送较小的块?如何控制手机的蓝牙比特率,我认为我没有启用该设置,不管它是什么,它现在默认运行?这似乎是一个重要的问题。手机只是将所有数据块存储在 Vector 的单独插槽中,每个插槽都是一个字节数组。此时的 Midlet 只是从输入流(第一个线程)读取,写入输出流(第二个线程)并绘制画布(第三个线程)。而这幅画此刻更像是我调试手机的日志。 我在网上找到了一个重要的 PDF,标题是 Andre Klingsheim 的“J2ME 蓝牙编程”。在蓝牙陷阱类别中,他指出:“还必须注意一次发送的数据量。6600 和 P900 智能手机中使用的缓冲区之一似乎是 512 字节。当尝试传输超过 512 字节时一次,接收方获得 512 个字节,然后连接将冻结。发送 512 个字节,刷新,发送 1 个字节,然后刷新工作正常。然后连接保持活动状态。" 这是一个已知问题,如诺基亚 wiki KIJ000109 上的“在 MIDlets 中使用蓝牙串行端口”中报告的那样 概述 在某些诺基亚 S60 和系列 80 设备中读取传入流无法正常工作。针对 S60 第 2 版报告:Nokia 6600 v.4.09.1 S60 第 2 版,功能包 1:Nokia 6620、Nokia 6260、Nokia 6670、Nokia 7610 Series 80 第 2 版:Nokia 9300、Nokia 9500 此文档的日期似乎是 2004 . 他们现在应该已经解决了这个错误。 我当然希望最近的手机已经解决了缓冲问题,但请记住,即使您的 N73 比您引用的所有手机好一个数量级,它仍然可能超过 3 年. 对于标准输出和标准错误,见***.com/questions/225489/…以上是关于J2ME,InputStream 在通过蓝牙接收 40K 数据后挂断的主要内容,如果未能解决你的问题,请参考以下文章