Как получить размер полученных данных SocketChannel

Я пишу сервер для своего приложения, которое должно получать данные от клиента и что-то делать. Связь осуществляется с использованием SocketChannel, но есть проблема: я могу прочитать только ранее указанное количество байтов из него (начиная с javadoc для channel.read(ByteBuffer dst))

Предпринимается попытка прочитать до r байтов из канала, где r — количество байтов, оставшихся в буфере.

Есть ли способ получить размер данных, которые в данный момент находятся в канале, и прочитать все это в byte[]?


person TEXHIK    schedule 30.10.2015    source источник
comment
Вы не можете этого сделать. Просто используйте средний буфер и используйте значение, возвращаемое чтением, чтобы узнать, сколько данных только что было прочитано.   -  person user996142    schedule 30.10.2015
comment
@ user996142 Это полностью эквивалентно тому, что вы только что сказали, что это невозможно.   -  person user207421    schedule 01.11.2015


Ответы (2)


есть проблема: я могу прочитать только ранее указанное количество байтов из него

Это неправильно.

(начиная с javadoc для channel.read(ByteBuffer dst))

Предпринимается попытка прочитать до r байтов из канала, где r — количество байтов, оставшихся в буфере.

Вы пропустили слова «до». Нет проблем. Если доступен один байт, будет прочитан один байт, независимо от количества места, оставшегося в ByteBuffer.

Есть ли способ получить размер данных, которые в данный момент находятся в канале, и прочитать все это в byte[]?

Это именно то, что происходит. Объем данных, «в настоящее время находящихся в канале» == объем данных, которые будут прочитаны, при условии, что в ByteBuffer осталось место >= размер данных в приемном буфере сокета, и это будет значение, возвращаемое read().

person user207421    schedule 30.10.2015
comment
Я не пропустил эти слова, но таким образом, я должен создать буфер с емкостью Integer.MAX_VALUE, если я хочу 100% прочитать все данные из канала, а это не очень хорошая идея. Но я уже сделал это, отправив размер данных в первых 4 байтах. - person TEXHIK; 01.11.2015
comment
Так что ваш вопрос был некорректно сформулирован. «Все данные в настоящее время в канале» могут означать только «все данные в настоящее время в буфере приема сокета». Если вместо этого вы имеете в виду «все данные, которые когда-либо будут отправлены по каналу», это, конечно, потенциально бесконечно. - person user207421; 02.11.2015

Я думаю, что нет. Вы должны управлять этим самостоятельно. Вы используете сериализованные объекты или создали свой собственный протокол?

person Kaputnik120    schedule 30.10.2015
comment
Я отправляю объект, сериализованный в byte[] по умолчанию в Java-сериализации. Я знаю, что могу отправить размер массива, но может есть способ не делать этого самому? - person TEXHIK; 30.10.2015
comment
Посмотрите мой блог, мне пришлось сделать это при отправке сериализованных объектов через UDP: ulrichbuschbaum.wordpress.com/2015/04/06/ - person Kaputnik120; 30.10.2015
comment
Ваш блог содержит множество ошибок, начиная со странного заявления о том, что отсутствие потоковой передачи в UDP связано с Java, и кодом, игнорирующим длину, возвращаемую receive(), и отправителем, присоединяющимся к группе многоадресной рассылки, когда в этом нет необходимости. Там нет ничего, что отвечало бы на этот вопрос. - person user207421; 31.10.2015
comment
Вы неправильно это поняли. Это связано с протоколом, а не с Java. Возможно, мне следовало объяснить это яснее. :) - person Kaputnik120; 31.10.2015
comment
Я ничего не понял. Я знаю, из-за чего это. Так я понял, что это ошибка. Когда вы заявляете: «В Java есть небольшая проблема с использованием UDP...», вы делаете ошибку. Конечно, вам нужно выразить это более четко. - person user207421; 31.10.2015