(蓝牙)网络编程中,使用InputStream read方法读取数据阻塞的解决方法
问题如题,这个问题困扰了我好几天,今天终于解决了,感谢[1]。
首先,我要做的是android手机和电脑进行蓝牙通信,android发一句话,电脑端程序至少就要做到接受到那句话。android端发送信息的代码如下:
try {
Log.i("Test", "begin saying hello world");
String test = "Hello world, I am james"; outputStream.write(test.getBytes()); Log.i("Test", "complete saying hello world");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Test", "fail to write 1 to server");
}
电脑服务器端接收程序如下:
byte[] bt = new byte[1024]; int bytes = inputStream.read(bt); String test = new String(bt); Syste.out.println(test);
最后的结果是服务器端阻塞在
int bytes = inputStream.read(bt);
没有能够得到进一步的执行。
最后在[1]中找到了解决方法。通过Inputstream中的availa()函数来获得目前流中可以读取到的字节数目,然后再读取。这个方法的意思是返回此输入流下一个方法调用可以不受阻塞地从此输入流读取(或跳过)的估计字节数。请看改后的电脑端接收信息的代码:
int count = 0; while(count == 0){ count = inputStream.available(); } if( count != 0 ){ System.out.println(count); byte[] bt = new byte[count]; int readCount = 0; while(readCount < count){ readCount += inputStream.read(bt, readCount, count-readCount); } System.out.println(readCount); String xx = new String(bt); System.out.println(xx);
这样,就能实现完整的信息接收了。通过count来保存当前流中可以读取的字节数,然后通过read(byte[],offset,len)函数来读取流中的字节,由于网络通信中,read函数不一定能一次将所有可读的字节读完整,所以用一个readCount来记录已经读到bt数组中的字节,当readCount和count相等后,说明读取完整了。