Я использую класс Java BufferedInputStream
для чтения байтов, отправленных в сокет. Данные в сокет - это HTTP-форма, так как обычно это заголовок с определенной длиной содержимого, затем некоторый контент.Чтение сокета с использованием BufferedInputStream
Проблема, с которой я сталкиваюсь, заключается в том, что иногда BufferedInputStream.read()
не будет читать полный объем данных, отправленных на него. Он возвращает количество прочитанных байтов, но это намного меньше, чем было отправлено. Я проверил байты, отправленные с Wireshark и может подтвердить полное сообщение передается)
Пример кода ниже:.
BufferedInputStream inFromClient = new BufferedInputStream(socket.getInputStream());
int contentLength = getContentLengthFromHeader();
byte[] b = new byte[contentLength];
int bytesRead = inFromClient.read(b, 0, contentLength);
После чтения() завершается иногда bytesRead
равно contentLength
, но и в других случаях read(), похоже, не читает до конца содержимого. Есть ли у кого-нибудь идеи о том, что происходит? Является ли вывод буферизации Java? Есть ли лучшие способы чтения из сокетов?
Параметр 'channelCopy()' цикл метода должен быть 'в то время как (src.read (буфер)> 0 || buffer.position()> 0). Вы можете избавиться от материала в конце, который заканчивается в EOF. – EJP
Привет @ejp, спасибо за комментирование; Я ожидаю, что вы, вероятно, правы, но я не совсем понимаю - можете ли вы доработать? Если я заменю 'while (src.read (buffer)! = -1)' на то, что вы предлагаете, мне кажется, что операция копирования может завершиться раньше, если, например, временно перейдет на перенос http (read может вернуть 0 потому что новых данных нет, и мы можем закончить дренирование буфера, который у нас есть, оставив его в позиции 0), но было бы неправильно завершить цикл в это время (поскольку EOF не был достигнут) - чего я здесь не вижу ? – JVMATL
Вам не хватает части после '|| .' – EJP