2012-01-18 1 views
1

Я разрабатываю двоичный протокол для взаимодействия клиент/сервер с использованием Netty, и количество отправленных байтов не является фиксированной суммой и может быть произвольного размера.Работа с фрагментацией в Netty

Клиент посылает что-то вроде этого:

первых 4 байта для представления идентификационного номера оставшихся байт является строкой

В примере, который я видел, что сообщение было фиксированным размером, но содержимое String может быть любого размера и необходимо обеспечить, чтобы он не был фрагментирован при получении сервером. Как я могу добиться этого в Netty?

Заранее спасибо.

ответ

3

Как вы определяете окончание сообщения? Нуль? Я хотел бы проверить переигрывая декодер Netty:

http://docs.jboss.org/netty/3.2/api/org/jboss/netty/handler/codec/replay/ReplayingDecoder.html

Это делает вещи легко для вас. Просто продолжайте читать, пока не найдете нуль. Если вы закончите байты до того, как достигнете нуля, будет выведено исключение для выхода из метода декодирования. Когда доступно больше байтов, метод декодирования будет вызываться снова с существующими байтами и новыми байтами, объединенными в один ChannelBuffer.

Этот цикл может повторяться до тех пор, пока у вас не будет всего сообщения в ChannelBuffer ..., который затем вы можете перейти на следующий уровень для обработки.

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

+1

Привет Гарет, спасибо за ответ - очень ценится. В настоящее время я не использую ничего, чтобы определить конец сообщения. Как только я получаю идентификатор, вызывая buffer.readLong(), я тогда вызываю buffer.toString (String charsetName) - что не является идеальным. Когда вы ссылаетесь на отправку размера полезной нагрузки, предлагаете ли вы добавить его в начало и дождаться получения длины и использовать это произвольное число, чтобы определить, ждать больше байтов на сервере? – algolicious

+0

Да. Как только у вас есть длина, вы можете вместо этого использовать функцию LengthFieldBasedFrameDecoder (если ваши сообщения, вероятно, будут очень большими, хотя, вероятно, лучше написать свой собственный на основе SimpleChannelUpstreamHandler, так что буфер будет выделен только один раз). – Gareth