Netty基于NIO的网络编程框架,是一个封装了NIO复杂的底层细节,可以拿来开发高并发的服务端和客户端的程序,简单直白你可以理解它就是一个好用的处理socket的东西就行啦。
首先,创建maven工程添加Netty依赖,新建两个包,一个是客户端,一个服务端,先来看看服务端代码,这个是服务器类,主要的逻辑都在这里实现。
public class Server { public static void main(String[] args) throws Exception { //1.创建两个线程组 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ //2.服务端启动类 ServerBootstrap serverBootstrap = new ServerBootstrap(); //3.定义好组,nio,以及初始化类 serverBootstrap.group(bossGroup,workerGroup)//加载线程组
.channel(NioServerSocketChannel.class)//选择NIO的通道
.childHandler(new TestServerInitializer());//自定义初始化类 System.out.println("服务器启动...."); //4.绑定端口 ChannelFuture channelFuture = serverBootstrap.bind(7889).sync(); //5.关闭任务 channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
自定义的初始化类,里面主要是设置处理器到通道以及设置异常处理等初始化工作,可以重写的方法很多,这里就简单重写两个基本的方法
public class TestServerInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel socketChannel) throws Exception { //获取管道,添加处理器 ChannelPipeline channelPipeline = socketChannel.pipeline(); //添加处理器 channelPipeline.addLast("decoder", new StringDecoder());//字符解码 channelPipeline.addLast("encoder", new StringEncoder());//字符编码 channelPipeline.addLast("MyClientHandler",new MyHandler());//自定义的Handler,里面处理具体的业务 } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { super.exceptionCaught(ctx, cause); } }
自定义的Hander,里面是自己要处理的具体业务,这次就是简单的传输字符串。
public class MyHandler extends SimpleChannelInboundHandler<String>{
//处理通道信息的方法 @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, String str) throws Exception { System.out.println("准备接收客户端的数据..."); //打印收到的客户端的信息 System.out.println(str); //发送信息给客户端 channelHandlerContext.writeAndFlush("this is server"); System.out.println("------发送给客户端成功"); } /* * 建立连接时,返回消息 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("连接的客户端地址:" + ctx.channel().remoteAddress()); System.out.println(InetAddress.getLocalHost().getHostName()); ctx.writeAndFlush("客户端"+ InetAddress.getLocalHost().getHostName() + "成功与服务端建立连接! \n"); super.channelActive(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
客户端,首先也是客户端类的代码,其实调用的API不太一样之外差不多,具体看下面的代码:
public class client { public static void main(String[] args) throws Exception { System.out.println("客户端启动...."); //1.创建线程组 EventLoopGroup clientGroup = new NioEventLoopGroup(); //2.客户端启动类 Bootstrap bootstrap = new Bootstrap(); //3.定义好组,nio,以及初始化类 bootstrap.group(clientGroup) .channel(NioSocketChannel.class) .handler(new TestClientInitializer()); //4.创建好通道 Channel channel = bootstrap.connect("127.0.0.1",7889).sync().channel(); channel.writeAndFlush("this is client-----"); System.out.println("----------------"); } }
然后和服务端一样,自定义的初始化类搞起来
public class TestClientInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//获取管道,添加处理器
ChannelPipeline channelPipeline = socketChannel.pipeline();
//添加处理器
channelPipeline.addLast("decoder", new StringDecoder());
channelPipeline.addLast("encoder", new StringEncoder());
channelPipeline.addLast("MyClientHandler",new MyClientHandler());
}
}
最后就是搞客户端的逻辑的Handler
public class MyClientHandler extends SimpleChannelInboundHandler<String>{ @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, String str) throws Exception { System.out.println(str); ByteBuf byteBuf = Unpooled.copiedBuffer("hello server ", CharsetUtil.UTF_8); //获取并设置响应体,版本信息,状态,响应内容等 //FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,byteBuf); //设置响应头信息 //response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain"); //channelHandlerContext.writeAndFlush("ssssssssssssssssssss"); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("正在连接... "); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("连接关闭! "); super.channelInactive(ctx); } }
原文:https://www.cnblogs.com/JimmyFanHome/p/9992482.html