BIO初探究

2024-06-04 15:12
文章标签 bio 探究

本文主要是介绍BIO初探究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、阻塞式 IO 到底阻塞在哪?
  • 二、多个客户端连接
    • 多个客户端,我们服务端代码应该怎么样修改呢?
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

做了一年多物联网,数采这块也接触了不少,但在网络IO 方面使用 一直都是网上找找代码,每次自己实现 简单 BIO 服务或client 都存在这样那样的问题,做此篇记录一下;


提示:以下是本篇文章正文内容,下面案例可供参考

一、阻塞式 IO 到底阻塞在哪?

一提到 BIO ,第一反应是 阻塞式 IO, 性能不好,各种低效率,但是在 tomcat 7 之前的 不都是 阻塞式IO 吗? 那么多应用不也跑的好好的;话不多说,看下面示例;

现在需要开发一个 BIO 服务器, 用来和多个客户端 收发消息;代码如下


import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;public class TestServer {public static void main(String[] args) throws IOException {ServerSocket server = new ServerSocket(9090);System.out.println("开启server等待连接");while (true) {// todo 查看是否阻塞Socket accept = server.accept();// todo 查看流是否阻塞InputStream inputStream = accept.getInputStream();byte[] content = new byte[26];int len = 0;/*int len = inputStream.read(content);System.out.println("len: " + len + " rev: " + new String(content));*/while ((len = inputStream.read(content)) != -1) {System.out.println("result:" + len);Date date = new Date();System.out.println(date.toLocaleString() + " rev:" + new String(content));content = new byte[26];}}}
}

客户端

private static void connectServer(String message) {Socket socket;try {//socket = new Socket("127.0.0.1", 4545);socket = new Socket("127.0.0.1", 9090);System.out.println("connect server success");PrintWriter pw = new PrintWriter(socket.getOutputStream());for (int i = 0; i < 2; i++) {pw.write(message);//pw.write("\n");pw.flush();System.out.println("发送" + message + "成功");Thread.currentThread().sleep(1000);}//pw.close();} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}

执行 输出 发送的message 信息;

二、多个客户端连接

多个客户端,我们服务端代码应该怎么样修改呢?

网上的代码,一搜多个客户端连接是不是立马就想着把上图服务端的代码写到一个thread 里边去?

服务端代码

// 修改前
InputStream inputStream = accept.getInputStream();
byte[] content = new byte[26];
int len = 0;while ((len = inputStream.read(content)) != -1) {System.out.println("result:" + len);Date date = new Date();System.out.println(date.toLocaleString() + " rev:" + new String(content));content = new byte[26];
}// 修改后
new thread(() -> {InputStream inputStream = accept.getInputStream();byte[] content = new byte[26];int len = 0;while ((len = inputStream.read(content)) != -1) {System.out.println("result:" + len);Date date = new Date();System.out.println(date.toLocaleString() + " rev:" + new String(content));content = new byte[26];}
}).start();

客户端端代码

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;public class TestClient {public static void main(String[] args) throws IOException {List<Thread> list = new ArrayList();for (int i = 0; i < 10; i++) {int finalI = i;Thread thread = new Thread(() ->connectServer("hello server,I M client " + finalI));list.add(thread);}for (Thread thread : list) {thread.start();}System.in.read();}private static void connectServer(String message) {Socket socket;try {socket = new Socket("127.0.0.1", 9090);System.out.println("connect server success");PrintWriter pw = new PrintWriter(socket.getOutputStream());for (int i = 0; i < 2; i++) {pw.write(message);//pw.write("\n");pw.flush();System.out.println("发送" + message + "成功");Thread.currentThread().sleep(1000);}pw.close();} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

执行发现,确实读取正常,那我们的 BIO server 就不能应付多个客户端吗?,那所谓的阻塞,到底阻塞在什么地方呢?去掉服务端 多个thread ,断点服务端代码, 同时启动 多个客户端连接;

结果:
发现 创建的10 个连接 都连上了服务端,但 服务端为何只收到 一个客户端发来的消息呢?所谓的阻塞到底阻塞在哪里?
在这里插入图片描述
在这里插入图片描述

于是 去掉服务端的 while ((len = inputStream.read(content)) != -1) 这段代码循环,再试试, 发现收到了所有客户端发来的消息,但是每个都只收到了一条;(我这边是每个客户端发送2 条)

百度得知
while ((len = inputStream.read(content)) != -1) 这行代码 在 客户端 socket 关闭或中断的情况下 才会 = -1 ,要实现 客户端和服务端 一直 连接 所以代码都会阻塞 在这个 while 循环里;


总结

之前理解的阻塞有多种层面, 一直都是理解在所谓的IO设计层面,即在网络传输的过程中,java 这边的线程 一直阻塞等待,直到有资源返回 这边线程才恢复正常,这段理解我也不知道准不准确,但确实较为晦涩难懂,而且于编码而言 毫无作用;

这边经过这个实例 我理解的阻塞:
即 io 上的阻塞,在 socket io 上没数据过来的情况下,当前socket 会一直在
while ((len = inputStream.read(content)) != -1) 这部分会一直占用当前线程,直到 client io 关闭,当前流结束;

这篇关于BIO初探究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1030403

相关文章

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

“序列优化探究:最长上升子序列的算法发现与应用“

最长上升子序列 最长上升子序列是指在一个给定序列中,找到一个最长的子序列,使得子序列中的元素单调递增。例如,序列 [1, 3, 5, 4, 7] 的最长上升子序列是 [1, 3, 5, 7],长度为4。 这是一个经典的动态规划问题。 假设dp[i]表示以第i个元素为结尾的最长上升子序列的长度。 可以用一个嵌套循环来遍历所有的元素对,如果前一个元素小于后一个元素,则可以将后一个元素添加到

java中BIO、AIO与NIO的区别

一、同步异步与阻塞非阻塞的区别 1.同步 例:买饭:自己亲自去饭馆买饭,这就是同步(自己处理IO读写) 2.异步 例:买饭:叫外卖送到家,这就是异步(IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(饭名和地址),OS需要支持异步IO操作API) 3.阻塞 例:办理业务:一直排队等待(调用会一直阻塞到读写完成才返回) 4.非阻塞 例:办理业务:抽号后就可以做其他事,如果你

【Redis实战专题】「技术提升系列」夯实基础分析探究List列表的点点滴滴

夯实基础分析探究List列表的点点滴滴 List列表介绍队列和堆栈场景常用操作指令llen获取链表的长度llen指令的案例介绍添加购物车信息获取用户数购物车数量 lindex获取指定位置的元素lindex指令的案例介绍获取第三个位置的购物车数据 lrange获取链表子元素列表下标的选择lrange指令的案例介绍 lset修改指定位置元素lset指令的案例介绍 linsert对链表的某个值

深入探究RTOS的IPC机制----邮箱

阅读引言: 因为将来工作需要, 最近在深入学习OS的内部机制,我把我觉得重要的、核心的东西分享出来, 希望对有需要的人有所帮助, 阅读此文需要读友有RTOS基础, 以及一些操作系统的基础知识, 学习过Linux的最佳, 特别是想RT-Thread适合Linux非常像的, 代码风格、IPC机制等等。 目录 一、RT-Thread中邮箱的特性 二、 邮箱的源码实现 1,邮箱

Java IO模型BIO、NIO、AIO介绍

第一章 BIO、NIO、AIO课程介绍 1.1 课程说明   在java的软件设计开发中,通信架构是不可避免的,我们在进行不同系统或者不同进程之间的数据交互,或者在高并发下的通信场景下都需要用到网络通信相关的技术,对于一些经验丰富的程序员来说,Java早期的网络通 信架构存在一些缺陷,其中最令人恼火的是基于性能低下的同步阻塞式的I/O通信(BIO),随着互联网开发下通 信性能的高要求,Java

学习、探究Java设计模式——观察者模式

http://blog.csdn.net/a553181867/article/details/52454178 http://blog.csdn.net/a553181867/article/details/52454178 http://blog.csdn.net/a553181867/article/details/52454178 学习、探

掌握rpc、grpc并探究内在本质

文章目录 rpc是什么?又如何实现服务通信?理解rpcRPC的通信过程通信协议的选择小结RPC VS Restful net_rpc实践案例net/rpc包介绍创建服务端创建client 看看net_rpc的通信调度实现的内部原理明确目标基于自己实现的角度分析我会怎么做代码分析 grpc介绍与下载安装前言与背景grpc针对上面问题的解决方案简述grpc下载 grpc框架实践案例分析流程项目结

Exception in thread http-bio-23230-exec-609 java.lang.OutOfMemoryError: unable to create new nativ

今天公司123上服务器上的项目都打不开了。看后台报错:   Exception in thread "http-bio-23230-exec-609" java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thre

气体传感器的工作原理探究

气体传感器的工作原理主要基于其内部的感应元件与目标气体之间的相互作用。不同的气体传感器可能采用不同的工作原理,但其核心目的都是将气体的浓度或成分转化为可测量和处理的电信号。 PID气体传感器 以常见的电化学式气体传感器为例,其工作原理涉及气体通过传感器外的过滤膜进入传感器内部,并与传感器内的液态电解质发生反应。在反应过程中,传感器针脚会输出电流电压信号,这些信号的大小与现场气体的