Netty学习之服务器端创建
一、服务器端开发时序图

图片来源:Netty权威指南(第2版)
二、Netty服务器端开发步骤
使用Netty进行服务器端开发主要有以下几个步骤:
1、创建ServerBootstrap实例
ServerBootstrap b=new ServerBootstrap();
ServerBootstrap是Netty服务器端的启动辅助类,提供了一系列的方法用于设置服务器端启动相关的参数。
2、设置并绑定Reactor线程池
EventLoopGroup bossGruop=new NioEventLoopGroup();//用于服务器端接受客户端的连接
EventLoopGroup workGroup=new NioEventLoopGroup();//用于网络事件的处理
Netty的线程池是EventLoopGroup,它实际上是EventLoop的数组,EventLoop职责是处理所有注册到本线程多路复用器Selector上的Channel,Selector的轮询操作是由绑定的EventLoop线程run方法驱动。
3、设置并绑定服务器端Channel
b.group(bossGruop, workGroup).channel(NioServerSocketChannel.class)
Netty对原生的NIO类库进行封装,作为NIO服务端,需要创建ServerSocketChannel,对应的实现是NioServerSocketChannel。
4、链路建立的时候创建并初始化ChannelPipeline
b.group(bossGruop, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>()
ChannelPipeline的本质是一个负责处理网络事件的职责链,负责管理和执行ChannelHandler。网络事件以事件流的形式在ChannelPipeline中流转,由ChannelPipeline根据Channel|Handler的执行策略调度ChannelHandler的执行。典型的网络事件有:
- 链路注册
- 链路激活
- 链路断开
- 接收到请求信息
- 请求信息接收并处理完毕
- 发送应答消息
- 链路发生异常
- 用户自定义事件
5、添加并设置ChannelHandler
b.group(bossGruop, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>()
{
@Override
protected void initChannel(SocketChannel arg0) throws Exception
{
arg0.pipeline().addLast(new HelloServerHandler()); }
}).option(ChannelOption.SO_BACKLOG, 1024);
ChannelHandler是Netty提供给用户定制和扩展的接口,例如消息编解码、心跳、安全认证、TSL/SSL认证
6、绑定并启动监听窗口
ChannelFuture f=b.bind(port).sync();
经过一系列初始化和检测工作后,会启动监听端口,并将ServerSocketChannel注册到Selector上监听客户端连接
7、Selector轮询
由Reactor线程NioEventLoop负责调度和执行Selector轮询操作,选择准备就绪的Channel集合
8、当轮询到准备就绪的Channel之后,就由Reactor线程NioEventLoop执行ChannelPipeline的相应方法,最终调度并执行ChannelHandler
public class HelloServerHandler extends ChannelHandlerAdapter
三、Netty服务器开发示例代码
需求:服务器端实现,每连接一个客户端,在服务器控制台打印客户端输入的字符。(注:本代码使用的netty是netty-all-5.0.0.Alpha1-sources.jar版本)
服务器端代码如下:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
//Netty服务器端
public class HelloServer
{
private int port; public HelloServer(int port)
{
super();
this.port = port;
}
private void bind() throws InterruptedException
{
EventLoopGroup bossGruop=new NioEventLoopGroup();//用于服务器端接受客户端的连接
EventLoopGroup workGroup=new NioEventLoopGroup();//用于网络事件的处理
try
{
ServerBootstrap b=new ServerBootstrap();
b.group(bossGruop, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>()
{
@Override
protected void initChannel(SocketChannel arg0) throws Exception
{
arg0.pipeline().addLast(new HelloServerHandler()); }
}).option(ChannelOption.SO_BACKLOG, 1024);//指定此套接口排队的最大连接个数
ChannelFuture f=b.bind(port).sync();
f.channel().closeFuture().sync();
}
finally
{
bossGruop.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException
{
new HelloServer(8080).bind();
}
}
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; //自定义的ChannelHandler
public class HelloServerHandler extends ChannelHandlerAdapter
{
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
{
System.out.println("客户端连上了...");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
{
ByteBuf buf=(ByteBuf) msg;
byte[] req=new byte[buf.readableBytes()];
buf.readBytes(req);
System.out.println("服务器端接收的消息:"+new String(req));
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
{
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
{
ctx.close();
}
}
客户端:使用telnet模拟客户端输入,

按住“ctrl+]”,然后输入指令send a

四、参考资料
Netty学习之服务器端创建的更多相关文章
- Netty学习之客户端创建
一.客户端开发时序图 图片来源:Netty权威指南(第2版) 二.Netty客户端开发步骤 使用Netty进行客户端开发主要有以下几个步骤: 1.用户线程创建Bootstrap Bootstrap b ...
- Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明
Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明 作者: Grey 原文地址: 博客园:Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明 ...
- Netty 学习(七):NioEventLoop 对应线程的创建和启动源码说明
Netty 学习(七):NioEventLoop 对应线程的创建和启动源码说明 作者: Grey 原文地址: 博客园:Netty 学习(七):NioEventLoop 对应线程的创建和启动源码说明 C ...
- Netty学习——Thrift的入门使用
Netty学习——Thrift的入门使用 希望你能够,了解并使用它.因为它是一个效率很高的框架 官网地址:http://thrift.apache.org/ 1.Thrift数据类型 一门技术如果需要 ...
- Netty学习(4):NIO网络编程
概述 在 Netty学习(3)中,我们已经学习了 Buffer 和 Channel 的概念, 接下来就让我们通过实现一个 NIO 的多人聊天服务器来深入理解 NIO 的第 3个组件:Selector. ...
- Netty学习笔记-入门版
目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...
- Netty 学习 一、初识Netty【原创】
在过去几年的工作和学习中,比较关注高层次的应用开发,对底层探究较少.实现Web应用的开发,主要依赖Tomcat.Apache等应用服务器,程序员无需了解底层协议,但同样限制了应用的性能和效率.现在开始 ...
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
随机推荐
- 判断big endian和little endian的方法
http://blog.sina.com.cn/s/blog_6ab0b9a80101awzr.html 不同体系的CPU在内存中的数据存储往往存在着差异.例如,Intel的x86系列处理器将低序 ...
- nlog(n)解动态规划--最长上升子序列(Longest increasing subsequence)
最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n). 具体分析参考:http://b ...
- 基于Multisim的buck降压斩波电路仿真
和boost电路相反,buck电路为DC-DC降压电路,搞了一下仿真发现低压情况下降压效率比較高,电压略微高一点降压效率就不敢恭维了. .不知道是怎么回事 仿真电路: 占空比D设置了0.5, U0=U ...
- WCF中因序列化问题引起的异常和错误。
尝试对参数 http://tempuri.org/ 进行序列化时出错: parameters.InnerException 消息是“不应为数据协定名称为“DBNull:http://schemas.d ...
- 使用Highcharts实现图表展示
本篇随笔记录的是本人2011年做广州地铁协同办公项目时,图表需求的解决方案.(Demo中只是虚拟的测试数据) 关键技术点: 使用Highcharts实现图表展示: 另外使用Highslide弹窗.使用 ...
- 华为 HG8245C 光猫 修改无线用户数限制+hw_ctree.xml 文件解密
这个操作方法是 从网上其他人提供的方法 和我一个朋友总结出来的,我只是负责整理,并实地在我自己的光猫上操作成功了 风险提示 :刷机有风险,操作需谨慎, 备份备份备份! 俺家,俺的新家是电信光纤接入, ...
- MVC自定义视图规则
自定义规则: using System.Web.Mvc; using System.Configuration; namespace Research { public class ViewConfi ...
- SVN分支与合并
分支的基本概念就正如它的名字,开发的一条线独立于另一条线,如果回顾历史,可以发现两条线分享共同的历史,一个分支总是从一个备份开始的,从那里开始,发展自己独有的历史(如下图所示) ⑴创建分支 假设目前我 ...
- css hack 整理
<ul> <li>"_" ------ IE6</li> <li>"-" ------ IE6</li&g ...
- 未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序
在C#的web程序中读取服务器端的Excel文件时所报的异常 问题描述:在Visual Studio中运行.调试均没有问题,但是部署到Windows Server 2008 64位操作系统的IIS7 ...