Цитата:
Сообщение от Sid
Нет, я понимаю что он может не полностью прийти. Однако как тогда определять его конец? Да и bytesAvailable() < 6, в теории заголовок то дойти должен чтобы уже определить каков реальный размер? Хотя если он не дошел полностью то и декриптор не сработает верно.
|
Код:
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer msg) throws Exception {
ChannelBuffer message = (ChannelBuffer) msg;
if (message.readableBytes() < 6) {
return null;
}
message.markReaderIndex();
R2CChannelHandler channelHandler = (R2CChannelHandler) ctx
.getPipeline().getLast();
Crypt crypt = channelHandler.getCrypt();
byte[] header = new byte[6];
message.readBytes(header);
header = crypt.encrypt(header);
ChannelBuffer clientHeader = ChannelBuffers.wrappedBuffer(
ByteOrder.LITTLE_ENDIAN, header);
int size = clientHeader.readByte() << 8;
size |= clientHeader.readByte() & 0xFF;
size -=4;
long opcode = clientHeader.readUnsignedInt();
if ((size < 0) || (size > 10240) || (opcode > 10240)) {
log
.error("PacketFrameDecoder::decode: client sent malformed packet size = "
+ size + " , opcode = " + opcode);
channel.close();
return null;
}
if (message.readableBytes() < size) {
message.resetReaderIndex();
return null;
}
ChannelBuffer frame = ChannelBuffers.buffer(ByteOrder.LITTLE_ENDIAN,
(size + 4));
frame.writeInt((int) opcode);
frame.writeBytes(message.readBytes(size));
return frame;
}
пример:
message.markReaderIndex(); - оставляем метку с начала чтения
и
message.resetReaderIndex(); - возврат к метке если недостаточно данных для чтения.
frame.writeBytes(message.readBytes(size)); - если все гуд - читаем (и сразу удаляем нужное кол-во байт)
зы у меня работает...