netty入門程式
阿新 • • 發佈:2018-11-01
匯入相應的包
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.28.Final</version>
</dependency>
客戶端
/** * 客戶端 */ public class Client { private String host; private int port; public Client(String host, int port) { this.host = host; this.port = port; } //啟動客戶端連線 public void start() { //執行緒組 EventLoopGroup group = new NioEventLoopGroup(); try { //客戶端啟動類 Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group)//加入執行緒組 .channel(NioSocketChannel.class) .remoteAddress(new InetSocketAddress(host, port))//設定連線引數 .handler(new ClientHandler());//設定客戶端連線的處理器 //阻塞直到連線完成 ChannelFuture connect = bootstrap.connect().sync(); //阻塞直到連線成功關閉 connect.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { try { group.shutdownGracefully().sync(); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Client client = new Client("127.0.0.1", 9999); client.start(); } }
客戶端處理器
public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> { //連線成功後,接收服務端響應的資料 protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { System.out.println("接收到服務端響應的資料......" + byteBuf.toString(CharsetUtil.UTF_8)); } //客戶端連線成功後呼叫的 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("客戶端成功連線,並向服務端傳送資料......"); ctx.writeAndFlush(Unpooled.copiedBuffer("Hello,Netty!", CharsetUtil.UTF_8)); } //連線失敗後呼叫 @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("客戶端連線失敗"); cause.printStackTrace(); //關閉資源 ctx.close(); } }
服務端
/** * 服務端 */ public class Server { private int port; public Server(int port) { this.port = port; } public void start() { EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap sb = new ServerBootstrap(); //服務端共用一個Handler final ServerHandler serverHandler = new ServerHandler(); sb.group(group) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() { /*接收到連線請求,新啟一個socket通訊,也就是channel,每個channel * 有自己的事件的handler*/ protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(serverHandler); } }); ChannelFuture sync = sb.bind().sync(); sync.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); }finally { try { group.shutdownGracefully().sync(); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Server(9999).start(); } }
服務端處理器
/*指明我這個handler可以在多個channel之間共享,意味這個實現必須執行緒安全的。*/
@ChannelHandler.Sharable
public class ServerHandler extends ChannelInboundHandlerAdapter {
//服務端讀取完客戶端的所有資料後
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)/*flush掉所有的資料*/
.addListener(ChannelFutureListener.CLOSE);/*當flush完成後,關閉連線*/
}
//服務端讀取客戶端的資料
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf msg1 = (ByteBuf) msg;
System.out.println("服務端接收到客戶端的資料......." + msg1.toString(CharsetUtil.UTF_8));
ctx.write(msg1);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
執行結果:
服務端:
客戶端: