【问题标题】:ServerSocket while not breaks on image data inputstreamServerSocket 虽然不中断图像数据输入流
【发布时间】:2015-04-16 22:56:32
【问题描述】:

我尝试使用蓝牙将图像从一台设备发送到另一台设备。为此,我使用 Android 蓝牙聊天应用程序源代码,当我发送字符串时它工作正常。但如果我将图像作为字节数组发送,while 循环不会中断或从 Inputstream 读取时未达到 EOF。

型号:1

它正确接收图像。但这里我需要传递resultByteArray长度。但我不知道长度。如何知道输入流中字节数组的长度? inputstream.available() 返回 0。

while(true)
{
    byte[] resultByteArray = new byte[150827];
    DataInputStream dataInputStream = new DataInputStream(mmInStream);
    dataInputStream.readFully(resultByteArray);

    mHandler.obtainMessage(AppConstants.MESSAGE_READ, dataInputStream.available(),-1, resultByteArray).sendToTarget();
}

型号:2

在这段代码中,while循环不会中断,

ByteArrayOutputStream bao = new ByteArrayOutputStream();

byte[] resultByteArray = new byte[1024];

int bytesRead;
while ((bytesRead = mmInStream.read(resultByteArray)) != -1) {
    Log.i("BTTest1", "bytesRead=>"+bytesRead);
    bao.write(resultByteArray,0,bytesRead);
}

final byte[] data = bao.toByteArray();

也尝试了byte[] resultByteArray = IOUtils.toByteArray(mmInStream);,但它也不起作用。我关注了Bluetooth chat sample

如何解决这个问题?

【问题讨论】:

  • 您的服务器是否关闭了它的输出流?如果它不应该关闭它,您可以先传输长度,然后传输数据。
  • 不,我的客户端在将图像字节数组写入输出流后没有关闭输出流。有写长度的示例代码吗?
  • 将整数转换为字节数组(您可以搜索该短语)并将其写入流中。
  • 是的,但是在接收端如何区分int数据和图像数据?
  • 没办法;你只知道它是先发送的。就像您需要发送两张图片(第一张,然后是第二张)一样。但是你为什么不想关闭连接呢?

标签: java android io java-io


【解决方案1】:

如评论中所述,服务器需要将图像的长度放在实际图像数据的前面。并且图像长度信息的长度应该固定为4字节。

然后在while循环中,需要先获取4个字节才能算出图片的长度。之后,从输入流中读取精确长度的字节。那是实际的图像。

在连接处于活动状态期间,while 循环不需要中断。实际上它需要在同一个while循环中等待另一个图像数据。 InputStream.read() 是一个阻塞函数,线程将处于休眠状态,直到从输入流中接收到足够的数据。

然后你可以期待在前一个图像数据之后的另外 4 个字节作为另一个图像的开始。

while(true) {
    try {
        // Get the length first
        byte[] bytesLengthOfImage = new byte[4];
        mmInStream.read(bytesLengthOfImage);
        int lengthOfImage = 0;
        {
            ByteBuffer buffer = ByteBuffer.wrap(bytesLengthOfImage);
            buffer.order(ByteOrder.BIG_ENDIAN);  // Assume it is network byte order.
            lengthOfImage = buffer.getInt();
        }

        byte[] actualImage = new byte[lengthOfImage];   // Mind the memory allocation.
        mmInStream.read(actualImage);

        mHandler.obtainMessage(AppConstants.MESSAGE_READ, lengthOfImage,-1, actualImage).sendToTarget();
    } catch (Exception e) {
        if(e instanceof IOException) {
            // If the connection is closed, break the loop.
            break;
        }
        else {
            // Handle errors
            break;
        }
    }
}

这是一种简化的通信协议。有一个用于轻松实现协议的开源框架,称为 NFCommunicator。

https://github.com/Neofect/NFCommunicator

对于一个简单的项目来说,这可能是一个过度规范,但值得一看。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2013-06-05
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多