当前位置: 首页 > 后端技术 > Java

Netty系列:netty中不同类型channel详解

时间:2023-04-01 20:01:27 Java

介绍Channel是连接客户端和服务端的桥梁。在netty中,最常用的就是NIO。NioServerSocketChannel和NioSocketChannel通常与NioEventLoopGroup一起使用。如果是UDP协议,则使用NioDatagramChannel作为支撑工具。如果是其他协议,还有其他不同的Channel类型。这些不同的渠道类型之间有什么区别?一个直观的感受是,不同的通道与通道连接使用的协议有关,不同的通道可能适配不同的连接协议。是真的吗?netty内部实现有几个渠道?今天我们一起来讨论一下。ServerChannel及其类型虽然ServerChannel继承自Channel,但ServerChannel本身并没有增加任何新的方法:publicinterfaceServerChannelextendsChannel{},所以ServerChannel和Channel都可以看成是Channel,只是语义上的不同。但是由于ServerChannel继承自Channel,所以相对ServerChannel的分类和实现要少于Channel。那么我们就以ServerChannel为例进行说明。ServerChannel有很多实现。我们以Abstract*开头的实现为例。下面是他们的继承关系:/>从上图可以看出ServerChannel有六个抽象类实现,分别是AbstractEpollServerChannel、AbstractKQueueServerChannel、AbstractServerChannel、ServerSocketChannel、SctpServerChannel和ServerDomainSocketChannel。其中,前三个抽象类同时继承自AbstractChannel。Epoll和KqueueEpoll和Kqueue是两个独特的NIO协议,依赖于特定的平台。其中epoll仅在linux平台上支持,而kQueue在FreeBSD、NetBSD、OpenBSD、macOS等操作系统上均有支持。我们看一下AbstractEpollServerChannel的构造函数:protectedAbstractEpollServerChannel(intfd){this(newLinuxSocket(fd),false);}AbstractEpollServerChannel(LinuxSocketfd){这个(fd,isSoErrorZero(fd));}AbstractEpollServerChannel(LinuxSocketbooleanactive){super(null,fd,active);}所有的构造函数都需要一个参数LinuxSocket,它是一个socket,用来为linuxnative方法提供访问支持。同样,我们看一下AbstractKQueueServerChannel的构造函数:AbstractKQueueServerChannel(BsdSocketfd){this(fd,isSoErrorZero(fd));}AbstractKQueueServerChannel(BsdSocketfd,booleanactive){super(null,fd,active);构造函数需要传入一个BsdSocket参数。BsdSocket是一个用于提供对BSD系统的本地方法的访问的类。AbstractServerChannelAbstractServerChannel我们在前面的通道章节已经讲过了,它唯一的实现就是LocalServerChannel,用于本地传输。ServerSocketChannelServerSocketChannel是一个基于Socket连接的ServerChannel。由于是Socket连接,ServerSocketChannel提供了一个InetSocketAddress类型的localAddress和一个remoteAddress,另外还有一个ServerSocketChannelConfig属性用来存放ServerSocketChannel相关的配置信息:@OverrideInetSocketAddresslocalAddress();@OverrideInetSocketAddressremoteAddress();}ServerDomainSocketChannelServerDomainSocketChannel是一个使用DomainSocket进行通信的ServerChannel。什么是域名套接字?DomainSocket的全称是unixdomainsocket,也可以称为IPCsocket,即进程间通信socket,是unix平台上同一台服务器上的一种进程通信方式。我们知道协议比较复杂。对于传统的socket通信,需要定制特定的协议,然后进行打包、解包等操作。但是使用DomainSocket,可以直接拷贝进程的数据,省事又省时。提高了程序效率。DomainSocket的地址是一个文件的路径,实际上是这样的结构:structsockaddr_un{sa_family_tsun_family;/*AF_UNIX,2个字节*/charsun_path[UNIX_PATH_MAX];/*路径名*/};在ServerDomainSocketChannel中,remoteAddress和localAddress的类型都是DomainSocketAddress,DomainSocketAddress有一个socketPath属性,用来存放DomainSocket文件的路径。SctpServerChannel最后要说明的ServerChannel是SctpServerChannel。Sctp的全称是StreamControlTransmissionProtocol,是一种类似于TCP/IP的协议。和SocketServerChannel一样,SctpServerChannel也有一个名为SctpServerChannelConfig的config,它也提供了多个bindAddress方法来绑定InetAddress。Sctp协议的具体内容本章不再深入讨论。感兴趣的朋友可以关注后续章节。Channel及其类型Channel作为ServerChannel的父类,有哪些实现?先看常用频道的实现类:/>channel的实现类好像有很多,基本都是按照channel使用的传输协议类型来分类的。下面详细看一下对应的实现类。UnixChannelUnixChannel代表unix平台上的操作。它有一个fd方法并返回一个FileDescriptor:FileDescriptorfd();这也是unix和windows平台的区别之一。unix平台上的一切都可以用文件来表示。SctpChannel上面说到SctpServerChannel的时候,我们提到了Sctp是一个类似于tcp/ip的协议。SctpChannel定义了协议中需要用到的localAddress和remoteAddress:InetSocketAddresslocalAddress();InetSocketAddress远程地址();定义了一些绑定方法:ChannelFuturebindAddress(InetAddressvar1);ChannelFuturebindAddress(InetAddressvar1,ChannelPromisevar2);ChannelFutureunbindAddress(InetAddressvar1);ChannelFutureunbindAddress(InetAddressvar1,ChannelPromisevar2);因为UDP具有广播的功能,所以在DatagramChannel中提供了joinGroup的方法来加入一个多播组:ChannelFuturejoinGroup(InetAddressmulticastAddress);当然加入后就可以离开了,leaveGroup方法有一些:ChannelFutureleaveGroup(InetAddressmulticastAddress);您还可以阻止特定地址在给定网络接口上的广播:ChannelFutureblock(InetAddressmulticastAddress,NetworkInterfacenetworkInterface,InetAddresssourceToBlock);这些方法与UDP的特性密切相关。DomainDatagramChannelDomainDatagramChannel与前面提到的ServerDomainSocketChannel一样,采用IPC内部进程通信技术,直接复制进程,省去了协议解析等步骤,提高了处理速度。DuplexChannelDuplexChannel顾名思义就是双向通道。DuplexChannel有一个特点,就是通道的两边都可以独立关闭,所以有以下方法:booleanisInputShutdown();ChannelFutureshutdownInput();booleanisOutputShutdown();ChannelFutureshutdownOutput();DuplexChannel的实现有很多,常见的有NIOSocketChannel、KQueueSocketChannel、EpollSocketChannel等。AbstractChannelChannel的另一个很重要的子类是AbstractChannel。AbstractChannel有3个非常重要的实现,分别是AbstractNioChannel、AbstractKQueueChannel和AbstractEpollChannel。这三个类使用了NIO技术,区别在于第一个使用了select,后两个使用了平台特定的KQueue和Epoll技术。其中NIO可以分为NioByteChannel和NioMessageChannel,KQueue和Epoll可以分为StreamChannel和DatagramChannel。综上所述,以上就是netty中channel的基本实现和分类。后面我们会详细说明具体的channel是如何实现的。本文已收录于www.flydean.com最流行的解读,最深刻的干货,最简洁的教程,很多你不知道的小技巧等你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!

最新推荐
猜你喜欢