Netty学习笔记四:Echo服务和Netty项目的搭建
Posted java开发架构师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty学习笔记四:Echo服务和Netty项目的搭建相关的知识,希望对你有一定的参考价值。
1. Netty学习笔记四:Echo服务和Netty项目的搭建
1.1. 什么是Echo服务1.2. Echo服务端程序编写1.3. Echo客户端编写1.4. Echo服务中的名词解析
1.1. 什么是Echo服务
Echo服务就是一个应答服务,客户端发送什么数据,服务端就响应对应的数据,是一个非常有的用于调试和检测的服务。
1.2. Echo服务端程序编写
EchoServer服务端
一、绑定端口
二、创建主从线程组
三、启动线程组,指定通道 类型,处理传过来的数据内容。
四、监听端口,关闭端口
五、释放线程。
1public class EchoServer {
2 private int port;
3 public EchoServer(int port){
4 this.port=port;
5 }
6 public void run() throws InterruptedException {
7 //创建主从线程组。
8 EventLoopGroup bossGroup=new NioEventLoopGroup();
9 EventLoopGroup workGroup=new NioEventLoopGroup();
10 try{
11 //配置线程组启动类,Netty框架已经封装好了。创建一个启动对象
12 ServerBootstrap serverBootstrap=new ServerBootstrap();
13 //将需要启动的线程组包裹进去。//可以通过链式的调用方法,指定Channel类型。
14 serverBootstrap.group(bossGroup,workGroup)
15 .channel(NioserverSocketChannel.class)//每启动一个线程组就要指定一个通道类型。
16 .childHandler(new ChannelInitializer<SocketChannel>() {//当建立通道连接时需要进行处理。
17 protected void initChannel(SocketChannel ch) throws Exception {
18 ch.pipeline().addLast(new EchoServerHandler());
19 }
20 });
21 System.out.println("Echo 服务器启动ing");
22 //绑定端口,需要同步等待。
23 ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
24 //等待服务端,监听端口关闭
25 channelFuture.channel().closeFuture().sync();
26 }finally {
27 //优雅退出,释放线程池。
28 workGroup.shutdownGracefully();
29 bossGroup.shutdownGracefully();
30 }
31 }
32 public static void main(String[] args) throws InterruptedException {
33 int port =7070;
34 if(args.length>0){
35 port=Integer.parseInt(args[0]);
36 }
37 new EchoServer(port).run();
38 }
39}
处理类
1public class EchoServerHandler extends ChannelInboundHandlerAdapter {
2 @Override
3 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
4 //ByteBuf是Netty封装的ByteBuffer。
5 ByteBuf data= (ByteBuf)msg;
6 System.out.println("服务端收到数据:"+data.toString(CharsetUtil.UTF_8));
7 //回写过去,并刷新管道。
8 ctx.writeAndFlush(data);
9 }
10 @Override
11 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
12 System.out.println("EchoServerHandle channelReadComplete");
13 }
14 @Override
15 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
16 cause.printStackTrace();
17 ctx.close();
18 }
19}
1.3. Echo客户端编写
EchoClient主类
1public class EchoClient {
2 private int port;
3 private String host;
4 public EchoClient(String host,int port){
5 this.port=port;
6 this.host=host;
7 }
8 public void start() throws InterruptedException {
9 EventLoopGroup group=new NioEventLoopGroup();
10 try{
11 Bootstrap bootstrap =new Bootstrap();
12 bootstrap.group(group)
13 .channel(NioSocketChannel.class)
14 .remoteAddress(new InetSocketAddress(host,port))
15 .handler(new ChannelInitializer<SocketChannel>() {
16 protected void initChannel(SocketChannel ch) throws Exception {
17 ch.pipeline().addLast(new EchoClientHandler());
18 }
19 });
20 //连接到服务器,connect是异步连接,在调用同步等待sync,等待连接成功。
21 ChannelFuture channelFulture = bootstrap.connect().sync();
22 //阻塞住,直到客户端通道关闭。
23 channelFulture.channel().closeFuture().sync();
24 }finally {
25 //优雅退出释放NIO线程。
26 group.shutdownGracefully();
27 }
28 }
29 public static void main(String[] args) throws InterruptedException {
30 new EchoClient("127.0.0.1",7070).start();
31 }
32}
EchoClientHandler处理类
一、与服务端处理类继承的不一样,但是实质是一样的。
二、打印顺序是,先走Active()方法,先激活,表示和服务端建立了通道。
三、读取服务端的数据,
四、读取完成。进入channelReadComplete()方法。
1public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
2 protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
3 System.out.println("Client received...."+msg.toString(CharsetUtil.UTF_8));
4 }
5 @Override
6 public void channelActive(ChannelHandlerContext ctx) throws Exception {
7 System.out.println("Active");
8 //创建一个缓存。使用Unpooled工具类。
9 ctx.writeAndFlush(Unpooled.copiedBuffer("世界你好,我是zkf",CharsetUtil.UTF_8));
10 }
11 @Override
12 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
13 System.out.println("EchoClient channelReadComplete");
14 }
15
16 @Override
17 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
18 cause.printStackTrace();
19 ctx.close();
20 }
21}
1.4. Echo服务中的名词解析
EventLoop和EventLoopGroup
线程和线程组,前者可以理解为线程,后者可以理解为线程组。
BootStrap
启动引导类,用于配置线程组,启动的时候,同时启动线程组,以及开启通道,初始化通道。和一些处理。
channel
channel是客户端和服务端建立的一个连接,是一个Socket连接,具有生命周期,建立成功,读取数据,读取完成,出现异常等。
channelHandler和channelPipeline
channelhandler是做处理的,对接收的数据进行处理到要直接或间接继承channelHandler。
channelPipeline就好比一个处理工厂,可以添加很多handler处理类,当进入channelHandler后都要经过pipeline添加的handler进行处理。
个人理解:
就像一个滤水系统,BootStrap是滤水系统的开关,它将滤水系统与水资源连接起来,然后产生一个通道Channel,每个通道里面有一个净水处理系统,即:ChannelHandler,每个净水系统里面有很多处理管道,即:Handler,处理管道是活的,可以添加,卸掉。这些动作都要pipeline这个工具类来实现。
以上是关于Netty学习笔记四:Echo服务和Netty项目的搭建的主要内容,如果未能解决你的问题,请参考以下文章