Netty学习(二)完整hello word 详细注解

1netty结构

419那个是以前网上看的,注解太少,不适合新手,后来又重新学习了下

论总结的重要性。。。

client发信息给Server,server再返回给client

2实现

 Netty 服务器都需要下面这些:

一个服务器 handler:这个组件实现了服务器的业务逻辑,决定了连接创建后和接收到信息后该如何处理

上图中的ServerHandler,Echo Server 将会将接受到的数据的拷贝发送给客户端。

我们需要实现 ChannelInboundHandler接口,用来定义处理入站事件的方法。由于我们的应用很简单,只需要继承ChannelInboundHandlerAdapter 就行了。这个类 提供了默认 ChannelInboundHandler 的实现,所以只需要覆盖下面的方法:channelRead() - 每个信息入站都会调用

channelReadComplete() - 通知处理器最后的 channelread() 是当前批处理中的最后一条消息时调用

exceptionCaught()- 读操作时捕获到异常时调用

@Sharable
// 11. @Sharable 标识这类的实例之间可以在 channel 里面共享
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) {
		ByteBuf in = (ByteBuf) msg;
		System.out
				.println("Server received: " + in.toString(CharsetUtil.UTF_8)); // 2.日志消息输出到控制台
		ctx.write(in); // 3将所接收的消息返回给发送者。注意,这还没有冲刷数据
	}
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)// 4.冲刷所有待审消息到远程节点。关闭通道后,操作完成
				.addListener(ChannelFutureListener.CLOSE);
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		cause.printStackTrace(); // 5打印异常堆栈跟踪
		ctx.close(); // 6.关闭通道
	}
}

是不是很详细,哈哈!!!

Bootstrapping: 这个是配置服务器的启动代码。最少需要设置服务器绑定的端口,用来监听连接请求

Echoserver.java就是了

public class EchoServer {
	
    private final int port;//1端口号
    
	public EchoServer(int port) {
		this.port = port;
	}
	public static void main(String[] args) throws Exception {
		new EchoServer(9090).start(); // 2呼叫服务器的 start()方法,就是你刚刚写的哪个类
	}
	public void start() throws Exception {
		NioEventLoopGroup group = new NioEventLoopGroup(); // 3创建 EventLoopGroup
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(group) // 4创建 ServerBootstrap
					.channel(NioServerSocketChannel.class) // 5指定使用 NIO 的传输 Channel
					.localAddress(new InetSocketAddress(port)) // 6设置 socket 地址使用所选的端口
					.childHandler(new ChannelInitializer<SocketChannel>() { // 7.添加 EchoServerHandler 到 Channel 的 ChannelPipeline
								@Override
								public void initChannel(SocketChannel ch)
										throws Exception {
									ch.pipeline().addLast(
											new EchoServerHandler());
								}
							});
			ChannelFuture f = b.bind().sync(); // 8绑定的服务器;sync 等待服务器关闭
			System.out.println(EchoServer.class.getName()
					+ " started and listen on " + f.channel().localAddress());
			f.channel().closeFuture().sync(); // 9关闭 channel 和 块,直到它被关闭
		} finally {
			group.shutdownGracefully().sync(); // 10关机的 EventLoopGroup,释放所有资源
		}
	}
	}

port是你自己写的端口号,一会和client写的对应就行了

服务器的主代码组件是

EchoServerHandler 实现了的业务逻辑在 main()方法,

引导了服务器

执行后者所需的步骤是:

创建 ServerBootstrap 实例来引导服务器并随后绑定

创建并分配一个 NioEventLoopGroup 实例来处理事件的处理,如接受新的连接和读/写数据。

指定本地 InetSocketAddress 给服务器绑定

通过 EchoServerHandler 实例给每一个新的 Channel 初始化

最后调用 ServerBootstrap.bind() 绑定服务器

好了,Server就写完了

写一个 echo 客户端客

户端要做的是:

连接服务器

发送信息

发送的每个信息,等待和接收从服务器返回的同样的信息

关闭连接

用 ChannelHandler 实现客户端逻辑跟写服务器一样,我们提供 ChannelInboundHandler 来处理数据。下面例子,我们用SimpleChannelInboundHandler 来处理所有的任务,需要覆盖三个方法:

channelActive() - 服务器的连接被建立后调用

channelRead0() - 数据后从服务器接收到调用

exceptionCaught() - 捕获一个异常时调用

@Sharable //1
public class EchoClientHandler extends
SimpleChannelInboundHandler<ByteBuf> {
	
@Override
   public void channelActive(ChannelHandlerContext ctx) {
	
            ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks! hello Netty", //2
		
            CharsetUtil.UTF_8));
                }
@Override
public void channelRead0(ChannelHandlerContext ctx,
ByteBuf in) {
	
System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8)); //3
}


@Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) { //4
cause.printStackTrace();
ctx.close();
}
}

1. @Sharable 标记这个类的实例可以在 channel 里共享2.当被通知该 channel 是活动的时候就发送信息3.记录接收到的消息写一个 echo 客户端本文档使用 -4.记录日志错误并关闭 channel

 

引导客户端客户端引导需要 host 、port 两个参数连接服务器

public class EchoClient {
	
          private final String host;

          private final int port;

	public EchoClient(String host, int port) {
		this.host = host;
		this.port = port;
	}
	public void start() throws Exception {
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			Bootstrap b = new Bootstrap(); // 1
			b.group(group) // 2
					.channel(NioSocketChannel.class) // 3
					.remoteAddress(new InetSocketAddress(host, port)) // 4
					.handler(new ChannelInitializer<SocketChannel>() { // 5
								@Override
								public void initChannel(SocketChannel ch)
										throws Exception {
									ch.pipeline().addLast(
											new EchoClientHandler());
								}
							});
			ChannelFuture f = b.connect().sync(); // 6
			f.channel().closeFuture().sync(); // 7
		} finally {
			group.shutdownGracefully().sync(); // 8
		}
	}

	public static void main(String[] args) throws Exception {
		new EchoClient("192.168.51.190", 9090).start();
	}
}

1.创建 Bootstrap2.指定 EventLoopGroup 来处理客户端事件。由于我们使用 NIO 传输,所以用到了NioEventLoopGroup 的实现3.使用的 channel 类型是一个用于 NIO 传输4.设置服务器的 InetSocketAddress5.当建立一个连接和一个新的通道时,创建添加到 EchoClientHandler 实例 到 channel pipeline6.连接到远程;等待连接完成7.阻塞直到 Channel 关闭8.调用 shutdownGracefully() 来关闭线程池和释放所有资源

一个 Bootstrap 被创建来初始化客户端一个 NioEventLoopGroup 实例被分配给处理该事件的处理,这包括创建新的连接和处理入站和出站写一个 echo 客户端本文档使用   -数据一个 InetSocketAddress 为连接到服务器而创建一个 EchoClientHandler 将被安装在 pipeline 当连接完成时之后 Bootstrap.connect()被调用连接到远程的 - 本例就是 echo(回声)服务器

运行两个mian函数,就能看到结果了

看不懂?没事,还有netty

netty学习四,对上面用到的组件进行了讲解

猜你喜欢

转载自blog.csdn.net/zzqtty/article/details/81066411