上一篇已经通过一个示例来了解了一下jdk的nio编程,这篇我们也通过一个简单的示例来学习一下netty的基础编程。
需求很简单,客户端发送一条信息给服务端,服务端接收信息并打印,然后回复给客户端,一次通信即结束。
首先编写一个服务端的处理handle
public class ServerExampleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client connect");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client close");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg);
ctx.channel().writeAndFlush("hello I am server");
}
}
三个方法分别对应着连接打开,连接关闭,和消息接收三个事件。
服务端代码如下:
public class NettyServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup(8);
ServerBootstrap b = new ServerBootstrap();
try {
b.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
//这两个handle为netty自带的
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
//这是实现我们自定义逻辑的handle
ch.pipeline().addLast(new ServerExampleHandler());
}
});
b.bind(8080).channel().closeFuture().sync();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
其次编写客户端的处理handle
public class ClientExampleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush("I am client");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg);
ctx.close();
}
}
客户端代码如下:
public class NettyClient {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup(1);
Bootstrap b = new Bootstrap();
try {
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
//这两个handle为netty自带的
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
//这是实现我们自定义逻辑的handle
ch.pipeline().addLast(new ClientExampleHandler());
}
});
b.connect("127.0.0.1", 8080).channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
这样一个服务端和客户端相互通信的功能就已经实现了。
其实在上述的netty编程中,我们自己写的逻辑主要就是两个handle,其他的代码都属于netty框架。可以和jdk的代码做个比较,netty的编程,明显可以让我们更专注于业务逻辑。
那么netty到底替我们做了那些事情呢?万变不离其宗,IO编程的两大步骤
1、 接收连接
2、 处理消息
netty也是一样。接下来我们就看看netty到底是怎么完成这两个步骤的。