模仿echo命令学习BIO——Java实现
时间:2022-07-25
本文章向大家介绍模仿echo命令学习BIO——Java实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、BIO模型:同步阻塞IO处理
在程序的开发之中Java里面最小的处理单元就是线程,也就是说每一个线程可以进行IO的处理,在处理之中,该线程无法进行任何的其他操作。 . 多线程是不可能无限制进行创造的,所以需要去考虑堆线程进行有效的个数控制。如果产生的线程过多,那么直接的问题在于,处理性能降低 ,响应的速度变慢。 需要去区分操作系统的内核线程,以及用户线程的区别,所以最好与内核线程有直接联系,需要使用到固定线程池。
举一个生活中的例子,现在烧水,意味着你现在需要一直盯着水壶去看,一直看它已经烧为止,在这之中你什么都干不了。
echo模型
程序部分
首先创建一个BIO的服务端的类
public class BIOEchoServer {
public static void main(String[] args) throws Exception{
ServerSocket serverSocket = new ServerSocket(HostInfo.PORT) ;// 设置监听端口
System.out.println("服务器端已经启动,监听的端口为:" + HostInfo.PORT);
boolean flag = true ;
ExecutorService executorService = Executors.newFixedThreadPool(10) ;
while(flag) {
Socket client = serverSocket.accept() ;
executorService.submit(new EchoClientHandler(client)) ;
}
executorService.shutdown() ;
serverSocket.close() ;
}
private static class EchoClientHandler implements Runnable {
private Socket client ; // 每一个客户端都需要启动一个任务(task)来执行。
private Scanner scanner ;
private PrintStream out ;
private boolean flag = true ; // 循环标记
public EchoClientHandler(Socket client) {
this.client = client ; // 保存每一个客户端操作
try {
this.scanner = new Scanner(this.client.getInputStream()) ;
this.scanner.useDelimiter("n") ; // 设置换行符
this.out = new PrintStream(this.client.getOutputStream()) ;
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(this.flag) {
if (this.scanner.hasNext()) { // 现在有数据进行输入
String val = this.scanner.next().trim() ; // 去掉多余的空格内容
System.out.println("{服务器端}" + val);
if("byebye".equalsIgnoreCase(val)) {
this.out.println("ByeByeByte...");
this.flag = false ;
} else {
out.println("【ECHO】" + val);
}
}
}
this.scanner.close();
this.out.close();
try {
this.client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
其次创建客户端类
public class BIOEchoClient {
public static void main(String[] args) throws Exception {
Socket client = new Socket(HostInfo.HOST_NAME,HostInfo.PORT) ; // 定义连接的主机信息
Scanner scan = new Scanner(client.getInputStream()) ; // 获取服务器端的响应数据
scan.useDelimiter("n") ;
PrintStream out = new PrintStream(client.getOutputStream()) ; // 向服务器端发送信息内容
boolean flag = true ; // 交互的标记
while(flag) {
String inputData = InputUtil.getString("请输入要发送的内容:").trim() ;
out.println(inputData); // 把数据发送到服务器端上
if(scan.hasNext()) {
String str = scan.next().trim() ;
System.out.println(str);
}
if ("byebye".equalsIgnoreCase(inputData)) {
flag = false ;
}
}
client.close();
}
}
工具类
public class InputUtil {
private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in));
private InputUtil() {
}
/**
* 实现键盘数据的输入操作 ,可以返回的数据类型为String
*
* @param prompt 提示信息
* @return 输入的数据返回
*/
public static String getString(String prompt) {
boolean flag = true; // 数据接收标记
String str = null;
while (flag) {
System.out.print(prompt);
try {
str = KEYBOARD_INPUT.readLine(); // 读取一行数据
if (str == null || "".equals(str)) {
System.out.println("数据输入错误 ,该内容不允许为空:");
} else {
flag = false;
}
} catch (IOException e) {
System.out.println("数据输入错误 ,该内容不允许为空:");
}
}
return str;
}
}
启动服务端&&客户端
测试一下:
使用 telnet测试
- Markdown语法讲解及MWeb使用教程
- 通过Linu命令实现屏幕录制和回放(r4笔记第5天)
- 用keras对国产剧评论文本的情感进行预测
- python常用可视化技巧
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(六)maven整合SSM
- 通过java程序抽取日志中的sql语句(r4笔记第4天)
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(七)JDBC url的连接参数
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(十)SVN搭建
- position:sticky的兼容性尝试
- Python爬虫股票评论,snowNLP简单分析股民用户情绪
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(十一)SVN服务器进阶
- node服务的监控预警系统架构
- Maven构建项目速度太慢的解决办法
- 分析函数之窗口子句(r4笔记第3天)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Elasticsearch: range 数据类型及基于range的聚合 (7.4发行版新功能)
- 漫画:如何在数组中找到和为 “特定值” 的三个数?
- 除了MySQL,大牛DBA还会啥?
- 用 Docker swarm 快速部署分布式图数据库 Nebula Graph 集群
- Labelhub 基于腾讯云 Serverless 技术为人工智能企业提供数据与模型解决方案
- 手把手教你使用 Prometheus 监控 JVM
- 基于云开发 CloudBase 搭建在线视频会议应用
- 手搓一个分布式大气监测系统(六)云端能力更新、说明及源码放出
- maybe incorrect parameters such as bit_rate, rate, width or height
- vue 怎么将Checkbox 多选框选中的值提交
- vue-element怎么给select下拉框赋值?
- 小程序生成二维码海报的组件-wxa-plugin-canvas
- kbone 是什么?这可能是最好的小程序开源框架
- jQuery根据填写的input的数值导出excel表格
- 解决多种版本python冲突问题