分隔符与定长解码器的使用 netty
程序员文章站
2022-05-06 20:08:09
...
netty 的分隔符与定长解码器的使用
4种解码器应对TCP的粘包、拆包问题
new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel ch) {
ChannelPipeline pl = ch.pipeline();
//pl.addLast(new LineBasedFrameDecoder(64)); //换行符解码
//pl.addLast(new FixedLengthFrameDecoder(3)); //固定长度解码
//消息以#作为分隔符,当达到单个消息的最大长度仍然没有查到分隔符,抛出TooLongFrameException
// ByteBuf delimiter = Unpooled.copiedBuffer("#".getBytes());
// pl.addLast(new DelimiterBasedFrameDecoder(16, delimiter));
pl.addLast(new SimpleDecoder());
pl.addLast(new SeverHandler());
}
LengthFieldBasedFrameDecoder 有点问题
public class SimpleDecoder extends LengthFieldBasedFrameDecoder {
private static final int FRAME_MAX_LENGTH = 64;
public SimpleDecoder() {
super(FRAME_MAX_LENGTH, 0, 4, 0, 4);
}
@Override
public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
ByteBuf frame = null;
try {
frame = (ByteBuf) super.decode(ctx, in);
if (null == frame) {
return null;
}
ByteBuffer byteBuffer = frame.nioBuffer();
//return RemotingCommand.decode(byteBuffer);
return decode(byteBuffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != frame) {
frame.release();
}
}
return null;
}
/*
public static RemotingCommand decode(final ByteBuffer byteBuffer) {
int length = byteBuffer.limit();
int oriHeaderLen = byteBuffer.getInt();
int headerLength = getHeaderLength(oriHeaderLen);
byte[] headerData = new byte[headerLength];
byteBuffer.get(headerData);
RemotingCommand cmd = headerDecode(headerData, getProtocolType(oriHeaderLen));
int bodyLength = length - 4 - headerLength;
byte[] bodyData = null;
if (bodyLength > 0) {
bodyData = new byte[bodyLength];
byteBuffer.get(bodyData);
}
cmd.body = bodyData;
return cmd;
}
public static String decode(final ByteBuffer byteBuffer) {
int length = byteBuffer.limit();
System.out.println("len="+length);
byte[] headerData = new byte[length];
byteBuffer.get(headerData);
String res=null;
try {
res = new String(headerData, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return res;
}
*/
public static Object decode(final ByteBuffer byteBuffer) {
int length = byteBuffer.limit();
int oriHeaderLen = byteBuffer.getInt();
System.out.println("decode..");
int headerLength = oriHeaderLen;
byte[] headerData = new byte[headerLength];
byteBuffer.get(headerData);
try {
String res = new String(headerData, "utf-8");
return res;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//RemotingCommand cmd = headerDecode(headerData, getProtocolType(oriHeaderLen));
/*
int bodyLength = length - 4 - headerLength;
byte[] bodyData = null;
if (bodyLength > 0) {
bodyData = new byte[bodyLength];
byteBuffer.get(bodyData);
}
cmd.body = bodyData;
*/
return null;
}
}
4种解码器应对TCP的粘包、拆包问题
new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel ch) {
ChannelPipeline pl = ch.pipeline();
//pl.addLast(new LineBasedFrameDecoder(64)); //换行符解码
//pl.addLast(new FixedLengthFrameDecoder(3)); //固定长度解码
//消息以#作为分隔符,当达到单个消息的最大长度仍然没有查到分隔符,抛出TooLongFrameException
// ByteBuf delimiter = Unpooled.copiedBuffer("#".getBytes());
// pl.addLast(new DelimiterBasedFrameDecoder(16, delimiter));
pl.addLast(new SimpleDecoder());
pl.addLast(new SeverHandler());
}
LengthFieldBasedFrameDecoder 有点问题
public class SimpleDecoder extends LengthFieldBasedFrameDecoder {
private static final int FRAME_MAX_LENGTH = 64;
public SimpleDecoder() {
super(FRAME_MAX_LENGTH, 0, 4, 0, 4);
}
@Override
public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
ByteBuf frame = null;
try {
frame = (ByteBuf) super.decode(ctx, in);
if (null == frame) {
return null;
}
ByteBuffer byteBuffer = frame.nioBuffer();
//return RemotingCommand.decode(byteBuffer);
return decode(byteBuffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != frame) {
frame.release();
}
}
return null;
}
/*
public static RemotingCommand decode(final ByteBuffer byteBuffer) {
int length = byteBuffer.limit();
int oriHeaderLen = byteBuffer.getInt();
int headerLength = getHeaderLength(oriHeaderLen);
byte[] headerData = new byte[headerLength];
byteBuffer.get(headerData);
RemotingCommand cmd = headerDecode(headerData, getProtocolType(oriHeaderLen));
int bodyLength = length - 4 - headerLength;
byte[] bodyData = null;
if (bodyLength > 0) {
bodyData = new byte[bodyLength];
byteBuffer.get(bodyData);
}
cmd.body = bodyData;
return cmd;
}
public static String decode(final ByteBuffer byteBuffer) {
int length = byteBuffer.limit();
System.out.println("len="+length);
byte[] headerData = new byte[length];
byteBuffer.get(headerData);
String res=null;
try {
res = new String(headerData, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return res;
}
*/
public static Object decode(final ByteBuffer byteBuffer) {
int length = byteBuffer.limit();
int oriHeaderLen = byteBuffer.getInt();
System.out.println("decode..");
int headerLength = oriHeaderLen;
byte[] headerData = new byte[headerLength];
byteBuffer.get(headerData);
try {
String res = new String(headerData, "utf-8");
return res;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//RemotingCommand cmd = headerDecode(headerData, getProtocolType(oriHeaderLen));
/*
int bodyLength = length - 4 - headerLength;
byte[] bodyData = null;
if (bodyLength > 0) {
bodyData = new byte[bodyLength];
byteBuffer.get(bodyData);
}
cmd.body = bodyData;
*/
return null;
}
}
推荐阅读