What is the best way to send out two byte buffers (header + body) in netty
I'm using netty in our project and now we will send out data in following format
- header: int(32bit) which contains the length of body
- body: byte[]
I'm searching the best way which is the fastest to send out about header+body The point is that I want to avoid the array copy since the body has large data.
1) Create a new byte[] and copy the body into it
void sendData1(ChannelHandlerContext ctx, byte[] body) {
byte[] newBuf = new byte[4+body.length];
// header
int len = body.length;
newBuf[3] = (byte) (len & 0xff);
len >>= 8;
newBuf[2] = (byte) (len & 0xff);
len >>= 8;
newBuf[1] = (byte) (len & 0xff);
len >>= 8;
newBuf[0] = (byte) len;
// body
System.arraycopy(body, 0, newBuf, 4, body.length);
final ByteBuf outBuf = Unpooled.wrappedBuffer(newBuf);
ctx.writeAndFlush(outBuf);
}
2) use netty ByteBuf's write function directly
void sendData2(ChannelHandlerContext ctx, byte[] body) {
final ByteBuf outBuf = ctx.alloc().buffer(4+body.length);
// header
outBuf.writeInt(body.length);
// body
outBuf.writeBytes(body);
ctx.writeAndFlush(outBuf);
}
3) Setup two netty ByteBuf and send them out separately and then flush()
void sendData3(ChannelHandlerContext ctx, byte[] body) {
// header
final ByteBuf headBuf = ctx.alloc().buffer(4);
headBuf.writeInt(body.length);
// body
final ByteBuf bodyBuf = Unpooled.wrappedBuffer(body);
ctx.write(headBuf);
ctx.write(bodyBuf);
ctx.flush();
}
4) using netty's CompositeByteBuf
void sendData4(ChannelHandlerContext ctx, byte[] body) {
// header
final ByteBuf headBuf = ctx.alloc().buffer(4);
headBuf.writeInt(body.length);
// body
final ByteBuf bodyBuf = Unpooled.wrappedBuffer(body);
CompositeByteBuf composite = ctx.alloc().compositeBuffer();
composite.addComponents(headBuf, bodyBuf);
ctx.writeAndFlush(composite);
}
Option 1) and option 2) will do Array copy, I think they will have the same performance? Option 3) I'm not sure whether it will do array copy or not, but it will invoke ctx.write() twice and I think this is expensive; Option 4) I'm not sure whether it will work or not. But I have tried it in netty5, seems it only send the head out.
Which one are you using or do you have any good options?
Thanks a lot!