什麼是Netty?Netty是一個框架。或者說是一個工具集。封裝了網絡編程方面java的API。java
Channel:java nio的基本構造,表明一個實體(硬件設備、文件、網路套接字等)的開放鏈接。用做傳入(入站)或者傳出(出站)數據linux
回調:封裝操做完成後須要作的事情的方法編程
Future: 提供異步操做的結果訪問bootstrap
事件和ChannelHandler:程序運行過程當中發生的事情抽象(事件)交給ChannerHandler來處理,channelHandler相似於爲了響應特定事件而執行的回調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();
}
}
}
複製代碼
serverHandlerbash
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