ServerSocket 不中断图像数据输入流

ServerSocket while not breaks on image data inputstream

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

型号:1

它接收图像 properly.But 这里我需要传递 resultByteArray length.But 我不知道 length.How 知道输入流中字节数组的长度? inputstream.available() returns 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);但也没有works.I跟进Bluetooth chat sample

如何解决这个问题?

如评论中所述,服务器需要将图像的长度放在实际图像数据的前面。并且图片长度信息的长度应该是固定的,比如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

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