Netty简介

Netty是一个异步通信、事件驱动基于NIO编写的高性能高并发的java网络编程框架。下面通过一个简单的服务器应答程序来完成Netty的初步学习。

代码地址:https://gitee.com/ShiXiCheng/study_netty

Netty的编程例子——应答程序

设置开发环境

Jdk1.8

Mvn配置

<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.12.Final</version></dependency>
</dependencies>

应答服务器

一个Netty服务器主要有三个部分组成

l  服务器配置,配置端口、操作线程池等。

l  通道初始程序,传输的编解码格式、粘包处理、通道处理程序的调用。

l  实现通道处理程序,它包含业务逻辑,即实现服务器通道发生连接、读取信息等事件时的处理。

启动服务器

通过创建SerserBootstrap对象来启动服务器,然后配置对象的相关属性,如端口、线程模式、处理程序等。

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;public classHelloServer {private static final int protNumner= 7878;public static void main(String[] args) throws InterruptedException {// 事件循环组/** Main函数开始的位置定义了两个工作线程,一个命名为WorkerGroup,另一个命名为BossGroup。* 都是实例化NioEventLoopGroup。这一点和3.x版本中基本思路是一致的。Worker线程用于管理线程为Boss线程服务。* EventLoopGroup,它是4.x版本提出来的一个新概念。类似于3.x版本中的线程。用于管理Channel连接的。* 在main函数的结尾就用到了EventLoopGroup提供的便捷的方法,shutdownGraceFully(),* 翻译为中文就是优雅的全部关闭。*/EventLoopGroupbossGroup= newNioEventLoopGroup();EventLoopGroupworkerGroup= newNioEventLoopGroup();/* ServerBootstrap负责初始化netty服务器,并且开始监听端口的socket请求 */ServerBootstrapb = new ServerBootstrap();b.group(bossGroup, workerGroup);b.channel(NioServerSocketChannel.class);b.childHandler(newHelloServerInitializer());// 服务器绑定端口监听ChannelFuturef = b.bind(protNumner).sync();// 监听服务器关闭监听f.channel().closeFuture().sync();}
}

通道的初始化程序

初始化程序可以加上编解码、消息分割(粘包)、业务处理程序等。这些设置都是通过ChannelPipeline.addLast()来实现的。

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;public classHelloServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected voidinitChannel(SocketChannel ch) throwsException {ChannelPipelinepipeline= ch.pipeline();// 以("\n")为结尾分割的解码器,最大帧长度为8192// Delimiter Based Frame Decoder 基于定界符的帧解码器// Delimiters.lineDelimiter()行分隔符// 这里使用时,会把换行符作为一个消息的分隔界限使用,即接收时,换行符前为一条消息pipeline.addLast("framer",newDelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));// 字符串解码和编码// encoder 编码器, decoder 解码器pipeline.addLast("decoder",newStringDecoder());pipeline.addLast("encoder",newStringEncoder());// 自己的逻辑Handlerpipeline.addLast("handler",newHelloServerHandler());}
}

通道的业务处理程序

处理程序是事件驱动的,用于监控服务器事件的产生,自定义事件的处理。

import java.net.InetAddress;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;public classHelloServerHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected voidchannelRead0(ChannelHandlerContext ctx, String msg)throwsException {// 收到消息直接打印输出System.out.println(ctx.channel().remoteAddress()+ " Say : "+ msg);// 返回客户端信息 - 我已经接收到了你的消息// writeAndFlush写消息并发送ctx.writeAndFlush("received your message !\n");}// 当Channel变成活跃状态时被调用public voidchannelActive(ChannelHandlerContext ctx) throwsException {System.out.println("RamoteAddress : "+ ctx.channel().remoteAddress()+ " active !");ctx.writeAndFlush("welcome to "+ InetAddress.getLocalHost().getHostName() + " server.\n");super.channelActive(ctx);}
}

SimpleChannelInboundHandler这里实现事件处理,ChannelRead0是读取数据事件,channelActive是通道连接事件。

除了以上事件,还有如下事件

void channelInactive(ChannelHandlerContextctx)  连接中断时,调用它

void userEventTriggered(ChannelHandlerContext ctx, Object evt)  如果触发了用户事件,将调用它。

void channelWritabilityChanged(ChannelHandlerContextctx)  一旦更改了{连接信道}的可写状态,就调用。您可以检查状态

void exceptionCaught(ChannelHandlerContextctx, Throwable cause)  如果抛出异常,将调用它。

在writeAndFlush后要接”\n”,pipeline设置的是通过换行符来分割信息。

编写应答程序客户端

一个客户端程序主要有三部分组成,与服务器类似

l  连接服务器,配置服务器的ip、端口,创建服务器连接通道对象,向服务器发送数据

l  通道初始程序,传输的解编码格式、粘包处理、通道处理程序的调用。

l  实现通道处理程序,它包含业务逻辑,即实现客户端通道发生连接、读取信息等事件时的处理。

连接服务器

Netty4通过Bootstrap来创建通道连接对象Channel,通过Channel的writeAndFlush来向服务器发送数据。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;/*** netty客户端** @author逝兮诚* @date 2017年6月26日下午5:37:23**/
public classHelloClient {public static String host = "127.0.0.1";public static int port = 7878;public static void main(String[] args) throws IOException,InterruptedException {EventLoopGroupgroup= newNioEventLoopGroup();Bootstrapb = new Bootstrap();b.group(group).channel(NioSocketChannel.class).handler(newHelloClientInitializer());// 连接服务端Channelch = b.connect(host, port).sync().channel();// 控制台输入BufferedReaderin = new BufferedReader(newInputStreamReader(System.in));for (;;) {Stringline= in.readLine();if (line == null)continue;ch.writeAndFlush(line + "\r\n");}}
}

通道的初始化设置程序

初始化设置程序同服务器一样,便不再过多累述。

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;public classHelloClientInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected voidinitChannel(SocketChannel ch) throwsException {ChannelPipelinepipeline= ch.pipeline();pipeline.addLast("framer",newDelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));pipeline.addLast("decoder",newStringDecoder());pipeline.addLast("encoder",newStringEncoder());// 客户端的逻辑pipeline.addLast("handler",newHelloClientHandler());}
}

通道的业务处理程序

客户端的连接通道的业务处理程序与服务器类似,就不再过多累述。

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;public classHelloClientHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected voidchannelRead0(ChannelHandlerContext ctx, String msg)throwsException {System.out.println("Server say : "+ msg);}@Overridepublic voidchannelActive(ChannelHandlerContext ctx) throwsException {System.out.println("Client active ");super.channelActive(ctx);}@Overridepublic voidchannelInactive(ChannelHandlerContext ctx) throwsException {System.out.println("Client close ");super.channelInactive(ctx);}
}

运行结果

客户端

服务端

Netty教程系列(一)——netty入门应答程序相关推荐

  1. Netty教程02:Netty实战之TCP服务

    源码地址:https://gitee.com/pidaner/netty-class 官网:https://netty.io/ Netty is an asynchronous event-drive ...

  2. Netty教程04:Netty知识点

    Bootstrap是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Netty 程序,串联各个组件,Netty 中 Bootstrap 类是客户端程序的启动引导类 ...

  3. Springboot微服务开发教程系列:开发入门

    使用IntelliJ IDEA开发springboot入门 第一步:创建项目 第二步:填写项目信息 第三步:选择特性 第四步:等待项目创建 下载项目依赖项需要一些时间,请耐心等待 第五步:编写demo ...

  4. java nio oio_Java NIO框架Netty教程(十四) Netty中OIO模型(对比NIO)

    Netty中不光支持了Java中NIO模型,同时也提供了对OIO模型的支持.(New IO vs Old IO). 首先,在Netty中,切换OIO和NIO两种模式是非常方便的,只需要初始化不同的Ch ...

  5. java nio oio_Java NIO框架Netty教程(十四)-Netty中OIO模型(对比NIO)

    OneCoder这个周末搬家,并且新家目前还没有网络,本周的翻译的任务尚未完成,下周一起补上,先上一篇OIO和NIO对比的小研究. Netty中不光支持了Java中NIO模型,同时也提供了对OIO模型 ...

  6. Netty教程06:netty实现群聊私聊

    netty实现群聊,点击查看 需求:在群聊基础上,增加私聊功能 Server package com.lian.groupprivatechat;import io.netty.bootstrap.S ...

  7. Java Netty 教程

    Netty是用于Java的高性能IO工具包. Netty是开源的,因此可以自由使用它,甚至可以为它做出贡献.该Netty教程将解释Netty的工作方式以及如何开始使用Netty.但本教程不会涵盖Net ...

  8. Netty系列(2)快速入门Netty线程模型、Netty入门程序、Netty任务队列

    文章目录 1 Netty线程模型 1.1 传统阻塞 I/O 服务模型 1.2 Reactor线程模型 1.2.1 单 Reactor 单线程模型 1.2.2 单Reactor多线程 1.2.3 主从 ...

  9. java netty教程_明哥教学 - Netty简单入门教程

    作为一个正在Java路上摸爬滚打的小菜鸡,之前在项目中也用过Netty,也因为Netty报名阿里的中间件大赛,但终究功力太浅,最终不了了之,最近工作中又遇到了Netty的小姐妹Mina.此时楼主觉得N ...

最新文章

  1. Linux期末复习题库(1)
  2. 使用jQuery的Scrollify插件实现鼠标滚轮或者手势滑动到页面下一节点部分
  3. Java8 lambda表达式10个示例
  4. 生活的花环:看雷加对文学的回顾
  5. 详解MTK系统中字符转换问题
  6. C#学习记录3上——类的封装,继承,多态
  7. 信息学奥赛一本通 1890:【15NOIP提高组】跳石头 | 洛谷 P2678 [NOIP2015 提高组] 跳石头
  8. 源码安装apache, jre, tomcat
  9. mysql备份-a是什么_MySQL主从备份和主主备份配置+Keepalived+MySQL读写分离
  10. 一张图学会python3语法-一张图理清 Python3 所有知识点
  11. java获取当月共有几天_Java计算当前月有多少天以及获取当前月开始以及结束日期...
  12. vue 面试题 前端面试题--vue 第六弹
  13. 利用unlocker在VMware里解锁macOS操作系统
  14. dbf格式转Excel(xls)格式教程
  15. 运行 Visual Studio 2019当前页面的脚本发生错误解决方法
  16. Kaggle时间序列(Time Series)教程 3-季节性(Seasonality)
  17. python实验总结与分析_Python实验报告七
  18. 商业图表案例8-全球十大电影成本收益
  19. 阿里云服务器学生机搭建及宝塔面板环境配置
  20. springboot+敬老院管理系统 毕业设计-附源码261535

热门文章

  1. java-php-python-ssm长庚游戏网站计算机毕业设计
  2. 网购图书java代码_基于JAVAEE网上购物系统(含源文件).doc
  3. 新型碎石破碎设备,鄂破机首居第一
  4. WKWebView的应用
  5. uml具有多种视图_UML的9种图及4+1视图简介(整理)
  6. NandFlash基础知识
  7. 任务2:常用的分词算法 I
  8. 20X47 FCPX模板悬挂翻转照片墙多张图片展示片头 Photo Grid Revealer
  9. VB与数据库结合开发全过程!
  10. 南京软博会·开源软件论坛丨盖国强:持续投身鲲鹏产业生态建设