1、Netty簡介
Netty是由JBOSS提供的一個java開源網絡通訊框架。Netty是基於Java NIO client-server的網絡應用框架,使用Netty可以快速開發網絡應用,例如服務器和客戶端協議。Netty提供了一種新的方式來開發網絡應用程序,這種新的方式使它很容易使用和具有很強的擴展性。Netty的內部實現是很複雜的,但是Netty提供了簡單易用的API從網絡處理代碼中解耦業務邏輯。Netty是完全基於NIO實現的,所以整個Netty都是異步的。
netty的優點
它的健壯性、功能、性能、可定製性和可擴展性在同類框架都是首屈一指的。它已經得到成百上千的商業/商用項目驗證,如Hadoop的RPC框架Avro、RocketMQ以及主流的分佈式通信框架Dubbox等等。
2、Hello World 入門
1、Netty通信的步驟:
①創建兩個NIO線程組,一個專門用於網絡事件處理(接受客戶端的連接),另一個則進行網絡通信的讀寫。
②創建一個ServerBootstrap對象,配置Netty的一系列參數,例如接受傳出數據的緩存大小等。
③創建一個用於實際處理數據的類ChannelInitializer,進行初始化的準備工作,比如設置接受傳出數據的字符集、格式以及實際處理數據的接口。
④綁定端口,執行同步阻塞方法等待服務器端啓動即可。
2、入門實例(以helloworld爲例)
2.1下載相應的jar包
可以去http://netty.io/上下載所需的Netty包
我所用的jar包爲 https://pan.baidu.com/s/1tm2EgYtDpTS5dejVnHhvPw 密碼:vc8b
2.2 代碼實現
服務器端
package com.xyq.netty.hello;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class Server {
public static void main(String[] args) throws Exception {
//1 創建兩個線程組
EventLoopGroup pGroup = new NioEventLoopGroup();//一個是用於處理服務器端接收客戶端連接的
EventLoopGroup cGroup = new NioEventLoopGroup();//一個是進行網絡通信的(網絡讀寫的)
//2 創建輔助工具類,用於服務器通道的一系列配置
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(pGroup, cGroup)//綁定倆個線程組
.channel(NioServerSocketChannel.class)//指定NIO的模式
.option(ChannelOption.SO_BACKLOG, 1024)//設置tcp緩衝區
.option(ChannelOption.SO_SNDBUF, 32*1024)//設置發送緩衝大小
.option(ChannelOption.SO_RCVBUF, 32*1024)//設置接收緩衝大小
.option(ChannelOption.SO_KEEPALIVE, true)//保持連接
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//3 在這裏配置具體數據接收方法的處理
ch.pipeline().addLast(new ServerHandler());
}
});
//4 進行綁定
ChannelFuture cf = bootstrap.bind(8765).sync();
System.out.println("server start ...");
//5 等待關閉
cf.channel().closeFuture().sync();
pGroup.shutdownGracefully();
cGroup.shutdownGracefully();
}
}
服務器管理類
package com.xyq.netty.hello;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
public class ServerHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//讀取客戶端發過來的信息
ByteBuf buf = (ByteBuf) msg;
byte[] bs = new byte[buf.readableBytes()];
buf.readBytes(bs);
String body = new String(bs, "utf-8");
System.out.println("server 接收到的數據爲 " + body);
//給客戶端迴應信息
String result = "server 已經接收到信息, 信息爲 " + body;
ctx.writeAndFlush(Unpooled.copiedBuffer(result.getBytes()));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
客戶端
package com.xyq.netty.hello;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class Client {
public static void main(String[] args)throws Exception {
//1 創建線程組
EventLoopGroup group = new NioEventLoopGroup();
//2 創建輔助工具類,用於服務器通道的一系列配置
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)//綁定線程組
.channel(NioSocketChannel.class)//指定NIO的模式
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//3 在這裏配置具體數據接收方法的處理
ch.pipeline().addLast(new ClientHandler());
}
});
//4 進行連接
ChannelFuture future = bootstrap.connect("127.0.0.1", 8765).sync();
System.out.println("Client connect....");
//5發送信息
future.channel().writeAndFlush(Unpooled.copiedBuffer("你好".getBytes()));
Thread.sleep(1000);
future.channel().writeAndFlush(Unpooled.copiedBuffer("世界".getBytes()));
Thread.sleep(1000);
future.channel().writeAndFlush(Unpooled.copiedBuffer("!".getBytes()));
//6等待關閉
future.channel().closeFuture().sync();
group.shutdownGracefully();
}
}
客戶端管理類
package com.xyq.netty.hello;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
public class ClientHandler extends ChannelHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//讀取服務器端發過來的信息
ByteBuf buf = (ByteBuf) msg;
byte[] bs = new byte[buf.readableBytes()];
buf.readBytes(bs);
String body = new String(bs, "utf-8");
System.out.println("客戶端接收到服務端的響應消息 " + body);
} finally{
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}