对于IO来说,除了传统的block IO,使用最多的就是NIO了,通常我们在netty程序中最常用到的就是NIO,比如NioEventLoopGroup,NioServerSocketChannel等。

我们也知道在IO中有比NIO更快的IO方式,比如kqueue和epoll,但是这两种方式需要native方法的支持,也就是说需要在操作系统层面提供服务。

如果我们在支持Kqueue或者epoll的服务器上,netty是否可以提供对这些优秀IO的支持呢?

答案是肯定的。但是首先kqueue和epoll需要JNI支持,也就是说JAVA程序需要调用本地的native方法。

native传输协议的依赖

要想使用kequeue和epoll这种native的传输方式,我们需要额外添加项目的依赖,如果是linux环境,则可以添加如下的maven依赖环境:

<dependencies>     <dependency>       <groupId>io.netty</groupId>       <artifactId>netty-transport-native-epoll</artifactId>       <version>${project.version}</version>       <classifier>linux-x86_64</classifier>     </dependency>     ...   </dependencies>

其中version需要匹配你所使用的netty版本号,否则可能出现调用异常的情况。

classifier表示的是系统架构,它的值可以是linux-x86_64,也可以是linux-aarch_64.

如果你使用的mac系统,那么可以这样引入:

<dependencies>     <dependency>       <groupId>io.netty</groupId>       <artifactId>netty-transport-native-kqueue</artifactId>       <version>${project.version}</version>       <classifier>osx-x86_64</classifier>     </dependency>     ...   </dependencies>

netty除了单独的个体包之外,还有一个all in one的netty-all包,如果你使用了这个all in one的包,那么不需要额外添加native的依赖。

如果netty提供的系统架构并没有你正在使用的,那么你需要手动进行编译,以下是编译所依赖的程序包, 如果是在RHEL/CentOS/Fedora系统中,则使用:

sudo yum install autoconf automake libtool make tar \                  glibc-devel \                  libgcc.i686 glibc-devel.i686

如果是在Debian/Ubuntu系统中,则使用:

sudo apt-get install autoconf automake libtool make tar \                      gcc

如果是在MacOS/BSD系统中,则使用:

brew install autoconf automake libtool

netty本地传输协议的使用

安装好依赖包之后,我们就可以在netty中使用这些native传输协议了。

native传输协议的使用和NIO的使用基本一致,我们只需要进行下面的替换即可。

如果是在liunx系统中,则进行下面的替换:

NioEventLoopGroup → EpollEventLoopGroup     NioEventLoop → EpollEventLoop     NioServerSocketChannel → EpollServerSocketChannel     NioSocketChannel → EpollSocketChannel

如果是在mac系统中,则进行下面的替换:

NioEventLoopGroup → KQueueEventLoopGroup     NioEventLoop → KQueueEventLoop     NioServerSocketChannel → KQueueServerSocketChannel     NioSocketChannel → KQueueSocketChannel

这里还是使用我们熟悉的聊天服务为例,首先看下基于Kqueue的netty服务器端应该怎么写:

EventLoopGroup bossGroup = new KQueueEventLoopGroup(1);         EventLoopGroup workerGroup = new KQueueEventLoopGroup();         try {             ServerBootstrap b = new ServerBootstrap();             b.group(bossGroup, workerGroup)              .channel(KQueueServerSocketChannel.class)              .handler(new LoggingHandler(LogLevel.INFO))              .childHandler(new NativeChatServerInitializer());              Channel channel = b.bind(PORT).sync().channel();             log.info("server channel:{}", channel);             channel.closeFuture().sync();

和NIO一样,在服务器端我们需要使用KQueueEventLoopGroup创建两个EventLoopGroup,一个是bossGroup, 一个是workerGroup。

然后将这两个group传入到ServerBootstrap中,并且添加KQueueServerSocketChannel作为channel。

其他的内容和NIO server的内容是一样的。

接下来我们看下基于Kqueue的netty客户端改如何跟server端建立连接:

EventLoopGroup group = new KQueueEventLoopGroup();         try {             Bootstrap b = new Bootstrap();             b.group(group)              .channel(KQueueSocketChannel.class)              .handler(new NativeChatClientInitializer());              // 建立连接             Channel ch = b.connect(HOST, PORT).sync().channel();             log.info("client channel: {}", ch);

这里使用的是KQueueEventLoopGroup,并将KQueueEventLoopGroup放到Bootstrap中,并且为Bootstrap提供了和server端一致的KQueueSocketChannel。

然后就是客户端向channel中写消息,这里我们直接从命令行输入:

// 从命令行输入             ChannelFuture lastWriteFuture = null;             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));             for (;;) {                 String line = in.readLine();                 if (line == null) {                     break;                 }                 // 将从命令行输入的一行字符写到channel中                 lastWriteFuture = ch.writeAndFlush(line + "\r\n");                 // 如果输入'再见',则等待server端关闭channel                 if ("再见".equalsIgnoreCase(line)) {                     ch.closeFuture().sync();                     break;                 }             }

上面代码的意思是将命令行收到的消息写入到channel中,如果输入的是’再见’,则关闭channel。

为了能够处理字符串,这里用到了三个编码解码器:

// 添加行分割器         pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));         // 添加String Decoder和String Encoder,用来进行字符串的转换         pipeline.addLast(new StringEncoder());         pipeline.addLast(new StringDecoder());

分别是行分割器,字符编码器和字符解码器。

运行一下看,程序运行没问题,客户端和服务器端可以进行通讯。

这里我们只以Kqueue为例介绍了netty中native传输协议的使用,具体的代码,大家可以参考:

learn-netty4

热门文章

和田宠物医院污水处理价格多少(宠物店污水处理设备)

摘要: 今天给各位分享和田宠物医院污水处理价格多少的知识,其中也会对宠物店污水处理设备进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、宠物医院未配.

长沙宠物领养贴吧 长沙宠物领养贴吧论坛

摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于长沙宠物领养贴吧的问题,于是小编就整理了4个相关介绍长沙宠物领养贴吧的解答,让我们一起看看吧。请问长沙有没有收留藏獒的地方?长沙

4月3日更新22.1M/S,2025年最新高速V2ray/Clash/Shadowrocket/SSR订阅链接免费节点地址分享

这一次的节点更新覆盖了香港、韩国、新加坡、美国、欧洲、日本、加拿大等地区,最高速度可达22.1 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

vue中npm run dev 报错(eslint规则)

1.报错了。。。 You may use special comments to disable some warnings. Use // eslint-disable-next-line to i

为啥家猫不需要打疫苗宠物猫要打呢(为什么猫不用打狂犬疫苗)

摘要: 今天给各位分享为啥家猫不需要打疫苗宠物猫要打呢的知识,其中也会对为什么猫不用打狂犬疫苗进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、为什.

3月9日更新18.9M/S,2025年最新高速Clash/Shadowrocket/V2ray/SSR订阅链接免费节点地址分享

这一次的节点更新覆盖了韩国、新加坡、加拿大、日本、欧洲、美国、香港等地区,最高速度可达18.9 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

通州区宠物店(通州区宠物店电话)

摘要: 本篇文章给大家谈谈通州区宠物店,以及通州区宠物店电话对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、宠物驯导师的职业概况2、... 本篇文章给

24小时宠物医院咨询电话临平(临平宠物店)

摘要: 本篇文章给大家谈谈24小时宠物医院咨询电话临平,以及临平宠物店对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、宠物医生怎么咨询.2、... 本

4月1日更新18.2M/S,2025年最新高速V2ray/Clash/SSR/Shadowrocket订阅链接免费节点地址分享

这一次的节点更新覆盖了美国、日本、加拿大、欧洲、香港、新加坡、韩国等地区,最高速度可达18.2 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。

宠物粮品牌起名字大全集图片及价格(宠物粮品牌名称)

摘要: 本篇文章给大家谈谈宠物粮品牌起名字大全集图片及价格,以及宠物粮品牌名称对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、世界十大顶级狗粮品牌...

归纳