什么是Netty?Netty是一个框架。或者说是一个工具集。封装了网络编程方面java的API。
server
public class EchoServer {
private final int port;
public EchoServer(int port) {
this.port = port;
}
public static void main(String[]args)throws Exception{
new EchoServer(8888).start();
}
public void start() throws Exception{
final EchoServerHandler handler = new EchoServerHandler();
EventLoopGroup group = new NioEventLoopGroup();
try{
ServerBootstrap b = new ServerBootstrap();
b.group(group).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(handler);
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
}finally {
group.shutdownGracefully().sync();
}
}
}
复制代码
serverHandler
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.printf("Server get:"+in.toString(CharsetUtil.UTF_8));
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//将目前暂存于ChannelOutboundBuffer中的消息在下一次flush或者writeAndFlush的时候冲刷到远程并关闭这个channel
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
复制代码
client
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();
b.group(group).channel(NioSocketChannel.class)//指定NIO的传输方式
.remoteAddress(new InetSocketAddress(host,port))//指定远程地址
.handler(new ChannelInitializer<SocketChannel>() {//向channel的pipeline添加handler
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoClientHandler());//channelHander交给pipeline
}
});
ChannelFuture f = b.connect().sync();//连接到远程节点,阻塞直到连接完成
System.out.println("wait");
f.channel().closeFuture().sync();//阻塞直到连接关闭
System.out.println("over");
}finally {
System.out.println("shutdown");
group.shutdownGracefully().sync();//关闭线程池并且释放资源
}
}
public static void main(String[]args) throws Exception{
new EchoClient("localhost",8888).start();
}
}
复制代码
clientHandler
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello world",CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("Client get:"+msg.toString(CharsetUtil.UTF_8));
}
}
复制代码
它们是netty对网络的抽象组件。
Channel本身用来提供基本的IO操作(bind/connect/read/write),连接建立之后通过EventLoop来处理所发生的事情,它们之间的对应关系是1个channel只能有1个EventLoop,但是一个EventLoop对应多个Channel。EventLoop整个生命周期中只和一个Thread绑定,对应来讲一个Channel中的所有IO操作也都是在一个线程中执行的。执行的结果则是通过ChannelFuture来获取
pipeline用来管理数据流,handler(client和server)是用来处理逻辑。
ChannelHandler接收事件,对事件进行逻辑处理,并将数据传给链(多个按照一定顺序定义的ChannelHandler)中的下一个ChannelHandler。ChannelPipLine就是ChannelHandler的编排顺序(二者建立关系的时机是ChannelInitializer执行initChannel的时候ChannelPipline组装自定义的channelHandler)。出于方便ChannelHandler会提供一些适配实现类让用户专注于处理自己的业务逻辑。
有两种类型,客户端(简称BootStrap)和服务端(简称ServerBootStrap)。区别有两点
Netty In Action