netty系列之:netty中各不同种类的channel详解
文章目錄
- 簡介
- ServerChannel和它的類型
- Epoll和Kqueue
- AbstractServerChannel
- ServerSocketChannel
- ServerDomainSocketChannel
- SctpServerChannel
- Channel和它的類型
- UnixChannel
- SctpChannel
- DatagramChannel
- DomainDatagramChannel
- DuplexChannel
- AbstractChannel
- 總結(jié)
簡介
channel是連接客戶端和服務(wù)器端的橋梁,在netty中我們最常用的就是NIO,一般和NioEventLoopGroup配套使用的就是NioServerSocketChannel和NioSocketChannel,如果是UDP協(xié)議,那么配套使用的就是NioDatagramChannel,如果是別的協(xié)議還有其他不同的Channel類型。
這些不同channel類型有什么區(qū)別呢?一個直觀的感覺就是不同的channel和channel連接使用的協(xié)議有關(guān)系,不同的channel可能適配了不同的連接協(xié)議。
事實到底是不是如此呢?在netty的內(nèi)部實現(xiàn)中到底有多少種channel呢?今天一起來探討一下。
ServerChannel和它的類型
雖然ServerChannel繼承自Channel,但是ServerChannel本身并沒有添加任何新的方法:
public interface ServerChannel extends Channel {}所以對ServerChannel和Channel來說都可以看做是Channel,他們只是語義上有區(qū)別。
但是因為ServerChannel繼承自Channel,所以相對的ServerChannel的分類和實現(xiàn)要比Channel要少。所以我們先以ServerChannel為例進行講解。
ServerChannel的實現(xiàn)也有很多,我們以Abstract*開頭的實現(xiàn)為例,下面是他們的繼承關(guān)系:
從上圖我們可以看出,ServerChannel有六個抽象類實現(xiàn),分別是AbstractEpollServerChannel,AbstractKQueueServerChannel,AbstractServerChannel,ServerSocketChannel,SctpServerChannel和ServerDomainSocketChannel。
其中前面三個抽象類同時繼承自AbstractChannel。
Epoll和Kqueue
Epoll和Kqueue是兩個獨特的依賴于特定平臺的NIO協(xié)議,其中epoll只在linux平臺才支持,而kQueue則在FreeBSD、NetBSD、OpenBSD、macOS 等操作系統(tǒng)支持。
我們來看下AbstractEpollServerChannel的構(gòu)造函數(shù):
protected AbstractEpollServerChannel(int fd) {this(new LinuxSocket(fd), false);}AbstractEpollServerChannel(LinuxSocket fd) {this(fd, isSoErrorZero(fd));}AbstractEpollServerChannel(LinuxSocket fd, boolean active) {super(null, fd, active);}所有的構(gòu)造函數(shù)都需要一個LinuxSocket的參數(shù),LinuxSocket是一個socket用來提供對于linux native方法的訪問支持。
同樣的,我們再看一下AbstractKQueueServerChannel的構(gòu)造函數(shù):
AbstractKQueueServerChannel(BsdSocket fd) {this(fd, isSoErrorZero(fd));}AbstractKQueueServerChannel(BsdSocket fd, boolean active) {super(null, fd, active);}AbstractKQueueServerChannel的構(gòu)造函數(shù)需要傳入一個BsdSocket參數(shù),BsdSocket是一個類用來提供對BSD系統(tǒng)的本地方法的訪問。
AbstractServerChannel
AbstractServerChannel我們在之前的channel一章中已經(jīng)講過了,它的唯一實現(xiàn)就是LocalServerChannel,用于本地的transport。
ServerSocketChannel
ServerSocketChannel是一個以Socket連接為基礎(chǔ)的ServerChannel,既然是Socket連接,那么ServerSocketChannel中提供了一個InetSocketAddress類型的localAddress和一個remoteAddress, 另外還有一個ServerSocketChannelConfig屬性,用來存儲ServerSocketChannel相關(guān)的配置信息:
public interface ServerSocketChannel extends ServerChannel {@OverrideServerSocketChannelConfig config();@OverrideInetSocketAddress localAddress();@OverrideInetSocketAddress remoteAddress(); }ServerDomainSocketChannel
ServerDomainSocketChannel是使用DomainSocket來進行通訊的ServerChannel。什么是DomainSocket呢?
DomainSocket的全稱是unix domain socket,它又可以叫做IPC socket,也就是inter-process communication socket,是在unix平臺上的同一服務(wù)器上的進程通信方式。
我們知道,協(xié)議是比較復(fù)雜的,對于傳統(tǒng)的socket通訊來說,需要定制特定的協(xié)議,然后進行封包和解包等操作,但是使用DomainSocket,可以直接將進程的數(shù)據(jù)直接拷貝,從而節(jié)約了時間,并提高了程序的效率。
DomainSocket的地址是一個文件的路徑,實際上是下面的一個結(jié)構(gòu)體:
struct sockaddr_un {sa_family_t sun_family; /* AF_UNIX ,2字節(jié)*/char sun_path[UNIX_PATH_MAX]; /* 路徑名 */ };在ServerDomainSocketChannel中的remoteAddress和localAddress的類型都是DomainSocketAddress,DomainSocketAddress有一個socketPath屬性,用來存儲DomainSocket文件的路徑。
SctpServerChannel
最后一個要講解的ServerChannel是SctpServerChannel,Sctp的全稱是Stream Control Transmission Protocol,他是一種類似于TCP/IP的協(xié)議。和SocketServerChannel一樣,SctpServerChannel中也有一個config叫做SctpServerChannelConfig,還提供了多個bindAddress方法用來綁定InetAddress.
有關(guān)Sctp協(xié)議的具體內(nèi)容,本章不深入討論,感興趣的朋友可以關(guān)注后續(xù)的章節(jié)。
Channel和它的類型
Channel作為ServerChannel的父類,又有哪些實現(xiàn)呢?
先來看下常用channel的實現(xiàn)類:
看起來channel的實現(xiàn)類非常多,基本上都是按照channel中使用傳輸協(xié)議的類型來的。
我們具體來看一下相應(yīng)的實現(xiàn)類。
UnixChannel
UnixChannel表示的unix平臺上的操作,它有一個fd方法,返回一個FileDescriptor:
FileDescriptor fd();這也是unix和windows平臺的區(qū)別之一,unix平臺所有的一切都可以用文件來表示。
SctpChannel
在上面我講SctpServerChannel的時候我們提過了,Sctp是一個類似于tcp/ip的協(xié)議,SctpChannel中定義了協(xié)議中需要使用到的localAddress和remoteAddress:
InetSocketAddress localAddress();InetSocketAddress remoteAddress();同時還定義了一些綁定方法:
ChannelFuture bindAddress(InetAddress var1);ChannelFuture bindAddress(InetAddress var1, ChannelPromise var2);ChannelFuture unbindAddress(InetAddress var1);ChannelFuture unbindAddress(InetAddress var1, ChannelPromise var2);DatagramChannel
DatagramChannel用來處理UDP協(xié)議的連接,因為UDP有廣播的功能,所以DatagramChannel中提供了joinGroup的方法,來join一個multicast group:
ChannelFuture joinGroup(InetAddress multicastAddress);當(dāng)然,可以join就可以leave,還有一些leaveGroup的方法:
ChannelFuture leaveGroup(InetAddress multicastAddress);還可以block某些地址在給定的networkInterface上的廣播:
ChannelFuture block(InetAddress multicastAddress, NetworkInterface networkInterface,InetAddress sourceToBlock);這些方法都和UDP的特性是息息相關(guān)的。
DomainDatagramChannel
DomainDatagramChannel和之前提到的ServerDomainSocketChannel一樣,都是使用的IPC內(nèi)部進程通訊技術(shù),直接進行進程的拷貝,免去了協(xié)議解析等步驟,提升了處理速度。
DuplexChannel
DuplexChannel從名字看就是一個雙向的channel,duplex Channel有一個特點,就是channel的兩邊可以獨立的關(guān)閉,所以有下面的方法:
boolean isInputShutdown();ChannelFuture shutdownInput();boolean isOutputShutdown();ChannelFuture shutdownOutput();DuplexChannel的是實現(xiàn)有很多種,比如常見的NIOSocketChannel,KQueueSocketChannel,EpollSocketChannel等。
AbstractChannel
另外一個channel的非常重要的子類就是AbstractChannel,AbstractChannel有三個非常重要的實現(xiàn),分別是AbstractNioChannel,AbstractKQueueChannel和AbstractEpollChannel。
這三個類使用的都是NIO技術(shù),不同的是第一個使用的是select,后面兩個使用的是平臺獨有的KQueue和Epoll技術(shù)。
其中NIO又可以分為NioByteChannel和NioMessageChannel,KQueue和Epoll又可以分為StreamChannel和DatagramChannel。
總結(jié)
以上就是channel在netty中的基本實現(xiàn)和分類。后面我們會詳解講解具體的channel到底是如何實現(xiàn)的。
本文已收錄于 www.flydean.com
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發(fā)現(xiàn)!
歡迎關(guān)注我的公眾號:「程序那些事」,懂技術(shù),更懂你!
總結(jié)
以上是生活随笔為你收集整理的netty系列之:netty中各不同种类的channel详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络标准之:IANA定义的传输编码
- 下一篇: java高级用法之:调用本地方法的利器J