krishh
krishh

Reputation: 1571

Does DataInputStream receives only 2048 bytes of data in Android?

From PC (server side) the C#.Net application has to sent 22000 bytes of data to an Android device (client side) via Wi-Fi. But dataInputStream in Android device is showing only 2048 bytes of it.

dataInputStream = new DataInputStream(workerSocket.getInputStream());
byte[] rvdMsgByte = new byte[dataInputStream.available()];
for (int i = 0; i < rvdMsgByte.length; i++)
    rvdMsgByte[i] = dataInputStream.readByte();
String rvdMsgStr = new String(rvdMsgByte);

I am confused with the following:

  1. Is PC can send only 2048 bytes of data?
  2. Or, is Android device has only 2048 bytes of capacity to receive data?
  3. Or, Does dataInputStream shows only 2048 bytes even after device received all bytes?

    If (data_received <= 2048 bytes) Above code works perfect;

Upvotes: 0

Views: 1452

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500035

You basically shouldn't be using InputStream.available(). That tells you how much data is available right now - which may well not be the whole message, if it's still coming over the network.

If the stream will end at the end of the message, you should simply keep looping, reading a block at a time until you're done (preferrably not just reading a byte at a time!). For example:

byte[] readFully(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[8 * 1024]; // 8K buffer
    int bytesRead;
    while ((bytesRead = input.read(buffer)) > 0) {
        output.write(buffer, 0, bytesRead);
    }
    return output.toByteArray();
}

If you need to break your stream up into messages, you should consider how to do that - sending a "message length" prefix before the data is usually the best option.

Once you've read all the data, you should not do this:

String rvdMsgStr = new String(rvdMsgByte);

That will use the platform default encoding to convert the bytes into text. If this is genuinely text data, you should use the string constructor overload which lets you specify the encoding explicitly.

If it's not genuinely text data, you shouldn't be trying to treat it as such. If you really need to represent it as a string, use base64.

Also note that there's no need to use DataInputStream here, as far as I can tell.

Upvotes: 5

Related Questions