ServerSocket while not breaks on image data inputstream

I tried to send an image from One device to other Device using Bluetooth.For that I take Android Bluetooth chat application source code and it works fine when I send String.But If i send image as byte array the while loop not breaks or EOF not reached when read from Inputstream.

Model:1

It receives image properly.But here I need to pass resultByteArray length.But I dont know the length.How to know the length of byte array in inputstream? 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();
}

Model:2

In this code while loop not breaks,

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

Also tried byte[] resultByteArray = IOUtils.toByteArray(mmInStream);but it also not works.I followed Bluetooth chat sample.

How to solve this issue?

Answer

As noted in the comment, the server needs to put the length of image at front of the actual image data. And the length of the image length information should be fixed like 4 bytes.

Then in the while loop, you need to get 4 bytes first to figure out the length of the image. After that, read bytes of the exact length from the input stream. That is the actual image.

The while loop doesn’t need to break during the connection is alive. Actually it needs to wait another image data in the same while loop. The InputStream.read() is a blocking function and the thread will be sleeping until it receives enough data from the input stream.

And then you can expect another 4 bytes right after the previous image data as a start of another image.

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

This is a kind of simplified communication protocol. There is an open source framework for easy protocol implementation, called NFCommunicator.

https://github.com/Neofect/NFCommunicator

It might be an over specificiation for a simple project, but is worth a look.