Netty教程系列(一)——netty入门应答程序
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入门应答程序相关推荐
- Netty教程02:Netty实战之TCP服务
源码地址:https://gitee.com/pidaner/netty-class 官网:https://netty.io/ Netty is an asynchronous event-drive ...
- Netty教程04:Netty知识点
Bootstrap是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Netty 程序,串联各个组件,Netty 中 Bootstrap 类是客户端程序的启动引导类 ...
- Springboot微服务开发教程系列:开发入门
使用IntelliJ IDEA开发springboot入门 第一步:创建项目 第二步:填写项目信息 第三步:选择特性 第四步:等待项目创建 下载项目依赖项需要一些时间,请耐心等待 第五步:编写demo ...
- java nio oio_Java NIO框架Netty教程(十四) Netty中OIO模型(对比NIO)
Netty中不光支持了Java中NIO模型,同时也提供了对OIO模型的支持.(New IO vs Old IO). 首先,在Netty中,切换OIO和NIO两种模式是非常方便的,只需要初始化不同的Ch ...
- java nio oio_Java NIO框架Netty教程(十四)-Netty中OIO模型(对比NIO)
OneCoder这个周末搬家,并且新家目前还没有网络,本周的翻译的任务尚未完成,下周一起补上,先上一篇OIO和NIO对比的小研究. Netty中不光支持了Java中NIO模型,同时也提供了对OIO模型 ...
- Netty教程06:netty实现群聊私聊
netty实现群聊,点击查看 需求:在群聊基础上,增加私聊功能 Server package com.lian.groupprivatechat;import io.netty.bootstrap.S ...
- Java Netty 教程
Netty是用于Java的高性能IO工具包. Netty是开源的,因此可以自由使用它,甚至可以为它做出贡献.该Netty教程将解释Netty的工作方式以及如何开始使用Netty.但本教程不会涵盖Net ...
- 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 主从 ...
- java netty教程_明哥教学 - Netty简单入门教程
作为一个正在Java路上摸爬滚打的小菜鸡,之前在项目中也用过Netty,也因为Netty报名阿里的中间件大赛,但终究功力太浅,最终不了了之,最近工作中又遇到了Netty的小姐妹Mina.此时楼主觉得N ...
最新文章
- Linux期末复习题库(1)
- 使用jQuery的Scrollify插件实现鼠标滚轮或者手势滑动到页面下一节点部分
- Java8 lambda表达式10个示例
- 生活的花环:看雷加对文学的回顾
- 详解MTK系统中字符转换问题
- C#学习记录3上——类的封装,继承,多态
- 信息学奥赛一本通 1890:【15NOIP提高组】跳石头 | 洛谷 P2678 [NOIP2015 提高组] 跳石头
- 源码安装apache, jre, tomcat
- mysql备份-a是什么_MySQL主从备份和主主备份配置+Keepalived+MySQL读写分离
- 一张图学会python3语法-一张图理清 Python3 所有知识点
- java获取当月共有几天_Java计算当前月有多少天以及获取当前月开始以及结束日期...
- vue 面试题 前端面试题--vue 第六弹
- 利用unlocker在VMware里解锁macOS操作系统
- dbf格式转Excel(xls)格式教程
- 运行 Visual Studio 2019当前页面的脚本发生错误解决方法
- Kaggle时间序列(Time Series)教程 3-季节性(Seasonality)
- python实验总结与分析_Python实验报告七
- 商业图表案例8-全球十大电影成本收益
- 阿里云服务器学生机搭建及宝塔面板环境配置
- springboot+敬老院管理系统 毕业设计-附源码261535
热门文章
- java-php-python-ssm长庚游戏网站计算机毕业设计
- 网购图书java代码_基于JAVAEE网上购物系统(含源文件).doc
- 新型碎石破碎设备,鄂破机首居第一
- WKWebView的应用
- uml具有多种视图_UML的9种图及4+1视图简介(整理)
- NandFlash基础知识
- 任务2:常用的分词算法 I
- 20X47 FCPX模板悬挂翻转照片墙多张图片展示片头 Photo Grid Revealer
- VB与数据库结合开发全过程!
- 南京软博会·开源软件论坛丨盖国强:持续投身鲲鹏产业生态建设