2 通过分隔符(换行 或者 分隔符)进行粘包和拆包
2020-05-14 本文已影响0人
程序男保姆
通过分隔符进行粘包和拆包
- LineBasedFrameDecoder 通过换行符,即\n或者\r\n对数据进行处理(换行加码没实现)
- DelimiterBasedFrameDecoder 通过用户指定的分隔符对数据进行粘包和拆包处理
/** 3 固定字符解码器 */
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, Unpooled.wrappedBuffer("#".getBytes())));
/** 3 固定字符编码 */
ch.pipeline().addLast(new DelimiterBasedFrameEncoder("#"));
- 客户端发送数据
本地发送数据:0 字节长度:1
本地发送数据:01 字节长度:2
本地发送数据:012 字节长度:3
本地发送数据:0123 字节长度:4
本地发送数据:01234 字节长度:5
- 服务端接收数据
0
01
012
0123
01234
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
/**
* 自定义分隔符加码器
* {@link DelimiterBasedFrameDecoder}
*/
public class DelimiterBasedFrameEncoder extends MessageToByteEncoder<String> {
private String delimiter;
public DelimiterBasedFrameEncoder(String delimiter) {
this.delimiter = delimiter;
}
@Override
protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out)
throws Exception {
System.out.println("自定义分隔符加码器 加码");
// 在响应的数据后面添加分隔符
out.writeBytes((msg + delimiter).getBytes());
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("自定义分隔符加码器 添加完成");
}
}
/**
* 自己实现的通过换行符,即\n或者\r\n对数据进行处理 需配合行解码器
* {@link LineBasedFrameDecoder }
*/
public class LineBasedFrameEncoder extends MessageToByteEncoder<String> {
private int length;
public LineBasedFrameEncoder(int length) {
this.length = length;
}
@Override
protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out)
throws Exception {
// 对于超过指定长度的消息,这里直接抛出异常
if (msg.length() + 4 > length) {
throw new UnsupportedOperationException(
"message length is too large, it's limited " + length);
}
// 如果长度不足,则进行补全
msg = append(msg);
System.out.println("自定义换行加码器 加码");
out.writeBytes(msg.getBytes());
}
// 进行空格补全
private String append(String msg) {
return msg + '\n';
}
}