這裏寫自定義目錄標題
使用分隔符解碼器
服務端
import io.netty.bootstrap.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
public class Server {
public void bind(int port) {
//1、創建線程池,服務端創建連個線程池
NioEventLoopGroup boosGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
//2、創建服務端啓動對象
ServerBootstrap bootstrap = new ServerBootstrap();
//3、配置啓動對象
bootstrap.group(boosGroup, workerGroup) //4、添加線程池
.channel(NioServerSocketChannel.class) //5、使用 NioServerSocketChannel 作爲服務器 端通道實現
.option(ChannelOption
.SO_BACKLOG, 128) //6、設置線程隊列中等待連接的個數
.childOption(ChannelOption.SO_KEEPALIVE, true) //7、保持活動狀態連接
.childHandler(new ChannelInitializer<SocketChannel>() { //8、創建一個通道初始化對象
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();//9、往 Pipeline 鏈中添加自定義的業務 處理 handler
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
//10、添加分隔符解碼器(指定$_爲分隔符,如果超過1024個字跡未找到分隔符將會報錯)
pipeline.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
//11、添加字符轉解碼器,將消息轉爲字符串
pipeline.addLast(new StringDecoder());
//12、添加自定義的處理類
pipeline.addLast(new EchoServerHandler());
}
});
try {
//13、啓動服務器端並綁定端口,等待接受客戶端連接(bind爲非阻塞,sync爲阻塞式的)
ChannelFuture channelFuture = bootstrap.bind(port).sync();
System.out.println("------Server is ready------");
//14、關閉通道(closeFuture爲非阻塞,sync爲阻塞式的)
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
System.out.println("------Chat Server is close------");
} finally {
boosGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
Server chatServer = new Server();
chatServer.bind(9999);
}
class EchoServerHandler extends SimpleChannelInboundHandler<String>{
int count = 0;
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
String body = (String)msg;
System.out.println("This is "+ ++count + "times receive client : ["+ body + "]");
body += "$_";
ByteBuf echo = Unpooled.copiedBuffer(body.getBytes());
ctx.writeAndFlush(echo);
}
public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause){
cause.printStackTrace();
ctx.close();
}
}
}
客戶端
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
public class Client {
public void connect(int port,String host){
//初始化線程池
NioEventLoopGroup group = new NioEventLoopGroup();
//創建啓動器
Bootstrap bootstrap = new Bootstrap();
//配置啓動器
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();//9、往 Pipeline 鏈中添加自定義的業務 處理 handler
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
//10、添加分隔符解碼器(指定$_爲分隔符,如果超過1024個字跡未找到分隔符將會報錯)
pipeline.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
//11、添加字符轉解碼器,將消息轉爲字符串
pipeline.addLast(new StringDecoder());
//添加自定義的處理類
pipeline.addLast(new EchoClientHandler());
}
});
try{
ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
System.out.println("連接異常");
}
}
public static void main(String[] args) {
new Client().connect(9999,"127.0.0.1");
}
class EchoClientHandler extends SimpleChannelInboundHandler<String>{
private int counter;
static final String ECHO_REQ = "Hi,Ni hao,Welcome to Netty.$_";
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String o) throws Exception {
System.out.println(++counter+":"+o);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
for(int i=0;i<10;i++){
ctx.writeAndFlush(Unpooled.copiedBuffer(ECHO_REQ.getBytes()));
}
}
}
}
定長解碼器:
//每次按照20個字符進行解碼,如果是半包消息,會緩存半包消息並等待下一個半包進行拼包
pipeline.addLast(new FixedLengthFrameDecoder(20));