<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.6.Final</version>
</dependency>
public static void main(String[] args) {
new Thread(()->{
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,128)
.childOption(ChannelOption.SO_KEEPALIVE,true)
.childHandler(new ServerChannelInitializer());
ChannelFuture channelFuture = bootstrap.bind(8099).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
}finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}).start();
}
public static class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new IdleStateHandler(10,10,10, TimeUnit.SECONDS));
pipeline.addLast(new ReadHandler());
pipeline.addLast(new WriteHandler());
pipeline.addLast(new ServerSendHandler());
}
}
public static class ReadHandler extends SimpleChannelInboundHandler<ByteBuf>{
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("from : "+ctx.channel().remoteAddress()+" data : "+ ByteBufUtil.hexDump(msg));
msg.retain();
ctx.fireChannelRead(msg);
}
}
public static class WriteHandler extends ChannelOutboundHandlerAdapter{
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (msg instanceof ByteBuf){
ByteBuf buf = (ByteBuf)msg;
System.out.println("to : "+ctx.channel().remoteAddress()+" data : "+ByteBufUtil.hexDump(buf));
super.write(ctx, msg, promise);
}
}
}
public static class ServerSendHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
private static AtomicInteger atomicInteger = new AtomicInteger(1);
//这里简单模拟消息发送
int a = msg.readInt();
long b = msg.readLong();
System.out.println("server ---- a:"+a +" b:"+b);
ByteBuf buffer = Unpooled.buffer();
buffer.writeInt(atomicInteger.getAndIncrement());
buffer.writeLong(170);
ctx.writeAndFlush(buffer);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
System.out.println("server disconnect "+ctx.channel().remoteAddress());
ctx.channel().disconnect();
ctx.fireChannelInactive();
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
IdleState state = ((IdleStateEvent) evt).state();
if (state == IdleState.READER_IDLE) {
// 读空闲超时,断开连接
System.out.println("Channel read timeout, remote address:" + ctx.channel().remoteAddress().toString());
ctx.close();
} else if (state == IdleState.WRITER_IDLE) {
ByteBuf buffer = Unpooled.buffer();
buffer.writeInt(101);
buffer.writeLong(171);
ctx.writeAndFlush(buffer);
System.out.println("Channel write timeout, remote address:" + ctx.channel().remoteAddress().toString());
}
}
super.userEventTriggered(ctx, evt);
}
}
public static void main(String[] args) {
new Thread(()->{
client(new NioEventLoopGroup());
}).start();
}
public static void client(NioEventLoopGroup group){
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE,true)
.handler(new ClientChannelInitializer());
try {
bootstrap.connect("127.0.0.1",8099).addListener(new ClientChannelListener()).sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class ClientChannelInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new IdleStateHandler(10,10,10, TimeUnit.SECONDS));
pipeline.addLast(new ReadHandler());
pipeline.addLast(new WriteHandler());
pipeline.addLast(new ClientActHandler());
}
}
public static class ClientActHandler extends SimpleChannelInboundHandler<ByteBuf>{
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ByteBuf buffer = Unpooled.buffer();
buffer.writeInt(99);
buffer.writeLong(180);
ctx.writeAndFlush(buffer);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
int a = msg.readInt();
long b = msg.readLong();
System.out.println("client : "+a+" "+b);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
System.out.println("重新建立新的连接。。。。。");
client(new NioEventLoopGroup());
}
}
public static class ClientChannelListener implements ChannelFutureListener{
@Override
public void operationComplete(ChannelFuture future) throws Exception {
boolean success = future.isSuccess();
if (success){
System.out.println("connect success ");
}else {
System.out.println("connect error");
}
}
}
可以看到因为读超时服务端断开连接,然后客户端又重新连接