Introduction
Channel is the bridge connecting the client and the server. In netty, the most commonly used one is NIO. Generally, NioServerSocketChannel and NioSocketChannel are used together with NioEventLoopGroup. If it is UDP protocol, then NioDatagramChannel is used. If it is another protocol, there are Other different Channel types.
What is the difference between these different channel types? An intuitive feeling is that different channels are related to the protocols used by channel connections, and different channels may be adapted to different connection protocols.
Is this the case? How many channels are there in the internal implementation of netty? Let's discuss it together today.
ServerChannel and its types
Although ServerChannel inherits from Channel, ServerChannel itself does not add any new methods:
public interface ServerChannel extends Channel {
}
So both ServerChannel and Channel can be regarded as Channel, they are only semantically different.
But because ServerChannel inherits from Channel, the relative classification and implementation of ServerChannel are less than Channel. So let's take ServerChannel as an example to explain.
There are also many implementations of ServerChannel. Let's take the implementation starting with Abstract* as an example. The following is their inheritance relationship:
<img src="https://img-blog.csdnimg.cn/9613bc4cb9314dc2903a938f80340b47.png" style="zoom:67%;" />
As can be seen from the above figure, ServerChannel has six abstract class implementations, namely AbstractEpollServerChannel, AbstractKQueueServerChannel, AbstractServerChannel, ServerSocketChannel, SctpServerChannel and ServerDomainSocketChannel.
The first three abstract classes inherit from AbstractChannel at the same time.
Epoll and Kqueue
Epoll and Kqueue are two unique NIO protocols that depend on specific platforms. Epoll is only supported on Linux platforms, while kQueue is supported on FreeBSD, NetBSD, OpenBSD, macOS and other operating systems.
Let's take a look at the constructor of AbstractEpollServerChannel:
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);
}
All constructors require a parameter of LinuxSocket, which is a socket used to provide access support for linux native methods.
Similarly, let's take a look at the constructor of AbstractKQueueServerChannel:
AbstractKQueueServerChannel(BsdSocket fd) {
this(fd, isSoErrorZero(fd));
}
AbstractKQueueServerChannel(BsdSocket fd, boolean active) {
super(null, fd, active);
}
The constructor of AbstractKQueueServerChannel needs to pass in a BsdSocket parameter. BsdSocket is a class used to provide access to the native methods of the BSD system.
AbstractServerChannel
AbstractServerChannel we have talked about in the previous channel chapter, its only implementation is LocalServerChannel, which is used for local transport.
ServerSocketChannel
ServerSocketChannel is a ServerChannel based on Socket connection. Since it is a Socket connection, ServerSocketChannel provides a localAddress of type InetSocketAddress and a remoteAddress, and there is also a ServerSocketChannelConfig property to store ServerSocketChannel related configuration information:
public interface ServerSocketChannel extends ServerChannel {
@Override
ServerSocketChannelConfig config();
@Override
InetSocketAddress localAddress();
@Override
InetSocketAddress remoteAddress();
}
ServerDomainSocketChannel
ServerDomainSocketChannel is a ServerChannel that uses DomainSocket for communication. What is DomainSocket?
The full name of DomainSocket is unix domain socket, which can also be called IPC socket, that is, inter-process communication socket, which is a process communication method on the same server on the unix platform.
We know that the protocol is relatively complicated. For traditional socket communication, it is necessary to customize a specific protocol, and then perform operations such as packetization and unpacking. However, using DomainSocket, the process data can be copied directly, thus saving time and Improve the efficiency of the program.
The address of DomainSocket is the path of a file, which is actually the following structure:
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX ,2字节*/
char sun_path[UNIX_PATH_MAX]; /* 路径名 */
};
The types of remoteAddress and localAddress in ServerDomainSocketChannel are both DomainSocketAddress. DomainSocketAddress has a socketPath property, which is used to store the path of the DomainSocket file.
SctpServerChannel
The last ServerChannel to be explained is SctpServerChannel. The full name of Sctp is Stream Control Transmission Protocol, which is a protocol similar to TCP/IP. Like SocketServerChannel, SctpServerChannel also has a config called SctpServerChannelConfig, which also provides multiple bindAddress methods to bind InetAddress.
For the specific content of the Sctp protocol, this chapter does not discuss in depth, and interested friends can pay attention to the subsequent chapters.
Channel and its types
As the parent class of ServerChannel, what are the implementations of Channel?
Let's first look at the implementation classes of commonly used channels:
<img src="https://img-blog.csdnimg.cn/69d7d0d53df847e2b5eb7791da956ef1.png" style="zoom:67%;" />
It seems that there are many implementation classes of channel, basically according to the type of transmission protocol used in channel.
Let's take a look at the corresponding implementation classes in detail.
UnixChannel
An operation on the unix platform represented by UnixChannel, which has an fd method that returns a FileDescriptor:
FileDescriptor fd();
This is also one of the differences between Unix and Windows platforms. Everything on the Unix platform can be represented by files.
SctpChannel
When I talked about SctpServerChannel above, we mentioned that Sctp is a protocol similar to tcp/ip. SctpChannel defines the localAddress and remoteAddress that need to be used in the protocol:
InetSocketAddress localAddress();
InetSocketAddress remoteAddress();
It also defines some binding methods:
ChannelFuture bindAddress(InetAddress var1);
ChannelFuture bindAddress(InetAddress var1, ChannelPromise var2);
ChannelFuture unbindAddress(InetAddress var1);
ChannelFuture unbindAddress(InetAddress var1, ChannelPromise var2);
DatagramChannel
DatagramChannel is used to handle UDP protocol connections. Because UDP has the function of broadcasting, DatagramChannel provides the joinGroup method to join a multicast group:
ChannelFuture joinGroup(InetAddress multicastAddress);
Of course, you can join to leave, and there are some leaveGroup methods:
ChannelFuture leaveGroup(InetAddress multicastAddress);
It is also possible to block the broadcast of certain addresses on a given networkInterface:
ChannelFuture block(
InetAddress multicastAddress, NetworkInterface networkInterface,
InetAddress sourceToBlock);
These methods are closely related to the characteristics of UDP.
DomainDatagramChannel
DomainDatagramChannel, like the aforementioned ServerDomainSocketChannel, uses the IPC internal process communication technology, which directly copies the process, eliminating steps such as protocol parsing and improving the processing speed.
DuplexChannel
DuplexChannel is a two-way channel from the name. Duplex Channel has a feature that both sides of the channel can be closed independently, so there are the following methods:
boolean isInputShutdown();
ChannelFuture shutdownInput();
boolean isOutputShutdown();
ChannelFuture shutdownOutput();
There are many implementations of DuplexChannel, such as the common NIOSocketChannel, KQueueSocketChannel, EpollSocketChannel, etc.
AbstractChannel
Another very important subclass of channel is AbstractChannel. AbstractChannel has three very important implementations, namely AbstractNioChannel, AbstractKQueueChannel and AbstractEpollChannel.
These three classes use NIO technology, the difference is that the first one uses select, and the latter two use platform-unique KQueue and Epoll technologies.
Among them, NIO can be divided into NioByteChannel and NioMessageChannel, and KQueue and Epoll can be divided into StreamChannel and DatagramChannel.
Summarize
The above is the basic implementation and classification of channel in netty. Later, we will explain in detail how the specific channel is implemented.
This article has been included in www.flydean.com
The most popular interpretation, the most profound dry goods, the most concise tutorials, and many tricks you don't know are waiting for you to discover!
Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。