IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Netty 专栏——I/O 模型 -> 正文阅读

[网络协议]Netty 专栏——I/O 模型

一、Netty介绍

Netty是由JBOSS提供的开源框架,是一个异步、基于事件驱动的网络应用框架,针对TCP协议下面向客户端的高并发应用、或Peer-To-Peer 场景下的大量数据传输的应用

二、IO模型

1、三种IO模型

就是用什么样的通道进行数据的发送和接收。
Java共支持三种网络编程模型I/O模式:BIO、NIO和AIO

  • 1)BIO(Blocking IO):同步阻塞,传统模式,服务器端实现模式为一个链接一个线程,即客户端有连接请求时,服务器端就需要启动一个线程进行处理,如果这个连接不做任何事就会造成不必要的线程开销,可以通过线程池机制改进,实现多个客户连接服务器;适用于连接数目较小且固定的框架,这种方式对服务器资源要求比较高,并发局限于应用中,多出现于JDK1.4以前的版本,但程序简单易理解。
  • 2)NIO:同步非阻塞,服务器端实现一个线程处理多个连接请求,即客户端发送的连接都会注册到多路复用器上,多路复用器轮询所有连接有I/O的请求进行处理,适用于连接数目多且连接较短的架构,比如聊天服务器、弹幕系统,服务器间通讯等;但编程比较复杂,需要JDK1.4以上版本的支持。
  • 3)AIO:异步非阻塞,引入了异步通道的概念,采用了Proactor模式,简化程序编写,有效的请求才启动线程,其特点为先由操作系统完成后才通知服务端程序启动线程去处理,一般用于连接数较多且连接时间较长的架构,如相册服务器,充分调用OS参与并发操作,编程比较复杂,需要JDK7以上版本的支持。

2、BIO工作机制

在这里插入图片描述

1)服务器启动ServerSocket
2)客户端启动ClientSocket,与服务器进行通讯,默认情况下服务器端需要对每个客户建立一个线程与之通讯
3)客户端发出请求后,先咨询是否有线程响应,若没有则会等待(阻塞)或被拒绝
4)如果线程有响应,客户端线程会等待(阻塞)请求结束后才继续执行
3、BIO示例
1)先创建一个线程池
2)如果有客户链接则创建线程与之通讯

public class Server {
    public static void main(String[] args) throws Exception{

        /*创建线程池*/
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();

        /*创建服务端套接字*/
        ServerSocket serverSocket = new ServerSocket(8001);

        System.out.println("Server Starting-----");

        while (true){
            /*监听,等待客户端连接*/
            Socket accept = serverSocket.accept();
            System.out.println("连接到一个客户端");

            /*创建线程与之通讯*/
            newCachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    /*与客户端通讯*/
                    handler(accept);
                }
            });

        }

    }
    /*通讯处理方法*/
    public static void handler(Socket socket){
        try{
            byte[] bytes = new byte[1024];
            /*通过socket获取输入流*/
            InputStream inputStream = socket.getInputStream();
            /*循环读取客户端发送的数据*/
            while (true){
                System.out.println("线程 ID:" + Thread.currentThread().getId() +
								      "名字:" + Thread.currentThread().getName());
                int read = inputStream.read(bytes);
                if(read!=-1){
                    System.out.println(new String(bytes, 0, read));
                }else{
                    break;
                }
            }

        }catch (Exception e){
            System.out.println(e.getMessage());
        }finally{
            System.out.println("关闭和client的连接");
            try {
                socket.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }

}

使用 telnet 127.0.0.1 8001 ,然后 Ctrl+] ,使用 send message 就可以向服务端发送数据。

Server Starting-----
连接到一个客户端
线程 ID:11名字:pool-1-thread-1
hello 100
线程 ID:11名字:pool-1-thread-1
连接到一个客户端
线程 ID:12名字:pool-1-thread-2
hello 200
线程 ID:12名字:pool-1-thread-2

三、NIO

Java NIO,即 non-blocking IO,JDK1.4以后开始支持,位于java.nio包下,有三大核心部件:Channel、Buffer 和 Selector;NIO 是面向缓冲区或数据块的编程,将数据先读取到一个缓冲区中,然后处理线程从缓冲区读取数据进行处理,实现非阻塞。Channel 对应一个buffer,用于支持读写。NIO 实现了一对多的连接处理,使得可以支持更多的客户端连接请求
在这里插入图片描述

selector会优先选取有IO请求的活跃的客户连接(通道)。

1、Buffer

1.1、Buffer 的四个重要属性

Buffer 有四个重要的属性:Capacity、Limit、Position 和 Mark

  • 1)Capacity:容量,在创建缓冲区时指定,并且之后不能更改,类似于静态数组。
  • 2)Limit:标识缓冲区的终点,不能对缓冲区超过极限的位置进行读写操作,允许进行修改
  • 3)Position:位置,写一个要被读或写的元素的索引,每次读写后数值会发生改变
  • 4)Mark 标记,调用Mark 来设置 position,在调用reset 可以让position恢复原来的位置

1.2、Buffer Demo

/**
	* Test how to use the buffer of the nio
	* @author 彭友聪
	*/
public class BufferTest {
    public static void main(String[] args) {
        /*create a int buffer with 5 capacity*/
        IntBuffer intBuffer = IntBuffer.allocate(5);

        /*storage data into the int buffer*/
        for(int i=0; i<intBuffer.capacity(); i++){
            intBuffer.put(i*2);
        }
        /*read data from the int buffer*/
        /*At first change the int buffer from write status to read status by the follow code*/
        intBuffer.flip();
        while (intBuffer.hasRemaining()){
            /*the get function can auto remove index to next one*/
            System.out.println(intBuffer.get());
        }
    }
}

1.3 NIO VS BIO

  • 1)BIO 以流的方式处理数据,NIO 则以数据块为单位进行处理,从而 NIO 的效率更高
  • 2)BIO 是阻塞的,NIO 是非阻塞的
  • 3)NIO 基于字节流和字符流进行操作,NIO 基于Channel 即通道和 Buffer 即缓冲区进行操作,数据总是从通道读取到缓冲区中,或相反,从缓冲区写入到通道中,Selector 用于监听多个通道中的事件,从而实现单个线程可以处理多个客户连接请求

2、Selector、Channel和Buffer之间的关系

在这里插入图片描述

  • 1)channel 和 buffer 一一对应
  • 2)selector 对应多个线程,一个线程对应多个channel
  • 3)程序切换到哪个Channel 由事件决定
  • 4)Selector 会根据不同的事件在不同的通道上进行切换
  • 5)Buffer 本质就是一个内存块(数组)
  • 6)数据的读取是通过Buffer进行,读写的切换需要使用flip进行操作
  • 7)Chann 也是双向非阻塞通道,可以反映底层操作系统的情况,比如Linux 底层的操作系统通道(epoll)就是双向的
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-09 12:01:41  更:2021-12-09 12:02:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:48:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码