Netty基础教程之服务器端创建,Netty基础教程之客

读书目录

阅读目录

  • 风度翩翩、客户端支出时序图
  • 二、Netty客商端支出步骤
  • 三、Netty顾客端支付示范代码
  • 四、仿效资料
  • 风流罗曼蒂克、服务器端开拓时序图
  • 二、Netty服务器端开辟步骤
  • 三、Netty服务器开荒示范代码
  • 四、参考资料

生机勃勃、客商端支出时序图

  图片 1

  图片源于:Netty权威指南(第2版)

风流罗曼蒂克、服务器端开辟时序图

  图片 2

  图片来源于:Netty权威指南(第2版)

二、Netty客商端支出步骤

  使用Netty实行客户端支付注重有以下几个步骤:

二、Netty服务器端开采步骤

  使用Netty实行劳动器端开拓入眼有以下多少个步骤:

  1、客户线程创立Bootstrap

Bootstrap b = new Bootstrap();

  Bootstrap是Socket客商端创造工具类,通过API设置成立顾客端相关的参数,异步发起客户端连接。

  1、创建ServerBootstrap实例

ServerBootstrap b=new ServerBootstrap();

  ServerBootstrap是Netty服务器端的开发银行帮忙类,提供了风度翩翩各类的艺术用于安装服务器端运转有关的参数。

  2、成立管理客商端连接、IO读写的Reactor线程组NioEventLoopGroup

EventLoopGroup group = new NioEventLoopGroup();

  2、设置并绑定Reactor线程池

EventLoopGroup bossGruop=new NioEventLoopGroup();//用于服务器端接受客户端的连接
EventLoopGroup workGroup=new NioEventLoopGroup();//用于网络事件的处理

  Netty的线程池是EventLoopGroup,它实质上是伊芙ntLoop的数组,EventLoop职分是拍卖全部注册到本线程多路复用器Selector上的Channel,Selector的轮询操作是由绑定的EventLoop线程run方法使得。

  3、通过Bootstrap的ChannelFactory和客户钦定的Channel类型创立用于顾客端连接的NioSocketChannel

b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)

  此处的NioSocketChannel类似于Java NIO提供的SocketChannel。

  3、设置并绑定服务器端Channel

b.group(bossGruop, workGroup).channel(NioServerSocketChannel.class)

  Netty对原生的NIO类库实行包装,作为NIO服务端,须求创立ServerSocketChannel,对应的兑现是NioServerSocketChannel。

  4、创立暗中认可的channel Handler pipeline

b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
 .handler(new ChannelInitializer<SocketChannel>()
  {
       @Override
       public void initChannel(SocketChannel ch) throws Exception
       {
         ch.pipeline().addLast(new HelloClientHandler());
        }
  });

  用于调治和试行网络事件。

  4、链路创建的时候创设并开始化ChannelPipeline

b.group(bossGruop, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>()

  ChannelPipeline的原形是二个负担处理网络事件的任务链,担当处理和实施ChannelHandler。互连网事件以事件流的花样在ChannelPipeline中流转,由ChannelPipeline依照Channel|Handler的举行政策调治ChannelHandler的推行。标准的互连网事件有:

  • 链路登记
  • 链路激活
  • 链路断开
  • 接到到伏乞新闻
  • 倡议新闻选择并管理达成
  • 发送应答新闻
  • 链路发出特别
  • 顾客自定义事件

  5、异步发起TCP连接

 // 发起异步连接操作
 ChannelFuture f = b.connect(host, port).sync();

  SocketChannel实行connect()操作后有以下两种结果:

  • 连接成功,然会true;
  • 临时并未有连接上,服务器端未有重临ACK应答,连接结果不分明,再次来到false。此种结果下,须求将NioSocketChannel中的selectionKey设置为OP_CONNECT,监听连接结果;
  • 一而再再而三受挫,直接抛出I/O非常

  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、由多路复用器在I/O中轮询个Channel,处理连接结果

  6、绑定并运转监听窗口

ChannelFuture f=b.bind(port).sync();

  经过大器晚成多元初阶化和检查实验工作后,会运行监听端口,并将ServerSocketChannel注册到Selector上监听顾客端连接

  7、假使一而再再而三成功,设置Future结果,发送连接成功事件,触发ChannelPipeline实行

  7、Selector轮询

  由Reactor线程NioEventLoop担负调治和实践Selector轮询操作,选取企图稳妥的Channel集合

  8、由ChannelPipeline调解推行系统和客商的ChannelHandler,试行工作逻辑

  8、当轮询到盘算妥贴的Channel之后,就由Reactor线程NioEventLoop实行ChannelPipeline的相应措施,最终调治并施行ChannelHandler

public class HelloServerHandler extends ChannelHandlerAdapter

三、Netty客商端支付示范代码

  供给:顾客端端达成,连接服务器端,并向劳动器端发送hello Netty。(注:本代码使用的netty是netty-all-5.0.0.Alpha1-sources.jar版本)

  服务器端代码见Netty学习之服务器端创制

  顾客端代码:

import io.netty.bootstrap.Bootstrap;
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.NioSocketChannel;

public class HelloClient
{
    public void connect(int port, String host) throws Exception
    {
        // 配置客户端NIO线程组
        EventLoopGroup group = new NioEventLoopGroup();
        try
        {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>()
                    {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception
                        {
                            ch.pipeline().addLast(new HelloClientHandler());
                        }
                    });

            // 发起异步连接操作
            ChannelFuture f = b.connect(host, port).sync();

            // 等待客户端链路关闭
            f.channel().closeFuture().sync();
        } finally
        {
            group.shutdownGracefully();
        }
    }
    public static void main(String[] args) throws Exception
    {
        int port = 8080;
        new HelloClient().connect(port, "127.0.0.1");
    }
}

 

 

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class HelloClientHandler  extends ChannelHandlerAdapter
{

    private final ByteBuf message;

    public HelloClientHandler()
    {
        byte[] req="hello Netty".getBytes();
        message=Unpooled.buffer(req.length);
        message.writeBytes(req);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception
    {
        ctx.writeAndFlush(message);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
    {
        ctx.close();
    }
}

  程序运营结果:

  图片 3

三、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模拟客商端输入,

  图片 4

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

  图片 5

四、参谋资料

  1、Netty权威指南(周丽娟峰)【Netty权威指南 PDF完整版带目录书签+源码 下载地址 http://www.linuxidc.com/Linux/2016-07/133575.htm 】

行使Spring评释落成Netty服务器端UDP应用程序  http://www.linuxidc.com/Linux/2013-09/89780.htm

Netty源码学习笔记 http://www.linuxidc.com/Linux/2013-09/89778.htm

Netty使用实例 http://www.linuxidc.com/Linux/2013-09/89779.htm

Java NIO框架--Netty4的简易示例  http://www.linuxidc.com/Linux/2015-01/111335.htm

Netty 的详实介绍:请点这里
**Netty 的下载地址**:请点这里

本文长久更新链接地址:http://www.linuxidc.com/Linux/2016-07/133585.htm

图片 6

四、参谋资料

  1、Netty权威指南(彭三源峰)【Netty权威指南 PDF完整版带目录书签+源码 下载地址 http://www.linuxidc.com/Linux/2016-07/133575.htm 】

运用Spring申明完成Netty服务器端UDP应用程序  http://www.linuxidc.com/Linux/2013-09/89780.htm

Netty源码学习笔记 http://www.linuxidc.com/Linux/2013-09/89778.htm

Netty使用实例 http://www.linuxidc.com/Linux/2013-09/89779.htm

Java NIO框架--Netty4的简要示例  http://www.linuxidc.com/Linux/2015-01/111335.htm

Netty 的详细介绍:请点这里
**Netty 的下载地址**:请点这里

正文永远更新链接地址:http://www.linuxidc.com/Linux/2016-07/133584.htm

图片 7

本文由华夏彩票发布于华夏彩票网络,转载请注明出处:Netty基础教程之服务器端创建,Netty基础教程之客

您可能还会对下面的文章感兴趣: