java BIO深入学习

一、BIO的工作原理

传统Io(BIO)的本质就是面向字节流来进行数据传输的
在这里插入图片描述
①:当两个进程之间进行相互通信,我们需要建立一个用于传输数据的管道(输入流、输出流),原来我们传输数据面对的直接就是管道里面一个个字节数据的流动(我们弄了一个 byte 数组,来回进行数据传递),所以说原来的 IO 它面对的就是管道里面的一个数据流动,所以我们说原来的 IO 是面向流的
②:我们说传统的 IO 还有一个特点就是,它是单向的。解释一下就是:如果说我们想把目标地点的数据读取到程序中来,我们需要建立一个管道,这个管道我们称为输入流。相应的,如果如果我们程序中有数据想要写到目标地点去,我们也得再建立一个管道,这个管道我们称为输出流。所以我们说传统的 IO 流是单向的

二、传统的BIO编程实例回顾

网络编程的基本模型是C/S(客户端/服务器端)模型,也就是两个进程之间的通讯,其中服务端提供位置信(绑定ip地址和端口),客户端通过连接操作向服务器端监听的端口地址发起连接请求,基于TCP协议下进行三次握手连接,连接成功后,双方进行socket通讯。
传统的同步阻塞模型开发中,服务端ServerSocket负责绑定ip地址,启动监听端口;客户端Socket负责发起连接操作。连接成功之后,双方通过输入和输出流进行同步阻塞式通信。
基于BIO模式下的通讯,客户端-服务器端是完全同步,完全耦合的。
服务器端代码

public class Server {
    public static void main(String[] args) {
        try {
            System.out.append("服务器端启动。。。");
            //1.定义ServerSocket对象进行服务端的端口注册
            ServerSocket serverSocket = new ServerSocket(8080);
            //2.监听客户端的Socket连接程序
            Socket socket = serverSocket.accept();
            //3.从socket对象当中获取到一个字节输入流对象
            InputStream iStream = socket.getInputStream();
            //打印输出
            int len = 0;
            int ReviceLen = 0;
            //计算机网络数据是以8bit为一个单元进行发送,我们接收到发送方发送的byte数据
            //将其转化为utf-8的格式进行输出
            byte[] recvBuf = new byte[1024];
            while ((ReviceLen = iStream.read(recvBuf)) != -1) {
                System.out.println("  客户端说:"
                        + new String(recvBuf, 0, ReviceLen, "UTF-8"));
            }
        } catch (Exception e) {

        }
    }
}

客户端代码

public class Client {
    public static void main(String[] args) throws Exception {
        //1.创建socket对象请求服务器的连接
        Socket socket = new Socket("127.0.0.1",8080);
        //2.从socket对象中获取一个字节输出流、
        OutputStream oStream = socket.getOutputStream();
        oStream.write(("你好服务器").getBytes());//以字节流的形式发送数据
        //4.关闭
        oStream.flush();
    }
}

三、BIO模式下的多发和多收消息

服务器端不变,客户端:

public class Client {
    public static void main(String[] args) throws Exception {
        //1.创建socket对象请求服务器的连接
        Socket socket = new Socket("127.0.0.1",8080);
        //2.从socket对象中获取一个字节输出流、
        OutputStream oStream = socket.getOutputStream();
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("请说....");
            String message = scanner.nextLine();
            oStream.write(message.getBytes());
            //4.关闭
            oStream.flush();
        }
    }
}

在这里插入图片描述
在这里插入图片描述

四、BIO模式下接收多个客户端

在上述的案例当中,一个服务端只能接收一个客户端的通信请求,那么如果服务端需要处理很多个客户端的消息通讯请求应该如何处理呢?

当我们启动两个客户端,分别去访问服务器端的时候,我们发现服务器端只连接了一个客户端,并且只能和一个客户端进行通信。
在这里插入图片描述
在这里插入图片描述

什么原因导致了我们服务器只能链接一个客户端

在这里插入图片描述

那如何解决呢?

此时就需要在服务端引入线程了,也就是说客户端发起一次请求,服务端就会创建一个新的线程来处理一个新的线程来处理这个客户端的请求,这样就实现了一个客户端一个线程的模型,图解如下:
在这里插入图片描述

服务器端改进代码

public class Server {
    public static void main(String[] args) {
        try {
            System.out.append("服务器端启动。。。");
            //1.定义ServerSocket对象进行服务端的端口注册
            ServerSocket serverSocket = new ServerSocket(8080);
            while (true){
                //2.监听客户端的Socket连接程序
                Socket socket = serverSocket.accept();
                //创建一个独立的线程来处理也客户端的Socket请求
                new ServerThreadReader(socket).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class ServerThreadReader extends Thread {
    private Socket socket;

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

    @Override
    public void run() {
        //3.从socket对象当中获取到一个字节输入流对象
        try {
            InputStream iStream = socket.getInputStream();
            //打印输出
            int len = 0;
            int ReviceLen = 0;
            //计算机网络数据是以8bit为一个单元进行发送
            byte[] recvBuf = new byte[1024];
            while ((ReviceLen = iStream.read(recvBuf)) != -1) {
                System.out.println("  客户端说:"
                        + new String(recvBuf, 0, ReviceLen, "UTF-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
小结

1.每个socket接受到,都会床架一个新的线程,线程的竞争、切换上下文影响性能。
2.每个线程都会占用栈空间和cpu资源
3.并不是每一个socket都进行IO操作,无意义的线程处理
4.客户端的并发访问增加时。服务端将呈现1:1的线程开销,访问量越大,系统将发生线程
   栈溢出,线程创建失败,最终导致进程宕机或僵死,从而不能对外提供服务

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

违背祖训,微软骚操作强制用户更新至 Win 11 23H2

话说,大伙儿有让 Windows 操作系统一直保持最新版习惯吗? 根据以往惯例,Windows 系统更新是个比较玄学的存在,谁也不能保证随手更新后会不会出现什么奇葩 Bug。 因此对于不少同学来说,Windows 更新到一个稳定版本后&a…

【两颗二叉树】【递归遍历】【▲队列层序遍历】Leetcode 617. 合并二叉树

【两颗二叉树】【递归遍历】【▲队列层序遍历】Leetcode 617. 合并二叉树 解法1 深度优先 递归 前序解法2 采用队列进行层序遍历 挺巧妙的可以再看 ---------------🎈🎈题目链接🎈🎈------------------- 解法1 深度优先 递归 前…

【GPU驱动开发】- mesa编译与链接过程详细分析

前言 不必害怕未知,无需恐惧犯错,做一个Creator! 一、总体框架图 暂时无法在飞书文档外展示此内容 二、Mesa API 处理 OpenGL 函数调用 Mesa API 负责实现 OpenGL 和其他图形 API 的函数接口。Mesa API 表是一个重要的数据结构&#xf…

密码学在 Web3 钱包中的应用:私钥是什么?bitget钱包为例

在非对称加密演算法中,私钥是一串随机生成的数字,通常以十六进制数表示(也就是由0、1、2、3、4、5、6、7、8、9、a、b、c、d、e和f组成)。私钥生成后,这串数字被作为一个单向数学函数中的输入值,计算产生的…

如何在nginx上设置html不缓存

一、简介 前端项目发布以后,经常会遇到访问不到最新的版本,这主要是由于我们项目的入口文件index.html被浏览器或者代理缓存了,没有实时拉取到最新文件。本文将介绍一下在nginx上如何设置html文件不缓存。 二、Cache-Control介绍 2.1 服务…

GEE入门篇|图像处理(一):理论介绍

光谱指数是基于地球表面不同的物体和土地覆盖反射不同波长的不同数量的太阳光的事实。例如,在光谱的可见部分,健康的绿色植物反射大量的绿光,同时吸收蓝光和红光——这就是为什么它在我们的眼中是绿色的。来自太阳的光的波长也超出了人眼所能…

aiohttp 目录遍历漏洞复现(CVE-2024-23334)

0x01 产品简介 aiohttp是一个用于异步网络编程的Python库,支持客户端和服务器端的网络通信。它利用Python的asyncio库来实现异步IO操作,这意味着它可以处理大量并发网络连接,而不会导致线程阻塞或性能下降。aiohttp常用于需要高性能网络通信的应用程序,如高频交易平台、大…

数据分析-Pandas数据探查初步柱状图

数据分析-Pandas数据探查初步柱状图 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表&am…

单宽GPU卡和双宽GPU卡是什么意思?

问题描述: 单宽GPU卡和双宽GPU卡是什么意思? 解答: 单宽GPU卡和双宽GPU卡是指安装在计算机中的不同尺寸的图形处理单元(GPU)卡。 单宽GPU卡通常是一张标准尺寸的PCIe扩展卡,它的宽度与其他PCIe设备相同&#xff0c…

Yapi部署

【GO开发工程师】Yapi部署 推荐个人主页:席万里的个人空间 文章目录 【GO开发工程师】Yapi部署1、Yapi部署 1、Yapi部署 初始化yapi: git clone https://github.com/Ryan-Miao/docker-yapi.git cd docker-yapi docker-compose upyapi启动失败 1.cd进入…

学习总结——JMeter做http接口功能测试

JMeter对各种类型接口的测试 默认做接口测试前,已经给出明确的接口文档(如,http://test.nnzhp.cn/wiki/index.php?doc-view-59);本地配好了JMeter 3.x的运行环境; 打开JMeter,添加一个线程组…

【PDF技巧】网上下载的pdf文件怎么才能编辑

不知道大家有没有遇到过网上下载的PDF文件不能编辑的情况,今天我们来详细了解一下导致无法编辑的原因即解决方法有哪些。 第一种原因:PDF文件中的内容是否是图片,如果确认是图片文件,那么我们想要编辑,就可以先使用PD…

Sqlmap进行http头注入及流量分析

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 利用 SQLMap 进行 HTTP 头注入的方式对于 Less-19 注入点的注入 SQLMap 工具我使用kali中自带的 注入准备 先使用bp将Less-19靶场的包抓下来保存到 txt 文件中,输入账号 admin…

day56 日期类 集合

日期类: 获取毫秒值: 1970.1.1午夜之间的时间差 System.currentTimeMillis() java.util.Date: 获取当前时间 new Date(); 指定的格式显示日期: java.text.SimpeDateFormat 格式化(日期-》文本)和解析日期(文本-》日期…

【leetcode】回文子串 动态规划

/*** param {string} s* return {number}*/ var countSubstrings function(s) {let dpnew Array(s.length).fill().map(()>new Array(s.length).fill(false));let num0;for(let i0;i<s.length;i){for(let j0;j<i;j){//在首尾相等时&#xff0c;如果长度时1或者2&…

浅谈XSS简单漏洞xss-labs-master(初级)

一、环境以及xss漏洞简介 网上很多gethub自己下就行 XSS简介&#xff1a; 当用户访问被XSS注入的网页&#xff0c;XSS代码就会被提取出来。用户浏览器就会解析这段XSS代码&#xff0c;也就是说用户被攻击了。 用户最简单的动作就是使用浏览器上网&#xff0c;并且浏览器中有J…

如何在阿里云申请沃通SSL证书

沃通CA已经与阿里云平台达成长期合作&#xff0c;沃通WoSign品牌SSL证书上线阿里云平台以来&#xff0c;成为阿里云平台热销的国产品牌证书。有SSL证书应用需求的阿里云用户&#xff0c;可直接在阿里云平台申请沃通WoSign SSL证书&#xff0c;快捷部署到已有的阿里云产品中。沃…

阿里云2核4G服务器租用价格85元一年,30元3个月

阿里云2核4G服务器多少钱一年&#xff1f;2核4G服务器1个月费用多少&#xff1f;2核4G服务器30元3个月、85元一年&#xff0c;轻量应用服务器2核4G4M带宽165元一年&#xff0c;本文阿里云服务器网整理的2核4G参加活动的主机是ECS经济型e实例和u1云服务器&#xff0c;阿里云服务…

uniapp:启动图 .9png 制作教程

1、工具安装&#xff1a;自行下载Android Studio 2、制作.9png 注意上图3条黑线的位置&#xff0c;意思是&#xff1a;标注黑线的位置可以进行缩放。 对其大多数启动图来说&#xff0c;标注以上3条黑线即可。

什么是Boot Guard?电脑启动中的信任链条解析

“无事可干”的黑客们早已经把目光从操作系统转移到固件上了&#xff0c;毕竟一旦攻破了固件的大门&#xff0c;那么在其上的操作系统也会门户洞开。现在电脑或者x86服务器系统中固件众多&#xff1a; UEFI在其中居于中间地位&#xff0c;它的安全性也是重中之重。我们在前文中…