Чтение того, что доступно с Socket без блокировки
Я работаю на сервере, который считывает данные, отправленные клиентом, но размер не известен, и я не могу изменить клиент для отправки размера.
Я хочу прочитать данные от клиента, пока он не блокирует и не ждет ответа сервера. Я пытался использовать available()
, он работает иногда, но иногда он просто возвращает ноль, даже когда в потоке есть некоторые данные.
while((len = in.available()) != 0)
in.read(b,0,len);
Есть ли способ сделать это в Java? Я знаю асинхронные методы, но никогда не пробовал это, поэтому, если кто-то может предоставить короткий пример.
Ответы
Ответ 1
Использование available()
- единственный способ сделать это, не прибегая к асинхронным методам.
Вам не нужно полагаться на значение, возвращаемое available()
; просто убедитесь, что есть "некоторые" данные, чтобы убедиться, что read
не будет блокироваться. Однако вы должны проверить значение, возвращаемое read
(фактическое количество байтов, считанных в массиве):
// Process all data currently available
while (in.available() != 0)
{
int nb = in.read(b);
// Process nb bytes
}
Обратите внимание, что available
возврат 0 не означает, что конец данных был достигнут - это просто означает, что нет данных для немедленного потребления (данные могут стать доступными в следующем миллисекунде). Таким образом, вам понадобится другой механизм, чтобы сервер знал, что клиент больше не будет отправлять данные и ожидает ответа.
Ответ 2
InputStream
JavaDocs для метода available()
четко заявляет, что
Обратите внимание, что хотя некоторые реализации InputStream вернут общее количество байтов в потоке, многие не будут. Это никогда правильно использовать возвращаемое значение этого метода для выделения буфера предназначенный для хранения всех данных в этом потоке.
Вместо этого попробуйте метод read()
для чтения данных в буфер фиксированного размера, выделенный, скажем, 4096 байт.
Ответ 3
Я перепробовал много решений, но нашел только одно, которое не блокировало выполнение:
BufferedReader inStream = new BufferedReader(new InputStreamReader(yourInputStream));
String line;
while(inStream.ready() && (line = inStream.readLine()) != null) {
System.out.println(line);
}