DataInputStream получает только 2048 байтов данных в Android?

С ПК (на стороне сервера) приложение C#.Net должно отправить 22000 байт данных на устройство Android (на стороне клиента) через Wi-Fi. Но dataInputStream в устройстве Android показывает только 2048 байт.

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

Меня смущает следующее:

  1. Может ли ПК отправлять только 2048 байт данных?
  2. Или устройство Android имеет только 2048 байт для приема данных?
  3. Или dataInputStream показывает только 2048 байтов даже после того, как устройство получило все байты?

    Если (data_received <= 2048 байт) вышеуказанный код работает отлично;

1 ответ

Решение

Вы в основном не должны использовать InputStream.available(), Это говорит о том, сколько данных доступно прямо сейчас - что, возможно, не является целым сообщением, если оно все еще поступает по сети.

Если поток заканчивается в конце сообщения, вы должны просто продолжать цикл, читая блок за раз, пока вы не закончите (желательно не просто читать байт за раз!). Например:

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

Если вам нужно разбить поток на сообщения, вам следует подумать, как это сделать - отправка префикса "длина сообщения" до того, как данные, как правило, является наилучшим вариантом.

После того, как вы прочитали все данные, вы не должны делать это:

String rvdMsgStr = new String(rvdMsgByte);

Это будет использовать кодировку платформы по умолчанию для преобразования байтов в текст. Если это действительно текстовые данные, вы должны использовать перегрузку строкового конструктора, которая позволяет вам явно указать кодировку.

Если это не настоящие текстовые данные, вы не должны пытаться рассматривать их как таковые. Если вам действительно нужно представить его в виде строки, используйте base64.

Также обратите внимание, что нет необходимости использовать DataInputStream здесь, насколько я могу судить.

Другие вопросы по тегам