netty基礎入門(channel理解)
備註:本文的分析基於netty 4.0.9final版本,僅對Nio進行分析,因為本人對Socket程式設計比較感興趣。
1、channel總體機構圖
nio channel的總體結構圖如下:
2、關鍵類和介面分析
2.1 基於NioServerSocketChannel進行分析
1)Channel
Channel是頂層介面,繼承了AttributeMap, ChannelOutboundInvoker, ChannelPropertyAccess, Comparable<Channel>,它作為一個具體IO能力的元件提供給開發者,包括read, write, connect, and bind等操作。另外還提供了Channel配置的功能,以及獲取Channel所在的eventloop的功能。
2)AbstractChannel
AbstractChannel實現Channel介面,關鍵程式碼如下:
- privatefinal Channel parent;
- privatefinallong hashCode = ThreadLocalRandom.current().nextLong();
- privatefinal Unsafe unsafe;
- privatefinal DefaultChannelPipeline pipeline;
-
privatefinal ChannelFuture succeededFuture =
- privatefinal VoidChannelPromise voidPromise = new VoidChannelPromise(this, true);
- privatefinal VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
- privatefinal CloseFuture closeFuture = new CloseFuture(this);
-
privatevolatile
- privatevolatile SocketAddress remoteAddress;
- privatevolatile EventLoop eventLoop;
- privatevolatileboolean registered;
- /** Cache for the string representation of this channel */
- privateboolean strValActive;
- private String strVal;<pre name="code"class="java"> /**
- * Creates a new instance.
- *
- * @param parent
- * the parent of this channel. {@code null} if there's no parent.
- */
- protected AbstractChannel(Channel parent) {
- this.parent = parent;
- unsafe = newUnsafe();
- pipeline = new DefaultChannelPipeline(this);
- }
3)AbstractNioChannel
AbstractNioChannel繼承AbstractChannel,從這個類開始涉及到JDK的socket,參考如下關鍵程式碼:
- privatefinal SelectableChannel ch;
- protectedfinalint readInterestOp;
- privatevolatile SelectionKey selectionKey;
- privatevolatileboolean inputShutdown;
- <pre name="code"class="java"> @Override
- protectedvoid doRegister() throws Exception {
- boolean selected = false;
- for (;;) {
- try {
- selectionKey = javaChannel().register(eventLoop().selector, 0, this);
- return;
- } catch (CancelledKeyException e) {
- if (!selected) {
- // Force the Selector to select now as the "canceled" SelectionKey may still be
- // cached and not removed because no Select.select(..) operation was called yet.
- eventLoop().selectNow();
- selected = true;
- } else {
- // We forced a select operation on the selector before but the SelectionKey is still cached
- // for whatever reason. JDK bug ?
- throw e;
- }
- }
- }
- }
/** * Create a new instance * * @param parent the parent {@link Channel} by which this instance was created. May be {@code null} * @param ch the underlying {@link SelectableChannel} on which it operates * @param readInterestOp the ops to set to receive data from the {@link SelectableChannel} */ protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) { super(parent); this.ch = ch; this.readInterestOp = readInterestOp; try { ch.configureBlocking(false); } catch (IOException e) { try { ch.close(); } catch (IOException e2) { if (logger.isWarnEnabled()) { logger.warn( "Failed to close a partially initialized socket.", e2); } } throw new ChannelException("Failed to enter non-blocking mode.", e); } } 從上面的程式碼可以看出,這裡定義真正的Socket Channel(SelectableChannel),關心的事件,註冊後的key。將Socket設定為非阻塞,這是所有非同步IO的關鍵,也就是說不管多麼好的框架,底層基礎還是不會變,可見學好基礎的重要性啊,^_^。這裡重點要關注一下register函式,這個函式是將Channel和事件迴圈進行關聯的關鍵。每個事件迴圈都有一個自己的selector,channel實際上是註冊到了相應eventloop的selector中,這也是Nio Socket程式設計的基礎。
從這個類中已經可以看到netty的channel是如何和socket 的nio channel關聯的了,以及channel是如何和eventloop關聯的了。
4)AbstractNioMessageChannel
這個類繼承AbstractNioChannel,主要是提供了一個newUnsafe方法返回NioMessageUnsafe物件的例項(實現read方法)。另外還定義doReadMessages和doWriteMessage兩個抽象方法。
5)ServerSocketChannel和ServerChannel
這兩個介面主要是定義了一個config方法,以及獲取網路地址的方法。
6)NioServerSocketChannel
NioServerSocketChannel繼承AbstractNioMessageChannel,實現ServerSocketChannel,它是一個具體類,提供給開發者使用。
- /**
- * A {@link io.netty.channel.socket.ServerSocketChannel} implementation which uses
- * NIO selector based implementation to accept new connections.
- */
- publicclass NioServerSocketChannel extends AbstractNioMessageChannel
- implements io.netty.channel.socket.ServerSocketChannel {
- privatestaticfinal ChannelMetadata METADATA = new ChannelMetadata(false);
- privatestaticfinal InternalLogger logger = InternalLoggerFactory.getInstance(NioServerSocketChannel.class);
- privatestatic ServerSocketChannel newSocket() {
- try {
- return ServerSocketChannel.open();
- } catch (IOException e) {
- thrownew ChannelException(
- "Failed to open a server socket.", e);
- }
- }
- privatefinal ServerSocketChannelConfig config;
- /**
- * Create a new instance
- */
- public NioServerSocketChannel() {
- super(null, newSocket(), SelectionKey.OP_ACCEPT);
- config = new DefaultServerSocketChannelConfig(this, javaChannel().socket());
- }
- @Override
- protected ServerSocketChannel javaChannel() {
-
return
相關推薦
netty基礎入門(channel理解)
備註:本文的分析基於netty 4.0.9final版本,僅對Nio進行分析,因為本人對Socket程式設計比較感興趣。 1、channel總體機構圖 nio channel的總體結構圖如下: 2、關鍵類和介面分析 2.1 基於Nio
Java基礎入門(十一)之基本數據包裝類以及簡單轉換
數據包 intvalue nbsp 1.5 lse false 永遠 ring jdk 一、 基本數據類型包裝類 引用數據類型一般為基本數據類型首字母大寫,除了int 、char,其中int的引用數據類型類Integer,char的引用數據類型為Character 關
Python基礎入門(類Class)
例項化:建立一個類的例項,類的具體物件。 類(Class): 用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。 方法:類中定義的函式。 類變數:類變數在整個例項化的物件中是公用的。類變數定義在類中且在函式體之外。類變數通常不作為例項變數使用。 資料成員:類變數
七天LLVM零基礎入門(Linux版本)------第一天
開篇語: 學習LLVM的過程是一個漫長而艱鉅的過程,需要大量的時間和精力。不僅僅如此,開始的過程也不輕鬆。一個好的開始就是成功的一半。我結合了自己學習的過程,以及給別人推薦學習的過程,整理出了這個七天LLVM零基礎入門的系列部落格。主要的目標是讓沒有LLVM基礎的人,經過
Linux平臺Makefile檔案的編寫基礎入門(課堂作業)
原作者:超超boy連結:http://www.cnblogs.com/jycboy/p/5084402.html根據老師的要求,寫一個超簡單的makefile準備:準備三個檔案:file1.c, file2.c, file2.h file1.c:1234567#i
Apache Flink 零基礎入門(十一)Flink transformation
前面講了常用的DataSource的用法,DataSource其實是把資料載入進來,載入進來之後就需要做Transformatio
Apache Flink 零基礎入門(十八)Flink windows和Time操作
Time型別 在Flink中常用的Time型別: 處理時間 攝取時間 事件時間 處理時間 是上圖
c#基礎入門(數據類型)
文字 直接 種類型 常用 log 數據類型 logs 基礎 cnblogs 字符類型 char ,存儲用‘’(英文單引號)括起來的一個單個字符。例如: char Size=‘大‘;//存儲大小 字符串類型 string ,存儲用“”(英文雙引號)括起來的一串字符,不限量
c#基礎入門(算術運算符++ --)
-1 clas num strong ron ack col line 操作符 運算符又名操作符是用於運算的符號,作用於一個或多個的操作數。(操作數:參與運算的數據。) 運算符++和-- ++,叫做自加運算符。比如今天22號,明年長了一天,用代碼寫出來是這樣: int
PHP基礎入門(二)【PHP函數基礎】
就是 進行 size 自定義 取地址 代碼 功能 sha 有一種 PHP基礎入門(二)——函數基礎 了解 PHP基礎入門詳解(一) 後,給大家分享一下PHP的函數基礎。 這部分主要講的就是: 函數的聲明與使用、PHP中變量的作用域、靜態變量、函數的參數傳遞、變量函數
02-Linux基礎入門(二)
... man sso term 創建文件系統 www. lease linux系統 結果 一、命令必須掌握的命令:man,touch,ls,mkdir,cp,rm,mv,echo,pwd,cat,alias,unalias,head,tail,tree,rmdir想拿到高
03-Linux基礎入門(三)-系統的基礎優化[對於使用虛擬機學習的學習者]
技術分享 ifcfg-eth 特殊 ... selinux 排查 運行 版本 get 1、關閉SELinux功能①SELinux配置文件路徑 /etc/selinux/config ②查看SELinux狀態 getenforce ③關閉SELinux 方法一:常規方法→修
08-Linux基礎入門(六)-文件和目錄的屬性及權限之文件類型、文件擴展名及文件權限基礎
ins tmp first 串口 .py 都是 公眾平臺 cond .com 一、Linux中的文件類型在Linux系統中,可以說一切(包括目錄、普通文件、設備文件等)皆為文件。文件類型包含有普通文件、目錄、字符設備文件、設備文件、符號鏈接文件、管道文件等等,當執行ls
10-Linux基礎入門(八)-文件和目錄的屬性及權限之用戶與組和時間戳基礎
log 信息 p s center 新浪 shell 使用 自己的 用戶配置 一、概述Linux是一個多用戶、多任務的操作系統,對於Linux系統來說,由於角色不同,權限和所完成的任務也不同。用戶的角色是通過UID和GID識別的,用戶的UID就相當於我們的身份證一樣,用戶名
11-Linux基礎入門(九)-Linux的通配符
cal echo 微信公眾平臺 當前 技術分享 vertical hub font not 一、概述Linux的通配符和正則表達式是不一樣的,因此代表的意義也是有較大區別的。通配符一般用於用戶命令行bash環境,而Linux正則表達式用於grep、sed、awk場景。符號代
PHP基礎入門(二)
是否 比較 shuffle end 填充 eset arr () int 數組處理:compact()函數:可以把單個變量,多個變量甚至數組放在一個數組中.$example=array("a","b","c");$example2=compact("d","e","exam
PHP基礎入門(三)
pos public enc 靜態變量 類型 對象共享 cname 創建 不用 PHP的面向對象:聲明類: 訪問權限關鍵字 class 類名{成員屬性: 訪問權限關鍵字 $屬性名;成員方法: 訪問權限關鍵字 function 方法名(){}構造方法:function __c
PHP基礎入門(一)
ipa arr 客戶 默認值 unset 他會 blog 不能 fine php現在很火的後臺開發語言,它融合了許多其他的語言,所以它的靈活性不用多說.話不多說,我們開始php的學習吧! 整數類型:$變量名=132;浮點類型:$變量名=1.32;字符串類型:$變量名="
爬蟲基礎入門(一)
第三部分 tps 百度首頁 控制 set 協議 debug AD 主機 1 URL含義 URL的格式由三部分組成: ①第一部分是協議(或稱為服務方式)。 ②第二部分是存有該資源的主機IP地址(有時也包括端口號)。 ③第三部分是主機資源的具體地址,如目錄和文件名等。 2 分
canvas基礎入門(一)繪制線條、三角形、七巧板
java i++ rip BE lin scrip 瀏覽器 返回 函數 復雜的內容都是有簡單的線條結合而成的,想要繪制出復雜好看的內容先從畫直線開始 canvas繪制直線先認識幾個函數 beginPath();開始一條路徑,或重置當前的路徑 moveTo(x,y);用於規定