通过蓝牙使用 SPP 发送和接收文件的问题

发布于 2024-10-04 23:25:50 字数 1029 浏览 3 评论 0原文

我正在尝试使用 SPP 通过蓝牙(在 Java 中,使用 BlueCove API)在两台 PC 之间传输文件(大小约为 6 MB 的 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 才能实现此功能?

I am attempting to transfer files (MP3s about six megabytes in size) between two PCs using SPP over Bluetooth (in Java, with the BlueCove API). I can get the file transfer working fine in one direction (for instance, one file from the client to the server), but when I attempt to send any data in the opposite direction during the same session (i.e., send a file from the server to the client), the program freezes and will not advance.

For example, if I simply:

StreamConnection conn;
OutputStream outputStream;

outputStream = conn.openOutputStream();

....

outputStream.write(data);  //Data here is an MP3 file converted to byte array

outputStream.flush();

The transfer works fine. But if I try:

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);
}

Both the client and the server freeze, and will not advance. I can see that the file transfer is actually happening at some point, because if I kill the client, the server will still write the file to the hard drive, with no issues. I can try to respond with another file, or with just an integer, and it still will not work.

Anyone have any ideas what the problem is? I know OBEX is commonly used for file transfers over Bluetooth, but it seemed overkill for what I needed to do. Am I going to have to use OBEX for this functionality?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

尹雨沫 2024-10-11 23:25:50

它可能很简单,因为两个程序都陷入阻塞接收调用,等待另一端说些什么......尝试添加大量日志语句,以便您可以看到每个程序所处的“状态”(即,所以它给出你一个正在运行的评论,例如“试图接收”,“得到xxx数据”,“试图回复”等),或设置调试,等到它卡住,然后停止其中一个并单步执行它。

It could be as simple as both programs stuck in blocking receive calls, waiting for the other end to say something... try adding a ton of log statements so you can see what "state" each program is in (ie, so it gives you a running commentary such as "trying to recieve", "got xxx data", "trying to reply", etc), or set up debugging, wait until it gets stuck and then stop one of them and single step it.

不气馁 2024-10-11 23:25:50

您当然可以使用 SPP 在应用程序之间传输文件(假设您使用应用程序在两端发送和接收)。从代码片段中很难看出你的程序出了什么问题。
我猜测您必须关闭流,以向另一方表明您已完成发送数据。请注意,即使您将整个文件写在一个块中,SPP /蓝牙协议层也可能会将其分段,并且另一端可以接收片段,因此您需要有一些协议来指示传输完成。

you can certainly use SPP to transfer file between your applications (assuming you are sending and receiving at both ends using your application). From the code snippet it is difficult to tell what is wrong with your program.
I am guessing that you will have to close the stream as an indication to the other side that you are done with sending the data .. Note even though you write the whole file in one chunk, SPP / Bluetooth protocol layers might fragment it and the other end could receive in fragments, so you need to have some protocol to indicate transfer completion.

待"谢繁草 2024-10-11 23:25:50

如果不查看客户端代码,很难说,但我的猜测,如果两者运行相同的代码(即都先写入,然后读取),则 outputStream 需要在读取发生之前关闭(否则,双方都将等待对方关闭自己的一侧以退出读取循环,因为 read() 仅返回 -1 当另一侧关闭时)。

如果不应该关闭流,则停止读取的条件不能是等待-1。 (因此,要么将其更改为首先传输文件大小,要么使用其他机制)。

It is hard to say without looking at the client side code, but my guess, if the two are running the same code (i.e. both writing first, and then reading), is that the outputStream needs to be closed before the reading occurs (otherwise, both will be waiting for the other to close their side in order to get out of the read loop, since read() only returns -1 when the other side closes).

If the stream should not be closed, then the condition to stop reading cannot be to wait for -1. (so, either change it to transmit the file size first, or some other mechanism).

☆獨立☆ 2024-10-11 23:25:50

为什么决定使用 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);

Why did you decide to use ByteArrayOutputStream? Try following code:

    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();
    }

And to convert the outputStream you could do something like this:

byte currentMP3Bytes[] = outputStream.toString().getBytes();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(currentMP3Bytes);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文