91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行Java--Netty的入門

發布時間:2021-11-20 14:10:13 來源:億速云 閱讀:158 作者:柒染 欄目:大數據

這篇文章將為大家詳細講解有關如何進行Java--Netty的入門,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Netty簡介

Netty是一個高性能,高可擴展性的異步事件驅動的網絡應用程序框架,它極大的簡化了TCP和UDP客戶端和服務器端網絡開發。它是一個NIO框架,對Java NIO進行了良好的封裝。作為一個異步NIO框架,Netty的所有IO操作都是異步非阻塞的,通過Future-Listener機制,用戶可以方便的主動獲取或者通過通知機制獲得IO操作結果。

Netty的特性

  • 統一的API,適用于不同的協議

  • 基于靈活、可擴展的事件驅動模型

  • 高度可定制的線程模型

  • 更好的吞吐量,低延遲

  • 更省資源,盡量減少不必要的內存拷貝

  • 完整的SSL/TLS和STARTTLS的支持

  • 能在Applet與Android的限制環境運行良好

  • 不再因過快、過慢或超負載連接導致OutOfMemoryError

  • 不再有在高速網絡環境下NIO讀寫頻率不一致的問題

Netty核心內容

Netty中最核心的內容主要有以下四個方面:

  • Reactor線程模型:一種高性能的多線程程序設計思路

  • Netty中自己定義的Channel概念:增強版的通道概念

  • ChannelPipeline職責鏈設計模式:事件處理機制

  • 內存管理:增強的ByteBuf緩沖區

Netty整體結構圖

如何進行Java--Netty的入門

Netty核心組件

EventLoop:EventLoop維護了一個線程和任務隊列,支持異步提交執行任務。EventLoop自身實現了Executor接口,當調用executor方法提交任務時,則判斷是否啟動,未啟動則調用內置的executor創建新線程來觸發run方法執行,其大致流程參考Netty源碼SingleThreadEventExecutor如下:

如何進行Java--Netty的入門

EventLoopGroup:EventLoopGroup主要是管理eventLoop的生命周期,可以將其看作是一個線程池,其內部維護了一組EventLoop,每個eventLoop對應處理多個Channel,而一個Channel只能對應一個EventLoop

如何進行Java--Netty的入門

Bootstrap:BootStrap 是客戶端的引導類,主要用于客戶端連接遠程主機,有1個EventLoopGroup。Bootstrap 在調用 bind()(連接UDP)和 connect()(連接TCP)方法時,會新創建一個單獨的、沒有父 Channel 的 Channel 來實現所有的網絡交換。

ServerBootstrap:ServerBootstrap 是服務端的引導類,主要用戶服務端綁定本地端口,有2個EventLoopGroup。ServerBootstarp 在調用 bind() 方法時會創建一個 ServerChannel 來接受來自客戶端的連接,并且該 ServerChannel 管理了多個子 Channel 用于同客戶端之間的通信。

Channel:Netty中的Channel是一個抽象的概念,可以理解為對Java NIO Channel的增強和擴展,增加了許多新的屬性和方法,如bing方法等。

ChannelFuture:ChannelFuture能夠注冊一個或者多個ChannelFutureListener 實例,當操作完成時,不管成功還是失敗,均會被通知。ChannelFuture存儲了之后執行的操作的結果并且無法預測操作何時被執行,提交至Channel的操作按照被喚醒的順序被執行。

ChannelHandler:ChannelHandler用來處理業務邏輯,分別有入站和出站的實現。

ChannelPipeline:ChannelPipeline 提供了 ChannelHandler鏈的容器,并定義了用于在該鏈上傳播入站和出站事件流的API。

Netty線程模型

Netty的線程模型是基于Reactor模式的線程實現。關于Reactor模式可以參考Reactor模式 ,Netty中依據用戶的配置可以支持單線程的Reactor模型,多線程的Reactor模型以及主從多Reactor的模型。在Netty中其大致流程如下如下:

如何進行Java--Netty的入門

Netty入門代碼示例

服務端代碼示例:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.nio.charset.Charset;
public class EchoServer {
 public static void main(String[] args) {

   // accept線程組,用來接受連接
   EventLoopGroup bossGroup = new NioEventLoopGroup(1);

   // I/O線程組, 用于處理業務邏輯
   EventLoopGroup workerGroup = new NioEventLoopGroup(1);

   try {
     // 服務端啟動引導
     ServerBootstrap b = new ServerBootstrap();

     b.group(bossGroup, workerGroup) // 綁定兩個線程組
         .channel(NioServerSocketChannel.class) // 指定通道類型
         .option(ChannelOption.SO_BACKLOG, 100) // 設置TCP連接的緩沖區
         .handler(new LoggingHandler(LogLevel.INFO)) // 設置日志級別
         .childHandler(
             new ChannelInitializer<SocketChannel>() {
               @Override
               protected void initChannel(SocketChannel socketChannel) throws Exception {
                 ChannelPipeline pipeline = socketChannel.pipeline(); // 獲取處理器鏈
                 pipeline.addLast(new EchoServerHandler()); // 添加新的件處理器

               }

             });

     // 通過bind啟動服務
     ChannelFuture f = b.bind(8080).sync();

     // 阻塞主線程,知道網絡服務被關閉
     f.channel().closeFuture().sync();

   } catch (Exception e) {
     e.printStackTrace();
   } finally {
     workerGroup.shutdownGracefully();
     bossGroup.shutdownGracefully();
   }
 }

}

class EchoServerHandler extends ChannelInboundHandlerAdapter {

 // 每當從客戶端收到新的數據時,這個方法會在收到消息時被調用
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
   System.out.println("收到數據:" + ((ByteBuf) msg).toString(Charset.defaultCharset()));
   ctx.write(Unpooled.wrappedBuffer("Server message".getBytes()));
   ctx.fireChannelRead(msg);
 }
 // 數據讀取完后被調用  @Override
 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
   ctx.flush();
 }
 // 當Netty由于IO錯誤或者處理器在處理事件時拋出的異常時被調用  @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
   cause.printStackTrace();
   ctx.close();
 }
}

客戶端代碼示例:

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.nio.charset.Charset;
public class EchoClient {
 public static void main(String[] args) {
   EventLoopGroup group = new NioEventLoopGroup();
   try {
     Bootstrap b = new Bootstrap();
     b.group(group)
         .channel(NioSocketChannel.class)
         .option(ChannelOption.TCP_NODELAY, true)
         .handler(
             new ChannelInitializer<SocketChannel>() {
               @Override
               public void initChannel(SocketChannel ch) throws Exception {
                 ChannelPipeline p = ch.pipeline();
                 p.addLast(new EchoClientHandler());
               }
             });
     ChannelFuture f = b.connect("127.0.0.1", 8080).sync();
     f.channel().closeFuture().sync();
   } catch (Exception e) {
     e.printStackTrace();
   } finally {
     group.shutdownGracefully();
   }
 }

}

class EchoClientHandler extends ChannelInboundHandlerAdapter {
 private final ByteBuf firstMessage;
 public EchoClientHandler() {
   firstMessage = Unpooled.buffer(256);
   for (int i = 0; i < firstMessage.capacity(); i++) {
     firstMessage.writeByte((byte) i);
   }
 }
 @Override
 public void channelActive(ChannelHandlerContext ctx) {
   ctx.writeAndFlush(firstMessage);
 }
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) {
   System.out.println("收到數據:" + ((ByteBuf) msg).toString(Charset.defaultCharset()));
   ctx.write(Unpooled.wrappedBuffer("Client message".getBytes()));
 }
 @Override
 public void channelReadComplete(ChannelHandlerContext ctx) {
   ctx.flush();
 }
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
   cause.printStackTrace();
   ctx.close();
 }
}

關于如何進行Java--Netty的入門就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

馆陶县| 丰镇市| 山丹县| 绵竹市| 专栏| 泗阳县| 扶沟县| 大同市| 社会| 冷水江市| 长子县| 攀枝花市| 桂东县| 建瓯市| 郎溪县| 开阳县| 秦皇岛市| 上高县| 湄潭县| 葵青区| 二连浩特市| 巩留县| 衢州市| 长沙县| 雅安市| 左贡县| 湟源县| 勐海县| 乐山市| 丹巴县| 云阳县| 衡阳县| 泰宁县| 金山区| 昌黎县| 图木舒克市| 玉溪市| 新建县| 石河子市| 宣恩县| 循化|