程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Netty學習之客戶端創建,netty客戶端創建

Netty學習之客戶端創建,netty客戶端創建

編輯:JAVA綜合教程

Netty學習之客戶端創建,netty客戶端創建


一、客戶端開發時序圖

  

  圖片來源:Netty權威指南(第2版)

二、Netty客戶端開發步驟

  使用Netty進行客戶端開發主要有以下幾個步驟:

  1、用戶線程創建Bootstrap

Bootstrap b = new Bootstrap();

  Bootstrap是Socket客戶端創建工具類,通過API設置創建客戶端相關的參數,異步發起客戶端連接。

  2、創建處理客戶端連接、IO讀寫的Reactor線程組NioEventLoopGroup

EventLoopGroup group = new NioEventLoopGroup();

  3、通過Bootstrap的ChannelFactory和用戶指定的Channel類型創建用於客戶端連接的NioSocketChannel

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

  此處的NioSocketChannel類似於Java NIO提供的SocketChannel。

  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());
        }
  });

  用於調度和執行網絡事件。

  5、異步發起TCP連接

 // 發起異步連接操作
 ChannelFuture f = b.connect(host, port).sync();

  SocketChannel執行connect()操作後有以下三種結果:

  • 連接成功,然會true;
  • 暫時沒有連接上,服務器端沒有返回ACK應答,連接結果不確定,返回false。此種結果下,需要將NioSocketChannel中的selectionKey設置為OP_CONNECT,監聽連接結果;
  • 接連失敗,直接拋出I/O異常

  6、由多路復用器在I/O中輪詢個Channel,處理連接結果

  7、如果連接成功,設置Future結果,發送連接成功事件,觸發ChannelPipeline執行

  8、由ChannelPipeline調度執行系統和用戶的ChannelHandler,執行業務邏輯

三、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();
    }
}

  程序運行結果:

  

四、參考資料

  1、Netty權威指南

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved