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

相关文章

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

还不懂BIO,NIO,AIO吗

BIO(Blocking I/O)、NIO(Non-blocking I/O)和 AIO(Asynchronous I/O)是 Java 中三种不同的 I/O 模型,主要用于处理输入 / 输出操作。 一、BIO(Blocking I/O) 定义与工作原理: BIO 即阻塞式 I/O(同步阻塞,传统IO)。在这种模型下,当一个线程发起一个 I/O 操作(如读取文件或网络数据)时,此线

探究零工市场小程序如何改变传统兼职模式

近年来,零工市场小程序正逐渐改变传统的兼职模式,为求职者和雇主提供了一个更为高效、便捷的平台。本文将深入探讨零工市场小程序如何影响传统兼职模式,以及它带来的优势和挑战。 一、背景与挑战 传统的兼职市场往往存在信息不对称的问题,求职者难以快速找到合适的工作,而雇主也难以找到匹配的劳动力。此外,兼职工作的不稳定性和安全性也是求职者关注的焦点。零工市场小程序的兴起,旨在解决这些问题,通过数字化手

apk中签名文件探究(*.SF, *.MF,*.RSA)

文章来源: 作者:嘟嘟小灰 链接:https://www.jianshu.com/p/e07da93acf98 来源:简书 1、取一个apk,然后进行不同签名,生成1.apk、2.apk,并提取META-INF里面的文件进行比对 def calc_sha1(data):sha1obj = hashlib.sha1()if not isinstance(data, (bytear

TRIZ在充电桩安全中的应用探究

在当今电动汽车日益普及的时代,充电桩的安全问题至关重要。TRIZ(发明问题解决理论)可以为提升充电桩的安全性提供强大助力。具体步骤如深圳天行健企业管理咨询公司下文所述: 一、充电桩安全面临的问题 1.电气安全风险:包括过压、过流、短路等电气故障,可能导致设备损坏、火灾甚至人员伤亡。 2.机械安全风险:如充电桩外壳的坚固程度、充电插头的插拔可靠性等,可能影响用户的使用安全。 3.环境安全

Flink on YARN模式下TaskManager的内存分配探究

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 我们使用如下的参数提交了Flink on YARN作业(per-job模式)。 /opt/flink-1.9.0/bin/flink run \--detached \--jobmanager yarn-cluster \--yarnname "x.y.z" \--yarnjobManagerMemory 2048 \--

BBR 与 AIMD 共存公平性探究

一个古已有之的结论: deep buffer 场景,bbr 相对 reno/cubic 等 aimd 有优势,侵占性强;shallow buffer 场景,aimd 有优势,bbr 带宽被挤占。 本文用实例分析 why 并给出 how。 先看 deep buffer 场景 bbr 单挑 aimd 双流的效果,下图是标准 bbr,被虐成经理: 下图是用 max(bw/delay) 替代 ma

深入Linux轻量级进程管理:线程创建、线程ID解析与进程地址空间页表探究

🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊 目录 `🚲Linux线程控制``🐏POSIX线程库``🐕创建线程``🐟指令查看轻量级进程``指令:ps -aL` `🐒线程ID及进程地址空间布局`*pthread_t 到底是什么类型呢?* `🦔__thread与线程的局部存储`