Netty核心技术二--BIO编程

news2024/9/21 1:44:55

1. I/O模型

  1. I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收很大程度上决定了程序通信的性能

  2. Java共支持3种网络编程模型/IO模式:BIONIOAIO

  3. Java BIO同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销

    image-20230512165651728

  4. Java NIO同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器,多路复用器轮询到连接有I/O请求就进行处理

    image-20230512165853634

  5. Java AIO(NIO.2)异步非阻塞,AIO 引入异步通道的概念,采用了Proactor 模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程,一般适用于连接数较多,连接时间较长的应用

2. BIO,NIO,AIO适用场景分析

  1. BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序简单易理解。
  2. NIO方式适用于==连接数目多且连接比较短(轻操作)==的架构,比如聊天服务器弹幕系统服务器间通讯等。编程比较复杂,JDK1.4开始支持
  3. AIO方式使用于==连接数目多且连接比较长(重操作)==的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持

3. JAVA BIO 基本介绍

  1. Java BIO 就是传统的java io 编程,其相关的类和接口在java.io
  2. BIO(blocking I/O) : 同步阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器)。
  3. BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,程序简单易理解

4. JAVA BIO 工作机制

4.1 工作原理图

image-20230512170932098

4.2 BIO编程简单流程

  1. 服务器端启动一个ServerSocket
  2. 客户端启动Socket对服务器进行通信,默认情况下服务器端需要对每个客户建立一个线程与之通讯
  3. 客户端发出请求后, 先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝
  4. 如果有响应,客户端线程会等待请求结束后,在继续执行

5. Java BIO 应用实例 &telnet基本使用

实例说明:

  1. 使用BIO模型编写一个服务器端,监听6666端口,当有客户端连接时,就启动一个线程与之通讯。
  2. 要求使用线程池机制改善,可以连接多个客户端.
  3. 服务器端可以接收客户端发送的数据(telnet 方式即可)。
package site.zhourui.nioAndNetty.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BIOServer {
    public static void main(String[] args) throws IOException {
        //线程池机制

        //思路
        //1. 创建一个线程池
        //2. 如果有客户端连接,就创建一个线程,与之通讯(单独写一个方法)
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        //创建ServerSocket
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("服务器启动了");

        while (true){
            System.out.println("线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
            System.out.println("等待连接...");
            Socket socket = serverSocket.accept();
            System.out.println("连接到一个客户端");
            //就创建一个线程,与之通讯(单独写一个方法)
            newCachedThreadPool.execute(()->{ //我们重写
                //可以和客户端通讯
                handle(socket);
            });



        }
    }

    private static void handle(Socket socket)  {
        try {
            System.out.println("线程信息 id =" + Thread.currentThread().getId() + " 名字=" + Thread.currentThread().getName());
            System.out.println("read....");
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            while (true){
                int read = inputStream.read(bytes);
                if (read!=-1){
                    System.out.println(new String(bytes,0,read)); //输出客户端发送的数据
                }else {
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println("关闭和client的连接");
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
  1. 启动服务器

    服务端等待客户端连接

    image-20230514101416436

  2. 使用cmd连接服务端

    telnet 127.0.0.1 6666
    

    image-20230512181847420

  3. 第一步回车后出现以下页面

    image-20230512181932809

    服务端日志显示连接到一个客户端,启动了一个线程id为20的线程阻塞等待客户端发送信息,之后id为1的线程(main线程)又再次阻塞等待新的客户端连接

    image-20230514101234705

  4. 使用快捷键:CTRL+] 显示欢迎页面

    image-20230512182019468

  5. 输入?输出帮助文档

    image-20230512182212801

  6. 使用send 命令发送字符串到服务器

    image-20230512182439517

  7. cmd再次连接一个客户端,id为1的线程(main线程)再次了一个线程id为20的线程阻塞等待客户端发送信息,之后id为1的线程又再次阻塞等待新的客户端连接

    image-20230514101853945

6. BIO 问题分析-总结

  1. 每个请求都需要创建独立的线程,与对应的客户端进行数据Read,业务处理,数据 Write 。
  2. 当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。
  3. 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 Read 操作上,造成线程资源浪费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/548022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++每日一练:饿龙咆哮-逃离城堡(避坑指南)非负整数求和

文章目录 前言一、题目二、解题代码及思路1、思路2、代码 三、非负整数求和总结 前言 饿龙这一题要说难度嘛,还真是挺简单的,但要满分也是有坑的!本文就记录了笔者解题过程,希望能对读者使用C编程有所启发。至于非负整数求和代码…

RocketMQ集群环境部署

文章目录 1. 准备环境2. 修改主机名3. 免密登录配置4. 配置RocketMQ集群5. 搭建RocketMQ集群6. 启动集群 1. 准备环境 准备好三台虚拟机,下面是我的虚拟机的一些基本信息 名称ip地址worker010.117.33.135worker110.117.39.202worker210.117.9.52 三台虚拟机都已经…

Windows下nginx的配置与启动

一,下载 http://nginx.org/,打开官网,点击download 选择下载稳定版 二,解压 1,解压到硬盘某个目录 2,由于80端口被占用,于是我要修改conf目录下的nginx.conf文件 查看端口是否被占用 net…

路径规划算法:基于蝴蝶算法的路径规划算法- 附代码

路径规划算法:基于蝴蝶优化的路径规划算法- 附代码 文章目录 路径规划算法:基于蝴蝶优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法蝴蝶…

【C++】类和对象(上):带你速度了解什么是类,如何定义类!!

前言: 前面我们学习C一些基础的内容,也可以说C针对C语言的缺陷进行改进。而今天我们要学的是C的内容也就是类和对象。 一、初识类: 我们先来看看C语言解决一个问题的过程: 假设有以下这个场景:你需要手洗一件衣服&am…

算法Day09 | KMP,28. 实现 strStr() ,459.重复的子字符串

Day09 KMP28. 实现 strStr()459.重复的子字符串 KMP KMP是三个人人名缩写,用于在文本字符串text中搜索pattern字符串,返回在text中第一出现的位置。 算法做法就是在暴力匹配的基础上加速匹配。通过对pattern字符串求next数组(该数组也成为前缀表)&#…

element ui 表格内嵌图片预览展示样式问题 (element plus)

❤️砥砺前行,不负余光,永远在路上❤️ 目录 前言一、问题二、解决 前言 一、问题 二、解决 添加上preview-teleported 属性即可。

ChatGPT ✖️ 前端 = 有点er意思

HOT! HOT! HOT! 🔥 🔥 🔥 ChatGPT登上了国内各大平台的热搜榜,应该在去年11月末的时候就有不少同学了解并使用过,那个时候它刚刚问世,在互联网圈子里有了很大的热度,但是对于大众来说&#xff…

OpenGLES读写图像数据(内存与GPU)——使用PBO

一、什么是PBO 在 OpenGL 开发中,特别是在低端平台上处理高分辨率的图像时,图像数据在内存和显存之前拷贝往往会造成性能瓶颈,而利用 PBO 可以在一定程度上解决这个问题。 PBO (Pixel Buffer Object)是 OpenGL ES 3.…

iOS开发提效cocoapods插件cocoapods-util

cocoapods-util介绍 cocoapods-util是一个iOS开发提效的cocoapods插件。 取名util的原因是我想做一个通用的插件,把一些iOS中常用的命令或问题整理起来。 插件中除了package命令是根据cocoapods-packager插件做了修改而来,其余命令都是属于自己总结开…

uwb高精度定位系统源码 UWB高精度定位技术原理与实现

uwb高精度定位系统 UWB高精度定位技术原理与实现 近些年物联网产业高速发展,越来越多的物联网终端连上了网络,实现了人与物,甚至物与物之间的互连互通。随着智能化要求的进一步提高和物联网应用的进一步拓展,除了互联互通&#x…

Doxygen源码分析:doxygen执行过程的拆解

Doxygen源码分析:doxygen执行过程的拆解 2023-05-19 23:09:17 ~ 2023-05-20 16:38:13 ChrisZZ imzhuofoxmailcom Hompage https://github.com/zchrissirhcz 文章目录 Doxygen源码分析:doxygen执行过程的拆解1. doxygen 版本2. doxygen 可执行程序的入口…

System V方案 — 共享内存

目录 System V方案 — 详述共享内存共享内存共享内存的原理共享内存数据结构共享内存函数实例 消息队列消息队列数据结构消息队列函数创建删除 信号量信号量数据结构信号量函数创建删除 进程互斥 总结 System V方案 — 详述共享内存 SystemV标准的进程间通信方式,是…

【react 全家桶】react-Hook(上)

本人大二学生一枚&#xff0c;热爱前端&#xff0c;欢迎来交流学习哦&#xff0c;一起来学习吧。 <专栏推荐> &#x1f525;&#xff1a;js专栏 &#x1f525;&#xff1a;vue专栏 &#x1f525;&#xff1a;react专栏 文章目录 14【react-Hook &#xff08;上&#x…

计算机网络基础知识(六)—— 什么是HTTP协议?你听我说

文章目录 01 | 基本概念02 | 工作原理 && 特点03 | URI && URL04 | 消息结构05 | 请求方法06 | http响应头信息07 | 状态码08 | HTTP的常见安全机制09 | HTTP的缓存机制10 | HTTP/2 && HTTP/3新特性11 | 面试中常见问题 超文本传输协议&#xff08;Hyp…

【前端知识】Cookie, Session,Token和JWT的发展及区别(四)

【前端知识】Cookie, Session,Token和JWT的发展及区别&#xff08;四&#xff09; 9. JWT9.1 JWT的背景及定义&#xff08;1&#xff09;JWT的字面理解&#xff08;2&#xff09;JWT与传统Token的区别 9.2 JWT的组成&#xff08;1&#xff09; Header&#xff08;头部&#xff…

【UDS】诊断故障代码老化机制

文章目录 简介相关术语1. 老化计数器 Ageing counter2. 诊断故障代码已老去 DTC aged3. 已老去计数器 Aged counter4. 操作循环 Operation cycle5. 诊断故障代码老化机制 DTC aging mechanism 总结 ->返回总目录<- 简介 诊断故障代码&#xff08;DTC&#xff09;一旦生…

【IDEA使用指南】使用Hibernate框架的Java项目,如何找到并打开 “Import Database Schema”窗口?

【IDEA使用指南】使用Hibernate框架的Java项目&#xff0c;如何找到并打开 “Import Database Schema”窗口&#xff1f; 背景&#xff1a; 使用 Hibernate 框架时&#xff0c;假如在 “Import Database Schema” 窗口&#xff08;如下图所示&#xff09;时&#xff0c;点击了…

day06_Java中的流程控制语句

流程控制 简单来讲所谓流程就是完成一件事情的多个步骤组合起来就叫做一个流程。在一个程序执行的过程中&#xff0c;各条语句的执行顺序对程序的结果是有直接影响的。我们必须清楚每条语句的执行流程。而且&#xff0c;很多时候要通过控制语句的执行顺序来实现我们想要的功能…