回顾TCP粘包/分包问题的解决方法
1.消息定长
2.在包尾都增加特殊字符进行分割
3.将消息分为消息头和消息体
针对这三种方法,下面我会分别举例验证
FixedLengthFrameDecoder类
对应第一种解决方法:消息定长
(1)例1:服务端代码:
public class Server4 {
public static void main(String[] args) throws SigarException {
//boss线程监听端口,worker线程负责数据读写
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
try{
//辅助启动类
ServerBootstrap bootstrap = new ServerBootstrap();
//设置线程池
bootstrap.group(boss,worker);
//设置socket工厂
bootstrap.channel(NioServerSocketChannel.class);
//设置管道工厂
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//获取管道
ChannelPipeline pipeline = socketChannel.pipeline();
//定长解码类
pipeline.addLast(new FixedLengthFrameDecoder(19));
//字符串解码类
pipeline.addLast(new StringDecoder());
//处理类
pipeline.addLast(new ServerHandler4());
}
});
//绑定端口
ChannelFuture future = bootstrap.bind(8866).sync();
System.out.println("server start ...... ");
//等待服务端监听端口关闭
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//优雅退出,释放线程池资源
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
class ServerHandler4 extends SimpleChannelInboundHandler <String>{
//用于记录次数
private int count = 0;
//读取客户端发送的数据
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("RESPONSE--------"+msg+";"+" @ "+ ++count);
}
//新客户端接入
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelActive");
}
//客户端断开
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelInactive");
}
//异常
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//关闭通道
ctx.channel().close();
//打印异常
cause.printStackTrace();
}
}
(2)例1:客户端代码:
public class Client4 {