netty服务端: import io.netty.bootstrap.ServerBootstrap; 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.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.timeout.IdleStateHandler; import java.util.concurrent.TimeUnit; public class NettyServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup parentGroup = new NioEventLoopGroup(); EventLoopGroup childGroup = new NioEventLoopGroup(); try { //2.创建服务端启动引导/辅助类:ServerBootstrap ServerBootstrap bootstrap = new ServerBootstrap(); //3.给引导类配置两大线程组,确定了线程模型 bootstrap.group(parentGroup, childGroup) // (非必备)打印日志 .handler(new LoggingHandler(LogLevel.INFO)) // 4.指定 IO 模型 .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); /** * 服务端添加IdleStateHandler心跳检测处理器,添加自定义处理Handler类实现userEventTriggered()方法作为超时事件的逻辑处理. * IdleStateHandler心跳检测每十五秒进行一次读检测,如果十五秒内ChannelRead()方法未被调用则触发一次userEventTrigger()方法 * 服务端为读IDLE * pipeline.AddLast(new IdleStateHandler(15, 0, 0));//第一个参数为读,第二个为写,第三个为读写全部 */ pipeline.addLast(new IdleStateHandler(15, 0, 0, TimeUnit.SECONDS)); //5.可以自定义客户端消息的业务处理逻辑 pipeline.addLast(new DemoSocketServerHandler()); } }); // ChannelFuture future = bootstrap.bind(8888).sync().addListener(new ChannelFutureListener() { // @Override // public void operationComplete(ChannelFuture channelFuture) throws Exception { // System.out.println("监听端口已经启动"); // } // }); ChannelFuture future = bootstrap.bind(8888).sync().addListener( future1 -> { if (future1.isSuccess()){ System.out.println("监听端口已经启动!"); } else { System.out.println("监听端口还未启动!"); } } ); System.out.println("服务器已启动。。。"); future.channel().closeFuture().sync(); } finally { parentGroup.shutdownGracefully(); childGroup.shutdownGracefully(); } } } netty客户端:
import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; public class NettyClient { public static void main(String[] args) throws InterruptedException { NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new DemoSocketClientHandler()); } }); ChannelFuture future = bootstrap.connect("localhost", 8888).sync(); future.channel().closeFuture().sync(); } finally { if(eventLoopGroup != null) { eventLoopGroup.shutdownGracefully(); } } } }
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import net.sf.jsqlparser.expression.DateTimeLiteralExpression; import java.io.Console; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.UUID; import java.util.concurrent.TimeUnit; public class DemoSocketServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { InetSocketAddress inetSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress(); String ip = inetSocketAddress.getAddress().getHostAddress(); int port = inetSocketAddress.getPort(); super.channelActive(ctx); System.out.println(ip+":"+port+" 上线了"); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println(msg); System.out.println("Client Address ====== " + ctx.channel().remoteAddress()); ctx.channel().writeAndFlush("from server:" + UUID.randomUUID()); ctx.fireChannelActive(); TimeUnit.MILLISECONDS.sleep(500); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent idleStateEvent = (IdleStateEvent) evt; if (idleStateEvent.state() == IdleState.READER_IDLE) { InetSocketAddress inetSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress(); String ip = inetSocketAddress.getAddress().getHostAddress(); System.out.println((ip + ":" + inetSocketAddress.getPort() + "close")); ctx.channel().close(); } } } } import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; public class DemoSocketClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println(msg); ctx.channel().writeAndFlush("from client: " + System.currentTimeMillis()); TimeUnit.MILLISECONDS.sleep(5000); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.channel().writeAndFlush("from client:begin talking"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } //超时则关闭链路 @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent idleStateEvent = (IdleStateEvent) evt; if (idleStateEvent.state() == IdleState.READER_IDLE) { InetSocketAddress inetSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress(); String ip = inetSocketAddress.getAddress().getHostAddress(); System.out.println((ip + ":" + inetSocketAddress.getPort() + "close")); ctx.channel().close(); } } } }