我正在尝试使用蓝牙SPP(使用BlueCove API的Java)在两台PC之间传输文件(大小约为6兆字节的MP3)。我可以让文件传输在一个方向上正常工作(例如,从客户端到服务器的一个文件),但是当我尝试在同一会话期间以相反方向发送任何数据时(即,从服务器发送文件)对于客户来说,程序会冻结而不会前进。
例如,如果我只是:
StreamConnection conn;
OutputStream outputStream;
outputStream = conn.openOutputStream();
....
outputStream.write(data); //Data here is an MP3 file converted to byte array
outputStream.flush();
转移工作正常。但如果我尝试:
StreamConnection conn;
OutputStream outputStream;
InputStream inputStream;
ByteArrayOutputStream out = new ByteArrayOutputStream();
outputStream = conn.openOutputStream();
inputStream = conn.openInputStream();
....
outputStream.write(data);
outputStream.flush();
int receiveData;
while ((receiveData = inputStream.read()) != -1) {
out.write(receiveData);
}
客户端和服务器都冻结,不会前进。我可以看到文件传输实际上是在某个时刻发生的,因为如果我终止客户端,服务器仍然会将文件写入硬盘驱动器,没有任何问题。我可以尝试用另一个文件来回复,或只用一个整数,它仍然无法工作。
任何人都有任何想法是什么问题?我知道OBEX通常用于通过蓝牙进行文件传输,但对于我需要做的事情来说,它似乎有些过分。我是否必须使用OBEX来实现此功能?
答案 0 :(得分:2)
这可能就像两个程序都阻塞接收呼叫一样简单,等待另一端说些什么......尝试添加大量的日志语句,这样你就可以看到每个程序所处的状态(即,所以它给你一个运行的评论,如“试图收到”,“得到xxx数据”,“试图回复”等,或设置调试,等到它卡住,然后停止其中一个并单步执行
答案 1 :(得分:1)
您当然可以使用SPP在您的应用程序之间传输文件(假设您使用您的应用程序在两端发送和接收)。从代码片段中很难说出您的程序出了什么问题。 我猜你必须关闭流,作为对方发送数据的指示。注意即使你把整个文件写在一个块中,SPP /蓝牙协议层可能会碎片化它另一端可以分段接收,因此您需要一些协议来指示传输完成。
答案 2 :(得分:1)
很难说没有查看客户端代码,但我的猜测,如果这两个代码运行相同的代码(即先写入然后再读取),那么outputStream
需要是在读取发生之前关闭(否则,两者都将等待另一方关闭它们以便退出读取循环,因为read()
仅在另一方关闭时返回-1
。 / p>
如果不应关闭流,则停止读取的条件不能等待-1
。 (因此,要么先将其更改为传输文件大小,要么使用其他机制)。
答案 3 :(得分:0)
你为什么决定使用ByteArrayOutputStream?请尝试以下代码:
try {
try {
byte[] buf = new byte[1024];
outputstream = conn.openOutputStream();
inputStream = conn.openInputStream();
while ((n = inputstream.read(buf, 0, 1024)) > -1)
outputstream.write(buf, 0, n);
} finally {
outputstream.close();
inputstream.close();
log.debug("Closed input streams!");
}
} catch (Exception e) {
log.error(e);
e.printStackTrace();
}
要转换outputStream,您可以执行以下操作:
byte currentMP3Bytes[] = outputStream.toString().getBytes();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(currentMP3Bytes);