一、服务器端开发时序图

  

  图片来源: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

  

四、参考资料

  1、Netty权威指南(李林峰)

Netty学习之服务器端创建的更多相关文章

  1. Netty学习之客户端创建

    一.客户端开发时序图 图片来源:Netty权威指南(第2版) 二.Netty客户端开发步骤 使用Netty进行客户端开发主要有以下几个步骤: 1.用户线程创建Bootstrap Bootstrap b ...

  2. Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明

    Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明 作者: Grey 原文地址: 博客园:Netty 学习(六):创建 NioEventLoopGroup 的核心源码说明 ...

  3. Netty 学习(七):NioEventLoop 对应线程的创建和启动源码说明

    Netty 学习(七):NioEventLoop 对应线程的创建和启动源码说明 作者: Grey 原文地址: 博客园:Netty 学习(七):NioEventLoop 对应线程的创建和启动源码说明 C ...

  4. Netty学习——Thrift的入门使用

    Netty学习——Thrift的入门使用 希望你能够,了解并使用它.因为它是一个效率很高的框架 官网地址:http://thrift.apache.org/ 1.Thrift数据类型 一门技术如果需要 ...

  5. Netty学习(4):NIO网络编程

    概述 在 Netty学习(3)中,我们已经学习了 Buffer 和 Channel 的概念, 接下来就让我们通过实现一个 NIO 的多人聊天服务器来深入理解 NIO 的第 3个组件:Selector. ...

  6. Netty学习笔记-入门版

    目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...

  7. Netty 学习 一、初识Netty【原创】

    在过去几年的工作和学习中,比较关注高层次的应用开发,对底层探究较少.实现Web应用的开发,主要依赖Tomcat.Apache等应用服务器,程序员无需了解底层协议,但同样限制了应用的性能和效率.现在开始 ...

  8. Netty学习笔记(二) 实现服务端和客户端

    在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...

  9. Netty 学习笔记(1)通信原理

    前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始.   Netty 的通信原理 Netty 底层 ...

随机推荐

  1. LCLFramework框架之IOC

    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 借助于"第三方"实现具有依赖关系的对象之间的解 ...

  2. 原创教程:SpagoBI4.2汉化及配置Mysql数据库教程

    SpagoBI4.2汉化及配置Mysql数据库教程 商务智能套件SpagoBI提供一个基于J2EE的框架用于管理BI对象如报表.OLAP分析.仪表盘.记分卡以及数据挖掘模型等的开源BI产品.它提供的B ...

  3. [emacs org-mode小技巧] org-indent-mode 让文档更容易阅读

    刚发现Emacs的org-mode里面一个叫做 org-indent-mode 的minor mode对于阅读org-mode文档很不错,版面看起来清晰多了: 从上图可以看到,org-indent-m ...

  4. session和jsessionid有什么关系

    首先,并不是说你一打开一个页面就会产生一个session. 所谓session你可以这样理解:当你与服务端进行会话时,比如说登陆成功后,服务端会为你开壁一块内存区间,用以存放你这次会话的一些内容,比如 ...

  5. android开发(49) android 使用 CollapsingToolbarLayout ,可折叠的顶部导航栏

    概述 在很app上都见过 可折叠的顶部导航栏效果.google support v7  提供了 CollapsingToolbarLayout 可以实现这个效果.效果图如下:    实现步骤 1. 写 ...

  6. Android Studio开发第四篇版本管理Git(下)

    前面一片介绍了在as下如何关联远程仓库,这篇就介绍在开发过程中怎么应用. 提交+Push 如果本地开发代码有改动了或者你觉得某功能做完了,你打算把改动代码提交到远程仓库,这个时候很简单, 还是在工具栏 ...

  7. NetBPM的安装 -转

    NetBPM的安装还是比较简单的,有比较详细的文档. 1.当然是先下载运行程序了, netbpm-0.8.3.1.zip ,官方网站:http://www.netbpm.org:2.然后解压后自己看 ...

  8. MVC5入门

    http://www.cnblogs.com/youring2/p/mvc-5-examining-the-edit-methods-and-edit-view.html

  9. 将main方法打成jar包,并引用第三方的maven jar包

    一.准备工作.执行命令 学习插件: 学习apache的打包插件maven-assembly-plugin:http://maven.apache.org/plugins/maven-assembly- ...

  10. php 使用zendstudio 生成webservice文件 wsdl

    首先新建一个项目 在项目中新建下面这些文件 php类文件 test.php <?php class test { public function __construct() { } public ...