Java入门(7)--网络编程

Java网络编程:构建网络应用的基石 🌐

🎯 掌握Java网络编程,打造强大的网络应用!

在上一篇文章中,我们探讨了Java的I/O操作和反射机制。今天,让我们深入学习Java网络编程,了解如何构建网络应用程序! 💻

1. 网络编程基础 📡

Java提供了强大的网络编程API,支持各种网络协议和通信模式。让我们从基础概念开始学习。

1.1 网络基础概念

  • IP地址:网络设备的唯一标识
  • 端口号:应用程序的通信端点
  • 协议:通信规则(如TCP、UDP)
  • Socket:网络通信的端点
public class NetworkBasics {public static void main(String[] args) throws Exception {// 获取本机IP地址InetAddress localHost = InetAddress.getLocalHost();System.out.println("本机IP地址:" + localHost.getHostAddress());// 解析域名InetAddress github = InetAddress.getByName("github.com");System.out.println("GitHub IP地址:" + github.getHostAddress());// 检查主机可达性boolean reachable = github.isReachable(5000);System.out.println("GitHub是否可达:" + reachable);}
}

1.2 URL处理

public class URLExample {public static void main(String[] args) {try {URL url = new URL("https://api.github.com/users/octocat");// 获取URL信息System.out.println("协议:" + url.getProtocol());System.out.println("主机:" + url.getHost());System.out.println("端口:" + url.getPort());System.out.println("路径:" + url.getPath());// 读取URL内容try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {String line;while ((line = reader.readLine()) != null) {System.out.println(line);}}} catch (IOException e) {System.out.println("URL处理错误:" + e.getMessage());}}
}

2. Socket编程 🔌

Socket是网络编程的核心,让我们通过实例来学习TCP和UDP通信。

2.1 TCP通信示例

服务器端代码:

public class TCPServer {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888)) {System.out.println("服务器启动,等待连接...");while (true) {Socket clientSocket = serverSocket.accept();System.out.println("客户端已连接:" + clientSocket.getInetAddress());// 处理客户端请求new Thread(() -> handleClient(clientSocket)).start();}} catch (IOException e) {System.out.println("服务器错误:" + e.getMessage());}}private static void handleClient(Socket clientSocket) {try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true)) {String message;while ((message = reader.readLine()) != null) {System.out.println("收到消息:" + message);writer.println("服务器收到:" + message);}} catch (IOException e) {System.out.println("客户端处理错误:" + e.getMessage());}}
}

客户端代码:

public class TCPClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8888);BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in))) {System.out.println("已连接到服务器");String message;while ((message = consoleReader.readLine()) != null) {writer.println(message);System.out.println("服务器响应:" + reader.readLine());}} catch (IOException e) {System.out.println("客户端错误:" + e.getMessage());}}
}

2.2 UDP通信示例

服务器端代码:

public class UDPServer {public static void main(String[] args) {try (DatagramSocket socket = new DatagramSocket(9999)) {System.out.println("UDP服务器启动...");byte[] buffer = new byte[1024];while (true) {DatagramPacket packet = new DatagramPacket(buffer, buffer.length);socket.receive(packet);String message = new String(packet.getData(), 0, packet.getLength());System.out.println("收到消息:" + message);// 发送响应String response = "服务器收到:" + message;byte[] responseData = response.getBytes();DatagramPacket responsePacket = new DatagramPacket(responseData,responseData.length,packet.getAddress(),packet.getPort());socket.send(responsePacket);}} catch (IOException e) {System.out.println("服务器错误:" + e.getMessage());}}
}

客户端代码:

public class UDPClient {public static void main(String[] args) {try (DatagramSocket socket = new DatagramSocket()) {InetAddress serverAddress = InetAddress.getByName("localhost");BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));while (true) {System.out.print("请输入消息:");String message = consoleReader.readLine();// 发送数据byte[] sendData = message.getBytes();DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,serverAddress,9999);socket.send(sendPacket);// 接收响应byte[] receiveData = new byte[1024];DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);socket.receive(receivePacket);String response = new String(receivePacket.getData(),0,receivePacket.getLength());System.out.println("服务器响应:" + response);}} catch (IOException e) {System.out.println("客户端错误:" + e.getMessage());}}
}

3. HTTP编程 🌍

3.1 HttpURLConnection示例

public class HttpExample {public static void main(String[] args) {try {URL url = new URL("https://api.github.com/users/octocat");HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置请求方法和头部conn.setRequestMethod("GET");conn.setRequestProperty("Accept", "application/json");// 获取响应码int responseCode = conn.getResponseCode();System.out.println("响应码:" + responseCode);// 读取响应内容try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {StringBuilder response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {response.append(line);}System.out.println("响应内容:" + response.toString());}} catch (IOException e) {System.out.println("HTTP请求错误:" + e.getMessage());}}
}

3.2 实用工具类

public class HttpClient {private static final int TIMEOUT = 5000;public static String get(String url) throws IOException {HttpURLConnection conn = null;try {URL urlObj = new URL(url);conn = (HttpURLConnection) urlObj.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(TIMEOUT);conn.setReadTimeout(TIMEOUT);try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {StringBuilder response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {response.append(line);}return response.toString();}} finally {if (conn != null) {conn.disconnect();}}}public static String post(String url, String body) throws IOException {HttpURLConnection conn = null;try {URL urlObj = new URL(url);conn = (HttpURLConnection) urlObj.openConnection();conn.setRequestMethod("POST");conn.setConnectTimeout(TIMEOUT);conn.setReadTimeout(TIMEOUT);conn.setDoOutput(true);// 写入请求体try (OutputStream os = conn.getOutputStream()) {byte[] input = body.getBytes(StandardCharsets.UTF_8);os.write(input, 0, input.length);}// 读取响应try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {StringBuilder response = new StringBuilder();String line;while ((line = reader.readLine()) != null) {response.append(line);}return response.toString();}} finally {if (conn != null) {conn.disconnect();}}}
}

4. 网络编程最佳实践 💡

  1. 连接管理:

    • 及时关闭网络连接
    • 使用连接池管理连接
    • 设置合适的超时时间
    • 处理断线重连
  2. 性能优化:

    • 使用NIO提升性能
    • 实现多线程处理
    • 使用缓冲区优化数据传输
    • 压缩传输数据
  3. 安全建议:

    • 使用SSL/TLS加密通信
    • 验证网络连接的合法性
    • 防止拒绝服务攻击
    • 保护敏感数据

5. 高级网络编程特性 🚀

5.1 NIO编程模型

NIO(New I/O)提供了更高效的网络编程模型,特别适合处理大量连接的场景。

public class NIOServer {public static void main(String[] args) throws IOException {// 创建选择器Selector selector = Selector.open();// 创建ServerSocketChannelServerSocketChannel serverSocket = ServerSocketChannel.open();serverSocket.bind(new InetSocketAddress(8889));serverSocket.configureBlocking(false);// 注册到选择器serverSocket.register(selector, SelectionKey.OP_ACCEPT);System.out.println("NIO服务器启动在端口8889...");while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iter = selectedKeys.iterator();while (iter.hasNext()) {SelectionKey key = iter.next();if (key.isAcceptable()) {handleAccept(serverSocket, selector);}if (key.isReadable()) {handleRead(key);}iter.remove();}}}private static void handleAccept(ServerSocketChannel serverSocket, Selector selector) throws IOException {SocketChannel client = serverSocket.accept();client.configureBlocking(false);client.register(selector, SelectionKey.OP_READ);System.out.println("接受新的连接:" + client.getRemoteAddress());}private static void handleRead(SelectionKey key) throws IOException {SocketChannel client = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = client.read(buffer);if (bytesRead == -1) {client.close();return;}buffer.flip();byte[] data = new byte[buffer.limit()];buffer.get(data);System.out.println("收到消息:" + new String(data));}
}

5.2 异步网络编程

Java 7引入的AIO(Asynchronous I/O)提供了真正的异步非阻塞I/O操作。

public class AsyncServer {public static void main(String[] args) throws IOException {AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();server.bind(new InetSocketAddress(8890));server.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {@Overridepublic void completed(AsynchronousSocketChannel client, Void att) {// 继续接受下一个连接server.accept(null, this);ByteBuffer buffer = ByteBuffer.allocate(1024);client.read(buffer, buffer, new CompletionHandler<Integer,ByteBuffer>() {@Overridepublic void completed(Integer result, ByteBuffer attachment) {attachment.flip();byte[] data = new byte[attachment.limit()];attachment.get(data);System.out.println("异步收到:" + new String(data));}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {exc.printStackTrace();}});}@Overridepublic void failed(Throwable exc, Void att) {exc.printStackTrace();}});System.out.println("异步服务器启动在端口8890...");// 保持主线程运行System.in.read();}
}

6. 网络安全编程 🔒

6.1 SSL/TLS实现

安全套接字层(SSL)和传输层安全(TLS)是网络通信加密的标准。

public class SSLServer {public static void main(String[] args) {try {// 加载密钥库String keystorePath = "server.keystore";char[] keystorePass = "password".toCharArray();KeyStore ks = KeyStore.getInstance("JKS");ks.load(new FileInputStream(keystorePath), keystorePass);// 初始化密钥管理器KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(ks, keystorePass);// 配置SSL上下文SSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), null, null);// 创建SSL服务器套接字SSLServerSocketFactory ssf = sslContext.getServerSocketFactory();SSLServerSocket serverSocket = (SSLServerSocket) ssf.createServerSocket(8891);System.out.println("SSL服务器启动在端口8891...");while (true) {SSLSocket client = (SSLSocket) serverSocket.accept();handleSecureClient(client);}} catch (Exception e) {System.out.println("SSL服务器错误:" + e.getMessage());}}
}

6.2 实用工具类:安全数据传输

public class SecureNetworkUtils {// AES加密配置private static final String ALGORITHM = "AES";private static final int KEY_SIZE = 256;private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";/*** 生成AES密钥*/public static SecretKey generateKey() throws NoSuchAlgorithmException {KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);keyGen.init(KEY_SIZE);return keyGen.generateKey();}/*** 加密数据*/public static byte[] encrypt(String data, SecretKey key, IvParameterSpec iv) throws Exception {Cipher cipher = Cipher.getInstance(TRANSFORMATION);cipher.init(Cipher.ENCRYPT_MODE, key, iv);return cipher.doFinal(data.getBytes());}/*** 解密数据*/public static String decrypt(byte[] encryptedData, SecretKey key, IvParameterSpec iv) throws Exception {Cipher cipher = Cipher.getInstance(TRANSFORMATION);cipher.init(Cipher.DECRYPT_MODE, key, iv);byte[] decryptedData = cipher.doFinal(encryptedData);return new String(decryptedData);}
}

7. 网络编程设计模式 🎨

7.1 Reactor模式

public class Reactor implements Runnable {final Selector selector;final ServerSocketChannel serverSocket;Reactor(int port) throws IOException {selector = Selector.open();serverSocket = ServerSocketChannel.open();serverSocket.socket().bind(new InetSocketAddress(port));serverSocket.configureBlocking(false);SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT);sk.attach(new Acceptor());}public void run() {try {while (!Thread.interrupted()) {selector.select();Set<SelectionKey> selected = selector.selectedKeys();Iterator<SelectionKey> it = selected.iterator();while (it.hasNext()) {dispatch(it.next());it.remove();}}} catch (IOException ex) {ex.printStackTrace();}}void dispatch(SelectionKey k) {Runnable r = (Runnable) (k.attachment());if (r != null) {r.run();}}
}

7.2 观察者模式在网络编程中的应用

public interface NetworkEventListener {void onConnected(String clientId);void onMessageReceived(String clientId, String message);void onDisconnected(String clientId);
}public class NetworkEventManager {private List<NetworkEventListener> listeners = new ArrayList<>();public void addListener(NetworkEventListener listener) {listeners.add(listener);}public void removeListener(NetworkEventListener listener) {listeners.remove(listener);}protected void fireOnConnected(String clientId) {for (NetworkEventListener listener : listeners) {listener.onConnected(clientId);}}// ... 其他事件触发方法
}

8. 性能优化技巧 🚀

8.1 网络性能调优

  1. 缓冲区优化
// 使用直接缓冲区
ByteBuffer buffer = ByteBuffer.allocateDirect(65536);// 使用合适的缓冲区大小
int bufferSize = socket.getReceiveBufferSize();
  1. 连接池管理
public class ConnectionPool {private static final int MAX_POOL_SIZE = 20;private Queue<Socket> pool = new ConcurrentLinkedQueue<>();public Socket acquire() {Socket socket = pool.poll();if (socket == null || socket.isClosed()) {socket = createNewConnection();}return socket;}public void release(Socket socket) {if (pool.size() < MAX_POOL_SIZE) {pool.offer(socket);} else {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}
}

9. 实战示例:高性能聊天服务器 💬

public class ChatServer {private static final int PORT = 8892;private final Map<String, SocketChannel> clients = new ConcurrentHashMap<>();private final Selector selector;public ChatServer() throws IOException {this.selector = Selector.open();ServerSocketChannel serverSocket = ServerSocketChannel.open();serverSocket.bind(new InetSocketAddress(PORT));serverSocket.configureBlocking(false);serverSocket.register(selector, SelectionKey.OP_ACCEPT);}public void start() {try {System.out.println("聊天服务器启动在端口 " + PORT);while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iter = selectedKeys.iterator();while (iter.hasNext()) {SelectionKey key = iter.next();if (key.isAcceptable()) {handleNewConnection();}if (key.isReadable()) {handleMessage(key);}iter.remove();}}} catch (IOException e) {e.printStackTrace();}}// ... 实现详细的处理方法
}

10. 写在最后 📝

咱们深入探讨了Java网络编程的高级特性和最佳实践,从基础的Socket编程到高级的NIO和安全编程,为构建强大的网络应用提供了全面的指导。

在未来的网络编程发展中,我们可以期待:

  1. 更高效的异步编程模型
  2. 更简单的响应式编程API
  3. 更强大的安全机制
  4. 更完善的云原生支持

学习资源推荐

  1. Java Network Programming, 4th Edition (O’Reilly)
  2. Netty in Action
  3. Java NIO (Ron Hitchens)

练习项目建议

  1. 实现一个支持多人的聊天室
  2. 开发一个简单的HTTP服务器
  3. 构建一个文件传输系统
  4. 设计一个基于WebSocket的实时通讯应用

记住:优秀的网络程序不仅要能正常工作,还要考虑性能、安全性和可维护性。持续学习和实践是提升网络编程能力的关键!

如果你觉得这篇文章有帮助,欢迎点赞转发,也期待在评论区看到你的想法和建议!👇

咱们下期见 !

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

只因把 https 改成 http,带宽减少了 70%!

起因 是一个高并发的采集服务上线后&#xff0c;100m的上行很快就被打满了。因为这是一条专线&#xff0c;并且只有这一个服务在使用&#xff0c;所以可以确定就是它导致的。 但是&#xff01;这个请求只是一个 GET 请求&#xff0c;同时并没有很大的请求体&#xff0c;这是为…

黑马官网最新2024前端就业课V8.5笔记---CSS篇(2)

盒子模型 画盒子 目标:使用合适的选择器画盒子 属性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"view…

认识单双链表

认识单双链表 前置知识&#xff1a;无&#xff0c;会的可以直接跳过。 基本概念 内存空间是所有程序的公共资源&#xff0c;在一个复杂的系统运行环境下&#xff0c;空闲的内存空间可能散落在内存各处。我们知道&#xff0c;存储数组的内存空间必须是连续的&#xff0c;而当…

导师双选系统开发新解:Spring Boot技术

摘 要 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较高要求&#xff0c;因此传统管理方式就不适合。为了让导师选择信息的管理模式进行升级&#xff0c;也为了更好的维护导师选择信息&#xff0c;卓越导师双选系统的开发运用就显得很有必要。并且通…

木马病毒相关知识

1、 木马的定义 相当于一个远控程序&#xff08;一个控制端[hack]、一个被控端[受害端]&#xff09; 在计算机系统中&#xff0c;“特洛伊木马”指系统中被植入的、人为设计的程序&#xff0c;目的包括通过网终远程控制其他用户的计算机系统&#xff0c;窃取信息资料&#xff0…

Oracle简介、环境搭建和基础DML语句

第一章 ORACLE 简介 1.1 什么是 ORACLE ORACLE数据库系统是美国ORACLE 公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是目前最流行的客户/服务器体系结构的数据库之一。 英文官网&#xff1a;Database | Oracle 中文官网&#xff…

【React】初学React

A. react中如何创建元素呢&#xff1f; 说明一点&#xff1a; 属性都改为驼峰形式&#xff08;无障碍属性aria-*除外&#xff09;&#xff0c; class改成className 创建元素 B. 变量或表达式如何表示呢&#xff1f;大括号{ }包起来 变量值用大括号包裹 C. 元素和组件的区别 元素…

GD32H7XX软件触发中断

这个在demo里没找到&#xff0c;有相关编程要求的可以直接套用。 先简单阐述一下&#xff0c;实际上就是用几个位来控制一根软件触发通道的中断情况。以GD32H7系列为例&#xff0c;中断使能寄存器EXTI_INTEN就是是否允许这条线启用中断&#xff0c;和平时的enableDMA一个意思。…

Leetcode 第 422 场周赛题解

Leetcode 第 422 场周赛题解 Leetcode 第 422 场周赛题解题目1&#xff1a;3340. 检查平衡字符串思路代码复杂度分析 题目2&#xff1a;3341. 到达最后一个房间的最少时间 I思路代码复杂度分析 题目3&#xff1a;3342. 到达最后一个房间的最少时间 II思路代码复杂度分析 题目4&…

Memento 备忘录模式

备忘录模式 意图结构适用性实例Java Web开发中的简单示例Originator 类Memento 类Caretaker 类 文本编辑器示例1. Originator (发起人) - TextEditor2. Memento (备忘录) - TextMemento3. Caretaker (负责人) - History4. 使用示例输出 备忘录模式&#xff08;Memento Pattern&…

导入项目时微信开发者工具如何自动识别项目APPID

一、需求 当我们在公司拉取小程序项目的时候&#xff0c;经常会在微信开发者工具中导入项目&#xff0c;需要我们手动输入自己的appid非常麻烦&#xff0c;我们可以用在导入项目的时候自动识别公司的appid 二、步骤 2.1 使用Hbuilder工具编译项目 编译成功后会有一个unpacka…

小语言模型介绍与LLM的比较

小模型介绍 小语言模型&#xff08;SLM&#xff09;与大语言模型&#xff08;LLM&#xff09;相比&#xff0c;具有不同的特点和应用场景。大语言模型通常拥有大量的参数&#xff08;如 GPT-3 拥有 1750 亿个参数&#xff09;&#xff0c;能够处理复杂的自然语言任务&#xff…

17.快递物流仓库管理系统(基于springboot和vue)

目录 1.系统的受众说明 2.系统详细设计 2.1 需求分析 2.2 系统功能设计 2.3 开发环境分析 ​​​​​​​2.4 E-R图设计 2.5 数据库设计 3. 系统实现 3.1 环境搭建 ​​​​​​​3.2 员工信息管理模块 3.3 销售订单信息管理模块 ​​​​​​​3.4 图表分析模块…

Shortcut Learning in In-Context Learning: A Survey

为我们的综述打一打广告&#xff0c;目前是初级版本&#xff0c;欢迎各位批评指正&#xff01;后续的论文列表、测评基准会在Github更新[/(ㄒoㄒ)/~~最近比较忙容许我拖一拖] 这里是arxiv链接&#xff1a;Linking!!! Abstract&#xff1a;捷径学习是指模型在实际任务中使用简单…

13.useTimeout

在 React 应用中&#xff0c;延迟执行某些操作是一个常见需求。传统的 setTimeout 在函数组件中使用可能会导致一些问题&#xff0c;如闭包陷阱或难以正确清理。useTimeout 钩子提供了一种声明式的方法来实现延迟执行&#xff0c;使得定时器的管理更加简单和可靠。这个自定义钩…

Golang gRPC

为什么要使用 gRPC&#xff1f; 我们的示例是一个简单的路线映射应用程序&#xff0c;它允许客户端获取有关路线上的特征的信息&#xff0c;创建路线摘要&#xff0c;并与服务器和其他客户端交换路线信息&#xff0c;例如交通更新。 使用 gRPC&#xff0c;我们可以在 .proto …

第三十四章 Vue路由进阶之声明式导航(导航高亮)

目录 一、导航高亮 1.1. 基于语法 1.2. 主要代码 二、声明式导航的两个类名 2.1. 声明式导航类名匹配方式 2.2. 声明式导航类名样式自定义 ​2.3. 核心代码 一、导航高亮 1.1. 基于语法 在Vue中通过VueRouter插件&#xff0c;我们可以非常简单的实现实现导航高亮效果…

群控系统服务端开发模式-应用开发-系统配置开发

其实在前面的章节中就已经提到过系统配置开发这块&#xff0c;包括建表及数据层开发都已完毕《群控系统服务端开发模式-应用开发-业务架构逻辑开发BaseAPI继续开发一》&#xff0c;今天在这里只要把系统配置控制层及验证层开发完毕就可以咯。 一、路由配置 因它是固定数据&…

第七部分:1. STM32之ADC实验--单通道实验

主要利用一个模拟量的电位器来实时改变电压值&#xff0c;通过STM32自带的ADC通道来采集这个数据&#xff0c;并打印出来&#xff01; 一句话&#xff0c;学完STM32&#xff0c;我就往南走&#xff0c;我的工资只有5000.~~~~Whappy

Ubuntu20.04两种安装及配置中文界面、输入法、换源、共享文件夹实现,及注意事项

虚拟机安装法 1、新建虚拟机&#xff0c;自定义下一步 任意指定路径 提高处理器数量能加快系统响应 完成以后不要运行&#xff0c;添加镜像文件 导入镜像文件&#xff0c;点击浏览 选择后打开->确认->运行虚拟机 出现这种情况就需要检查虚拟机的配置&#xff0c;操作系统…