Java分别用BIO、NIO实现简单的客户端服务器通信
分别用BIO、NIO实现客户端服务器通信
- BIO
- NIO
- NIO演示(无Selector)
- NIO演示(Selector)
前言:
Java I/O模型发展以及Netty网络模型的设计思想
BIO
Java BIO是Java平台上的BIO(Blocking I/O)模型,是Java中用于实现同步阻塞网络编程的一种方式。 在Java中,使用BIO模型需要通过Socket和ServerSocket类来完成网络连接和数据传输,但是由于BIO是同步阻塞的,所以会导致线程阻塞和资源浪费的问题。
因此,在高并发的网络编程场景中,通常会选择使用NIO(Non-blocking I/O)模型或者Netty等框架来实现。
服务端类代码
package com.yu.io.bio;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class BIOServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8081);while (true) {System.out.println("wait connect...");Socket clientSocket = serverSocket.accept();System.out.println(clientSocket.getPort() + "connected");System.out.println("start read...");byte[] readArr = new byte[1024];int read = clientSocket.getInputStream().read(readArr);if (read != -1) {System.out.println("read info : " + new String(readArr,0,read));}System.out.println("end read...");byte[] resBytes = "server response".getBytes();clientSocket.getOutputStream().write(resBytes);System.out.println("response info : " + new String(readArr,0,read));clientSocket.getOutputStream().flush();}}
}
客户端类代码
package com.yu.io.bio;import java.io.IOException;
import java.net.Socket;public class BIOClient {public static void main(String[] args) throws IOException {Socket clientSocket = new Socket("127.0.0.1",8081);byte[] resBytes = "client response".getBytes();clientSocket.getOutputStream().write(resBytes);System.out.println("response info : " + new String(resBytes));clientSocket.getOutputStream().flush();byte[] readArr = new byte[1024];int read = clientSocket.getInputStream().read(readArr);if (read != -1) {System.out.println("read info : " + new String(readArr,0,read));}}
}
NIO
Java NIO 能够支持非阻塞网络编程,可以理解为new io 或者no blok io 我更喜欢称之为new io,因为他不仅仅实现了非阻塞的网络编程方式,同时也封装了常用的网络编程api,更重要的是引入了多路复用器Selector的概念
下面的代码只是展示NIO非阻塞的实现,并没有展示NIO的真正用法
NIO演示(无Selector)
服务端类代码
package com.yu.io.nio;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;public class NIOServer {public static List<SocketChannel> socketChannelList = new ArrayList<>();public static void main(String[] args) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8081));serverSocketChannel.configureBlocking(false);System.out.println("server start...");while (true) {SocketChannel socketChannel = serverSocketChannel.accept();if (socketChannel != null) {System.out.println(socketChannel.socket().getPort() + " connected");socketChannel.configureBlocking(false);socketChannelList.add(socketChannel);}List<SocketChannel> rmChannelList = new ArrayList<>();for (SocketChannel channel : socketChannelList) {try {doChannel(rmChannelList, channel);} catch (IOException ioException) {//有客户端断开连接System.out.println(channel.socket().getPort() + " disconnected");channel.close();rmChannelList.add(channel);}}socketChannelList.removeAll(rmChannelList);}}private static void doChannel(List<SocketChannel> rmChannelList, SocketChannel channel) throws IOException {ByteBuffer readByteBuffer = ByteBuffer.allocate(2048);int read = channel.read(readByteBuffer);String readStr = new String(readByteBuffer.array());if (read > 0) {System.out.println(channel.socket().getPort() + " : " + readStr);if (readStr.contains("hello")) {ByteBuffer sendByteBuffer = ByteBuffer.wrap("hello! I am robot.".getBytes());channel.write(sendByteBuffer);System.out.println("me : " + new String(sendByteBuffer.array()));}if (readStr.contains("old")) {ByteBuffer sendByteBuffer = ByteBuffer.wrap("I am 1 years old.".getBytes());channel.write(sendByteBuffer);System.out.println("me : " + new String(sendByteBuffer.array()));}if (readStr.contains("bey")) {ByteBuffer sendByteBuffer = ByteBuffer.wrap("see you.".getBytes());channel.write(sendByteBuffer);System.out.println("me : " + new String(sendByteBuffer.array()));}}if (read == -1) {rmChannelList.add(channel);}}
}
客户端类代码
package com.yu.io.nio;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;public class NIOClient {public static void main(String[] args) throws IOException {SocketChannel clientSocketChannel = SocketChannel.open();clientSocketChannel.connect(new InetSocketAddress("127.0.0.1",8081));clientSocketChannel.configureBlocking(false);String sendStr = "hello! I am client " + clientSocketChannel.socket().getPort() + ".";ByteBuffer sendByteBuffer = ByteBuffer.wrap(sendStr.getBytes());clientSocketChannel.write(sendByteBuffer);System.out.println("me : " + new String(sendByteBuffer.array()));int msgSize = 0;while (msgSize < 10) {ByteBuffer readByteBuffer = ByteBuffer.allocate(1024);int read = clientSocketChannel.read(readByteBuffer);String readStr = new String(readByteBuffer.array());if (read > 0) {System.out.println("robot : " + readStr);msgSize ++;ByteBuffer resByteBuffer = null;if (readStr.contains("hello")) {resByteBuffer = ByteBuffer.wrap("how old are you?.".getBytes());clientSocketChannel.write(resByteBuffer);System.out.println("me : " + new String(resByteBuffer.array()));resByteBuffer.clear();}if (readStr.contains("old")) {resByteBuffer = ByteBuffer.wrap("en, place say hello!".getBytes());clientSocketChannel.write(resByteBuffer);System.out.println("me : " + new String(resByteBuffer.array()));resByteBuffer.clear();}}}ByteBuffer resByteBuffer = ByteBuffer.wrap("bey bey!".getBytes());clientSocketChannel.write(resByteBuffer);System.out.println("me : " + new String(resByteBuffer.array()));resByteBuffer.clear();clientSocketChannel.close();}
}
NIO演示(Selector)
无Selector的NIO演示中,显然会出现空转的情况,以及无效连接的处理问题,这些问题都会影响性能。
NIO提供Selector多路复用器,优化上述问题
以下demo实现服务器与客户端通信,相互发消息。并由服务器转发给其他客户端(广播功能)
服务端类代码
server main类
import java.io.IOException;public class NIOServerMain {public static void main(String[] args) throws IOException {NIOSelectorServer server = new NIOSelectorServer();server.start();}
}
server run类
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;public class NIOSelectorServer {public void start() throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(8081));serverSocketChannel.configureBlocking(false);//注册到selector多路复用器中Selector selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("server start...");run(selector);}/*** 遍历多路复用器的事件,处理事件*/private void run(Selector selector) throws IOException {while (true) {//阻塞等待事件selector.select();Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey selectedKey = iterator.next();try {if (selectedKey.isAcceptable()) {doAccept(selector, selectedKey);}if (selectedKey.isReadable()) {doReadChannel(selectedKey, selector);}} catch (IOException ioException) {//有客户端断开连接disConnect(selectedKey, "exception");}iterator.remove();}}}/*** 处理连接事件*/private void doAccept(Selector selector, SelectionKey selectedKey) throws IOException {ServerSocketChannel serverChannel = (ServerSocketChannel)selectedKey.channel();SocketChannel socketChannel = serverChannel.accept();socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);System.out.println(socketChannel.socket().getPort() + " connected");}/*** 处理接收信息事件*/private void doReadChannel(SelectionKey selectedKey, Selector selector) throws IOException {SocketChannel channel = (SocketChannel)selectedKey.channel();ByteBuffer readByteBuffer = ByteBuffer.allocate(2048);int read = channel.read(readByteBuffer);String readStr = "";readByteBuffer.flip();readStr += StandardCharsets.UTF_8.decode(readByteBuffer);if (read > 0) {System.out.println(channel.socket().getPort() + " : " + readStr.length() + " - "+ readStr);//转发消息(其他客户端)broadcast(selectedKey, selector, readStr);if (readStr.contains("hello")) {sendMsg(channel, "hello! I am robot.");}if (readStr.contains("old")) {sendMsg(channel, "I am 1 years old.");}if (readStr.contains("bye")) {sendMsg(channel, "see you.");}}if (read == -1) {//有客户端断开连接disConnect(selectedKey, "read = -1");}}/*** 连接异常的处理*/private void disConnect(SelectionKey selectedKey, String type) throws IOException {SocketChannel channel = (SocketChannel)selectedKey.channel();System.out.println(channel.socket().getPort() + " disconnected. " + type);selectedKey.cancel();channel.close();}/*** 发送消息*/private void sendMsg(SocketChannel channel, String s) throws IOException {ByteBuffer sendByteBuffer = ByteBuffer.wrap(s.getBytes());channel.write(sendByteBuffer);System.out.println("me : " + new String(sendByteBuffer.array()));}/*** 广播* 转发消息(给其他客户端)*/private void broadcast(SelectionKey fromSelectedKey, Selector selector, String readStr) throws IOException {Iterator<SelectionKey> selectionKeyIterator = selector.keys().iterator();while (selectionKeyIterator.hasNext()) {SelectionKey otherKey = selectionKeyIterator.next();if (otherKey == fromSelectedKey) {continue;}if (!(otherKey.channel() instanceof SocketChannel)) {continue;}SocketChannel otherChannel = (SocketChannel)otherKey.channel();sendMsg(otherChannel, "(转发自 "+ ((SocketChannel)fromSelectedKey.channel()).socket().getPort() + ")" + readStr);}}
}
客户端代码
一共构造了两个客户端(消息客户端和looker客户端), looker客户端优先启动,随后启动消息客户端,消息客户端与服务器的通信会被转发给looker客户端
look client main类
import java.io.IOException;public class NIOClientLookMain {public static void main(String[] args) throws IOException, InterruptedException {NIOSelectorClient client = new NIOSelectorLookClient();client.start(8081, 100);}
}
msg client main类
import java.io.IOException;public class NIOClientMain {public static void main(String[] args) throws IOException, InterruptedException {NIOSelectorClient lookClient = new NIOSelectorClient();lookClient.start(8081, 10);}
}
client run类
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;public class NIOSelectorClient {protected int port;protected int size;public void start(int port, int size) throws IOException, InterruptedException {this.port = port;this.size = size;SocketChannel clientSocketChannel = SocketChannel.open();clientSocketChannel.connect(new InetSocketAddress("127.0.0.1",port));clientSocketChannel.configureBlocking(false);Selector selector = Selector.open();clientSocketChannel.register(selector, SelectionKey.OP_READ);//发送开始数据sendMsg(clientSocketChannel, "hello! I am client " + clientSocketChannel.socket().getLocalPort() + ".");run(selector);sendMsg(clientSocketChannel, "bye bye!");clientSocketChannel.close();}/*** 遍历多路复用器的事件,处理事件*/protected void run(Selector selector) throws IOException, InterruptedException {int msgSize = 0;while (msgSize < size) {int length=selector.select();if(length ==0){continue;}Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while(iterator.hasNext()){SelectionKey selectionKey = iterator.next();if(selectionKey.isReadable()){boolean readChannel = false;try {readChannel = doReadChannel(selectionKey, selector);} catch (IOException e) {selectionKey.cancel();System.out.println("robot disconnect, restart connect...");while (true){try {reConnect();return;} catch (IOException ioException) {System.out.println("restart connecting(5s) ");//ioException.printStackTrace();Thread.sleep(5000);}}}if (readChannel) {msgSize ++;}}iterator.remove();}}}protected boolean doReadChannel(SelectionKey selectedKey, Selector selector) throws IOException {SocketChannel channel = (SocketChannel)selectedKey.channel();ByteBuffer readByteBuffer = ByteBuffer.allocate(2048);int read = channel.read(readByteBuffer);String readStr = "";readByteBuffer.flip();readStr += StandardCharsets.UTF_8.decode(readByteBuffer);if (read > 0) {System.out.println("robot : " + readStr);if (readStr.contains("hello")) {sendMsg(channel, "how old are you?.");}if (readStr.contains("old")) {sendMsg(channel, "en, place say hello!");}return true;}return false;}protected void sendMsg(SocketChannel channel, String sendStr) throws IOException {ByteBuffer sendByteBuffer = ByteBuffer.wrap(sendStr.getBytes());channel.write(sendByteBuffer);System.out.println("me : " + new String(sendByteBuffer.array()));}protected void reConnect() throws IOException, InterruptedException {NIOSelectorClient client = new NIOSelectorClient();client.start(port, size);}
}
look client run类
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;public class NIOSelectorLookClient extends NIOSelectorClient{@Overridepublic void start(int port, int size) throws IOException, InterruptedException {this.port = port;this.size = size;SocketChannel clientSocketChannel = SocketChannel.open();clientSocketChannel.connect(new InetSocketAddress("127.0.0.1",port));clientSocketChannel.configureBlocking(false);Selector selector = Selector.open();clientSocketChannel.register(selector, SelectionKey.OP_READ);//发送开始数据sendMsg(clientSocketChannel, "I am looker. " + clientSocketChannel.socket().getLocalPort() + ".");run(selector);}@Overrideprotected boolean doReadChannel(SelectionKey selectedKey, Selector selector) throws IOException {SocketChannel channel = (SocketChannel)selectedKey.channel();ByteBuffer readByteBuffer = ByteBuffer.allocate(2048);int read = channel.read(readByteBuffer);String readStr = "";readByteBuffer.flip();readStr += StandardCharsets.UTF_8.decode(readByteBuffer);if (read > 0) {System.out.println("robot : " + readStr.length() + " - "+ readStr);if (readStr.contains("bye")) {sendMsg(channel, "bye.");}return true;}return false;}@Overrideprotected void reConnect() throws IOException, InterruptedException {NIOSelectorClient client = new NIOSelectorLookClient();client.start(port, size);}
}
相关文章:

Java分别用BIO、NIO实现简单的客户端服务器通信
分别用BIO、NIO实现客户端服务器通信 BIONIONIO演示(无Selector)NIO演示(Selector) 前言: Java I/O模型发展以及Netty网络模型的设计思想 BIO Java BIO是Java平台上的BIO(Blocking I/O)模型&a…...
React Portals
什么是React Portals React Portals(React 门户)是 React 提供的一种机制,用于将组件渲染到 DOM 树中的不同位置,而不受组件层次结构的限制。它允许你将一个组件的渲染内容“传送”到 DOM 结构中的任何位置,通常用于处…...

Python基础之高级函数
异常捕获 Python中,使用trycatch两个关键字来实现对异常的处理。在我们平时的工作中,异常的出现是在所难免的,但是异常一旦出现,极有可能会直接导致程序崩溃,无法正常运行,所以异常一定要及时的做出对应的…...

CSS3常用的新功能总结
CSS3常用的新功能包括圆角、阴渐变、2D变换、3D旋转、动画、viewpor和媒体查询。 圆角、阴影 border-redius 对一个元素实现圆角效果,是通过border-redius完成的。属性为两种方式: 一个属性值,表示设置所有四个角的半径为相同值ÿ…...

Lvs+KeepAlived高可用高性能负载均衡
目录 1.环境介绍 2.配置keepalived 3.测试 1.测试负载均衡 2.测试RS高可用 3.测试LVS高可用 3.1测试lvs主服务宕机 3.2.测试lvs主服务器恢复 4.我在实验中遇到的错误 1.环境介绍 环境:centos7 RS1---RIP1:192.168.163.145 VIP 192.168.163.200 RS2---RIP2…...

无涯教程-Android Online Test函数
Android在线测试模拟了真正的在线认证考试。您将看到基于 Android概念的多项选择题(MCQ),将为您提供四个options。您将为该问题选择最合适的答案,然后继续进行下一个问题,而不会浪费时间。完成完整的考试后,您将获得在线考试分数。 总问题数-20 最长时间-20分钟 Start Test …...

蓝桥杯打卡Day1
文章目录 全排列八皇后 一、全排列IO链接 本题思路:本题是一道经典的全排列问题,深度优先搜索即可解决。 #include <bits/stdc.h>constexpr int N10;std::string s; std::string ans; int n; bool st[N];void dfs(int u) {if(un){std::cout<<ans<…...
zipkin2.24.2源码install遇见的问题
1、idea导入项目后将Setting中的关于Maven和Java Compile相关的配置改为jdk11,同时Project Structure改为jdk11 2、将pom配置中的fork标签注释 标题未修改以上配置产生的问题 Compilation failure javac: Ч ı : --release : javac <options> <source files&g…...

yapi密码是如何生成的
yapi密码是如何生成的 关闭yapi注册功能后,想要通过手动插入用户数据到db中,那么密码是如何生成的呢? exports.generatePassword (password, passsalt) > { return sha1(password sha1(passsalt)); }; 所以如果想要创建一个用户&#x…...

2023-09-02 LeetCode每日一题(最多可以摧毁的敌人城堡数目)
2023-09-02每日一题 一、题目编号 2511. 最多可以摧毁的敌人城堡数目二、题目链接 点击跳转到题目位置 三、题目描述 给你一个长度为 n ,下标从 0 开始的整数数组 forts ,表示一些城堡。forts[i] 可以是 -1 ,0 或者 1 ,其中&…...

k8s环境部署配置
目录 一.虚拟机准备 二.基础环境配置(各个节点都做) 1.IP和hosts解析 2.防火墙和selinux 3.安装基本软件 4.配置时间同步 5.禁用swap分区 6.修改内核参数并重载 7.配置ipvs 三.docker环境(各个节点都做) 1.配置软件源并…...

Java之文件操作与IO
目录 一.认识文件 1.1文件是什么? 1.2文件的组织 1.3文件路径 1.4文件的分类 二.文件操作 2.1File概述 三.文件内容操作--IO 3.1JavaIO的认识 3.2Reader和Writer ⭐Reader类 ⭐Writer类 3.2FileInputStream和FileOutputStream ⭐FileInputStream类 …...

指令系统(408)
一、拓展操作码指令格式 【2017 统考】某计算机按字节编址,指令字长固定且只有两种指令格式,其中三地址指令29条、二地址指令107条,每个地址字段6位,则指令字长至少应该是( A) A、24位 B、26位 …...

Pygame中Trivia游戏解析6-3
3.3 Trivia类的show_question()函数 Trivia类的show_question()函数的作用是显示题目。主要包括显示题目框架、显示题目内容和显示题目选项等三部分。 3.3.1 显示题目的框架 在show_question()函数中,通过以下代码显示题目的框架。 print_text(font1, 210, 5, &q…...

热释电矢量传感器设计
1 概述 使用4个热释电传感器组成一个2X2的矩阵。通过曲线的相位差、 峰峰值等特征量来计算相关信息。本文使用STM32单片机设计、制作了热释电传感器矩阵;使用C#.NET设计了上位机软件。为以上研究做了试验平台。 2 硬件电路设计 2.1 热释电传感器介绍 热释电红外…...
MySql学习笔记10——视图介绍
视图 概述 view view可以看作是一张“虚拟表”,(但是他也是会作为文件存在的) 当我们通过复杂的查询语句获取一张表的时候,可以将这张表作为一个视图,和创建一个新表不同,在视图上进行的DML操作会对数据…...

【探索Linux】—— 强大的命令行工具 P.7(进程 · 进程的概念)
阅读导航 前言一、冯诺依曼体系结构二、操作系统(OS)1. 概念 三、进程1. 进程的概念2. PCB(Process Control Block)3. 查看进程 四、fork函数1. 函数简介2. 调用方式3. 返回值4. 使用示例 五、进程的几种状态1. 状态简介2. 进程状…...

JAVA宝典----容器(理解记忆)
目录 一、Java Collections框架是什么? 二、什么是迭代器? 三、Iterator与ListIterator有什么区别? 四、ArrayList、Vector和LinkedList有什么区别? 五、HashMap、Hashtable、TreeMap和WeakHashMap有哪些区别? 六…...
JS中的扩展操作符...(点点点)
标题 前言概述拓展操作符(Spread Operator)赋值与扩展操作符的区别 剩余操作符(Rest Operator) 前言 大家应该都在代码中用过或者看到…方法,我每次用到这个方法的时候都会想到第一次见到这个方法一头雾水的样子&#…...

找redis大key工具rdb_bigkeys
github官网 https://github.com/weiyanwei412/rdb_bigkeys 在centos下安装go [roothadoop102 rdb_bigkeys-master]# wget https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz [roothadoop102 rdb_bigkeys-master]# tar -zxf go1.13.5.linux-amd64.tar.gz -C /usr/local将g…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

XXE漏洞知识
目录 1.XXE简介与危害 XML概念 XML与HTML的区别 1.pom.xml 主要作用 2.web.xml 3.mybatis 2.XXE概念与危害 案例:文件读取(需要Apache >5.4版本) 案例:内网探测(鸡肋) 案例:执行命…...

Vue.js教学第二十一章:vue实战项目二,个人博客搭建
基于 Vue 的个人博客网站搭建 摘要: 随着前端技术的不断发展,Vue 作为一种轻量级、高效的前端框架,为个人博客网站的搭建提供了极大的便利。本文详细介绍了基于 Vue 搭建个人博客网站的全过程,包括项目背景、技术选型、项目架构设计、功能模块实现、性能优化与测试等方面。…...