Netty笔记之基本介绍与Socket联系

作者:叁念



本系列是学习慕课网相关视频所整理的笔记,无关盈利,如有侵权,请即时联系删除!
借鉴博客: https://blog.csdn.net/chenssy/article/details/78703551

一 、Netty是什么?

◆ 异步事件驱动框架用于快速开发高性能服务端和客户端
◆ 封装了JDK底层BIO和NIO模型,提供高度可用的API
◆ 自带编解码器解决拆包粘包问题,用户只用关心业务逻辑
◆ 精心设计的reactor线程模型支持高并发海量连接
◆ 自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手

二、实现一个Socket通信

来理解Netty我们首先看一下Socket是如何实现通信的,然后我们跟着Socket的实现思路来讨论我们的Netty:
本文代码所在地址为:
子项目项目名称为:netty_1

首先建立你的服务端 MySocketServer

public class MySocketServer {

    private ServerSocket serverSocket;

    public static void main(String[] args) {
        MySocketServer server = new MySocketServer(8000);
        server.start();
    }

    public MySocketServer(int port) {
        try {
            this.serverSocket = new ServerSocket(port);
            System.out.println("MySocketServer服务端启动成功! 端口:" + port);
        } catch (IOException exception) {
            System.out.println("MySocketServer服务端启动失败!");
        }
    }

    /**
     * 开启服务端主线程,用于接收客户端连接
     * 并为客户端创建其独有的新Handler处理线程,防止堵塞
     */
    private void start() {
        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        Socket client = serverSocket.accept();
                        new MyClientHandler(client).start();
                    } catch (IOException e) {
                        System.out.println("服务端异常!");
                    }
                }
            }
        }).start();
    }
}

建立专用于服务器处理客户端的Handler处理器 MyClientHandler

public class MyClientHandler {

    public static final int MAX_DATA_LEN = 1024;
    private final Socket socket;

    public MyClientHandler(Socket socket) {
        this.socket = socket;
    }

    public void start() {
        System.out.println("新客户端接入");
        new Thread(new Runnable() {
            public void run() {
                doStart();
            }
        }).start();
    }

    private void doStart() {
        try {
            InputStream inputStream = socket.getInputStream();
            while (true) {
                byte[] data = new byte[MAX_DATA_LEN];
                int len;
                while ((len = inputStream.read(data)) != -1) {
                    String message = new String(data, 0, len);
                    System.out.println("从客户端 " + socket.getLocalPort()+" 接收数据: " + message);
                    socket.getOutputStream().write(data);
                }

            }


        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

启动服务器你可以看到如下,说明服务器启动成功了,服务器会为每个客户端分配一个Handler来处理数据,互不干扰

Netty笔记之基本介绍与Socket联系_第1张图片

接下来建立客户端 MySocketClient 来进行连接

public class MySocketClient {

    private static final String HOST = "127.0.0.1";
    private static final int PORT = 8000;
    private static final int SLEEP_TIME = 5000;

    public static void main(String[] args) throws IOException {
        final Socket socket = new Socket(HOST, PORT);

        new Thread(new Runnable() {
            public void run() {
                System.out.println("客户端启动成功!");
                while (true) {
                    try {
                        String message = "Netty笔记之基本介绍与Socket联系!";
                        System.out.println("客户端发送数据: " + message);
                        socket.getOutputStream().write(message.getBytes());
                    } catch (Exception e) {
                        System.out.println("写数据出错!");
                    }
                    sleep();
                }


            }
        }).start();

    }

    /**
     * 线程睡眠5秒钟发送一次数据
     */
    private static void sleep() {
        try {
            Thread.sleep(SLEEP_TIME);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

启动客户端,客户端的作用就是链接服务器发送数据,我们定义了每5秒钟就像服务器发送一次数据,如下:

Netty笔记之基本介绍与Socket联系_第2张图片

此时可以给发现服务器接收到消息,如下:

Netty笔记之基本介绍与Socket联系_第3张图片

到这里你应该能明白作为Socket是在吗进行通讯的了,基于原生的Socket我这里写了一个简单的GUI即时聊天器,有兴趣的可以下载了解更多

三、理解Netty与Socket通信的一些区别与联系

如果你了解了以上Socket是如何实现连接通讯的,你就能很好的理解Netty所对应相关类的功能,这里我们可以来看一下网上的一幅图片,来对比一下
Netty笔记之基本介绍与Socket联系_第4张图片

四、Netty的一些组件介绍

  • Channel

网络操作抽象类,它除了包括基本的 I/O 操作,如 bind、connect、read、write 之外,还包括了 Netty 框架相关的一些功能,如获取该 Channe l的 EventLoop
当一个连接到达时,Netty 就会注册一个 Channel,然后从 EventLoopGroup 中分配一个 EventLoop 绑定到这个Channel上,在该Channel的整个生命周期中都是有这个绑定的 EventLoop 来服务的

  • ChannelFuture

Netty 为异步非阻塞,即所有的 I/O 操作都为异步的,因此,我们不能立刻得知消息是否已经被处理了,通过该接口的 addListener() 方法注册一个 ChannelFutureListener,当操作执行成功或者失败时,监听就会自动触发返回结果

  • EventLoop

主要是为Channel 处理 I/O 操作

  • ChannelHandler

Netty 中最核心的组件,它充当了所有处理入站和出站数据的应用程序逻辑的容器。
ChannelHandler 主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等,有两个核心子类 ChannelInboundHandler 和 ChannelOutboundHandler
其中 ChannelInboundHandler 用于接收、处理入站数据和事件,而 ChannelOutboundHandler 则相反

  • ChannelPipeline

ChannelPipeline 为 ChannelHandler 链提供了一个容器并定义了用于沿着链传播入站和出站事件流的 API。
一个数据或者事件可能会被多个 Handler 处理,在这个过程中,数据或者事件经流 ChannelPipeline,由 ChannelHandler 处理。在这个处理过程中,一个 ChannelHandler 接收数据后处理完成后交给下一个 ChannelHandler,或者什么都不做直接交给下一个 ChannelHandler
当一个数据流进入 ChannlePipeline 时,它会从 ChannelPipeline 头部开始传给第一个ChannelInboundHandler ,当第一个处理完后再传给下一个,一直传递到管道的尾部。与之相对应的是,当数据被写出时,它会从管道的尾部开始,先经过管道尾部的 “最后” 一个ChannelOutboundHandler,当它处理完成后会传递给前一个 ChannelOutboundHandler

你可能感兴趣的:(Netty)