当前位置: 首页 > news >正文

JavaEE-网络编程套接字(UDP/TCP)


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


下面写一个简单的UDP客户端服务器流程
思路:
对于服务器端:读取请求,并解析–> 根据解析出的请求,做出响应(这里是一个回显,)–>把响应写回客户端
对于客户端:从控制台读取用户输入的内容–>从控制台读取用户输入的内容–>从控制台读取用户输入的内容–>将其显示在屏幕上
全部代码如下:
服务器端:

package network;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//UDP的回显服务器   客户端发出的请求是啥,服务器返回的响应就是啥
public class UdpEchoServer {private DatagramSocket socket=null;//  指定服务器的portpublic UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);}//指定一个方法启动服务器public void start() throws IOException {System.out.println("服务器开始启动");while(true){// 反复的, 长期的执行针对客户端请求处理的逻辑.// 一个服务器, 运行过程中, 要做的事情, 主要是三个核心环节.//服务器这里需要接收请求//1.读取请求,并解析DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//解析String request=new String(requestPacket.getData(),0, requestPacket.getLength());//2.根据解析出的请求,做出响应(这里是一个回显,)String response=process(request);//3. 把响应写回客户端  此时需要告诉网卡,要发的内容是啥,发给谁//构造一个发送数据包DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//记录日志System.out.printf("[%s:%d]  req: %s, resp: %s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}//这里是一个回显,只需要返回这个字符串public String process(String request){return request;}public static void main(String[] args) throws IOException {UdpEchoServer udpEchoServer=new UdpEchoServer(9090);udpEchoServer.start();}
}

客户端:

package network;import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {//由于客户端的port是自动分配的,所以这里不会像服务器那样配置port//但是,客户端需要向服务器发送请求,所以,这里我们需要知道服务器的ip和portprivate DatagramSocket socket=null;private String serverIp;private int serverPort;//外部指定服务器的ip和portpublic UdpEchoClient(String ip,int port) throws SocketException {this.serverIp=ip;this.serverPort=port;//客户端的port是自动分配的socket=new DatagramSocket();}// 让这个客户端反复的从控制台读取用户输入的内容. 把这个内容构造成 UDP 请求, 发给服务器. 再读取服务器返回的 UDP 响应// 最终再显示在客户端的屏幕上.public void  start() throws IOException {Scanner scanner=new Scanner(System.in);System.out.println("客户端开始启动");while(true){//1. 从控制台读取用户输入的内容System.out.println("->");String requset=scanner.next();//2.构造请求对象,发送给服务器DatagramPacket requsetPacket=new DatagramPacket(requset.getBytes(),requset.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requsetPacket);//3.读取服务器的响应,并解析出其内容DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());//4 。将其显示在屏幕上System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient udpEchoClient=new UdpEchoClient("127.0.0.1",9090);//127.0.0.1 本机ipudpEchoClient.start();}
}

运行结果如下
在这里插入图片描述
对上述过程中的一些谈论和分析:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


多个客户端向一个服务器发送请求
在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


下面写一个简单的翻译服务器
在这里插入图片描述

重写的服务器端的代码如下:

package network;import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;public class UdpDictServer extends UdpEchoServer{//使用HashMap保存中英文翻译的键值对private Map<String,String> dict =new HashMap<>();//实现父类的构造方法public UdpDictServer(int port) throws SocketException {super(port);//一些原始的键值对dict.put("cat","猫");dict.put("dog","狗");dict.put("people","人");}//与原始的UdpEachServer相比,这里对于请求的处理过程是不一样的//重写process方法@Overridepublic String process(String request) {//找到对应的翻译,并返回//getOrDefault方法,找到key所对应的value值,如果没有找到,则返回defaultValue(即第二个参数)return dict.getOrDefault(request,"该词没有查询到");}public static void main(String[] args) throws IOException {UdpDictServer server=new UdpDictServer(9090);// start 不需要重新再写一遍了. 直接就复用了之前的 startserver.start();}
}

执行结果如下:

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


下面写一个基于TCP 的回显流程

思路:
服务器端:先从队列中拿到一个“连接”–> 读取请求并解析–>根据请求计算响应–>把响应写回给客户端
客户端:从控制台输入字符串–>把请求发送给服务器–>从服务器读取响应.–>把响应打印出来

全部代码如下:
服务器端代码:

package network;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;//基于TCP的回显服务器
public class TcpEachServer {private ServerSocket serverSocket=null;//绑定端口号public  TcpEachServer(int port) throws IOException {serverSocket=new ServerSocket(port);}//启动服务器public  void  start() throws IOException {System.out.println("服务器开始启动");while(true){//从管理连接的队列中拿出一个“连接”出来Socket clientSocket=serverSocket.accept();//处理这个连接内的请求processConnection(clientSocket);}}//这个方法用来处理连接中的逻辑private void processConnection(Socket clientSocket) throws IOException {//日志System.out.printf("[%s:%d] 客户端上线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());//下面开始读取请求,计算响应,返回响应  三步曲//Socket对象内部包含两种字节流对象InputStream和OutputStream,可以先把这两个对象流获// 取到,方便后续处理过程种的读写工作try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){//不同于UDP协议中的无连接,在客户端的一次连接过程中,可能涉及多次请求/响应过程//因此。这里使用一个while循环,直到该连接中的所有请求处理完毕while(true){//1,读取请求并解析Scanner scanner=new Scanner(inputStream);//hasNext的作用是,检测输入流中是否有结束输入的控制符,比如0x1A(EOF,Ctrl-Z)//用于检测一个连接是否结束if(!scanner.hasNext()){//一个连接处理完毕System.out.printf("[%s:%d] 客户端本次连接处理完毕,下线!\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}// 这个代码暗含一个约定, 客户端发过来的请求, 得是文本数据, 同时, 还得带有空白符作为分割. (比如换行这种)//next():当输入到空白符结束String request=scanner.next();//2.根据请求计算响应String response=process(request);//3. 把响应写回客户端,把OutputStream用PrintWriter(此处的PrintWriter相当于Scanner)包裹一下,便于发送数据//将outputStream和PrintWriter关联起来PrintWriter writer=new PrintWriter(outputStream);//使用 PrintWriter 的 println 方法,打印到输出流中 把响应返回给客户端.//此处用 println, 而不是 print 就是为了在结尾加上 \n . 方便客户端读取响应, 使用 scanner.next 读取.writer.println(response);//这里还需要加一个 "刷新缓冲区" 操作.将缓冲区的数据强制输出,用于清空缓冲区writer.flush();//日志 记录当前的请求和响应System.out.printf("[%s:%d]  req: %s,resp: %s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}}}//回显,只需要再返回这个字符串public String process(String requset){return requset;}public static void main(String[] args) throws IOException {TcpEachServer tcpEachServer=new TcpEachServer(9090);tcpEachServer.start();}
}

客户端代码:

package network;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoClient {private Socket socket=null;//服务器端的ip和portpublic  TcpEchoClient(String serverIp,int serverPort) throws IOException {//这个new的动作完成后,完成了tcp的建立socket=new Socket(serverIp,serverPort);}public void start() throws IOException {System.out.println("客户端启动");Scanner scannerConsole=new Scanner(System.in);//Socket对象内部包含两种字节流对象InputStream和OutputStream,可以先把这两个对象流获//   取到,方便后续处理过程种的读写工作try(InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){while(true){//1.从控制台输入字符串System.out.println("-->");String request=scannerConsole.next();//2.把请求发送给服务器  需要对request进行包装,使用PrintWriterPrintWriter printWriter=new PrintWriter(outputStream);//使用 println 带上换行. 后续服务器读取请求, 就可以使用 scanner.next 来获取了printWriter.println(request);//发送请求printWriter.flush();//3.从服务器中接收响应Scanner scannerNetwork=new Scanner(inputStream);String response=scannerNetwork.next();//4.把响应打印出来System.out.println(response);}}}public static void main(String[] args) throws IOException {TcpEchoClient tcpEchoClient=new TcpEchoClient("127.0.0.1",9090);tcpEchoClient.start();}
}

当开多个线程时,发现只有一个线程在被处理,其它线程都在等待,
在这里插入图片描述
当被处理的线程下线后,其他线程的逻辑才开始被处理
在这里插入图片描述

在这里插入图片描述
原因在于 Socket clientSocket = serverSocket.accept();和processConnection(clientSocket);都是主线程进行处理的且在同一次循环体中,只有一个clinetSocket连接被处理完后,才会去队列中accept下一个连接,为此,这里我们可以采用多线程进行处理。
在这里插入图片描述

修改为多线程后,可以看到 有多个客户端可以访问服务器
在这里插入图片描述

在这里插入图片描述
考虑到一个现实的情况,许多客户端需要频繁的访问服务器,那就是需要频繁的断开/连接,我们这里可以使用线程池
在这里插入图片描述
在这里插入图片描述
同样也可以实现多个客户端同时访问服务器。

最终的服务器的代码如下:

package network;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//基于TCP的回显服务器
public class TcpEachServer {private ServerSocket serverSocket=null;//创建一个非固定数目的线程池private ExecutorService service= Executors.newCachedThreadPool();//绑定端口号public  TcpEachServer(int port) throws IOException {serverSocket=new ServerSocket(port);}//启动服务器public  void  start() throws IOException {System.out.println("服务器开始启动");while(true){//从管理连接的队列中拿出一个“连接”出来Socket clientSocket=serverSocket.accept();//处理这个连接内的请求service.submit(new Runnable() {@Overridepublic void run() {try {processConnection(clientSocket);} catch (IOException e) {e.printStackTrace();}}});
/*            Thread t=new Thread(() ->{try {processConnection(clientSocket);} catch (IOException e) {e.printStackTrace();}});t.start();*/}}//这个方法用来处理连接中的逻辑private void processConnection(Socket clientSocket) throws IOException {//日志System.out.printf("[%s:%d] 客户端上线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());//下面开始读取请求,计算响应,返回响应  三步曲//Socket对象内部包含两种字节流对象InputStream和OutputStream,可以先把这两个对象流获// 取到,方便后续处理过程种的读写工作try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){//不同于UDP协议中的无连接,在客户端的一次连接过程中,可能涉及多次请求/响应过程//因此。这里使用一个while循环,直到该连接中的所有请求处理完毕while(true){//1,读取请求并解析Scanner scanner=new Scanner(inputStream);//hasNext的作用是,检测输入流中是否有结束输入的控制符,比如0x1A(EOF,Ctrl-Z)//用于检测一个连接是否结束if(!scanner.hasNext()){//一个连接处理完毕System.out.printf("[%s:%d] 客户端本次连接处理完毕,下线!\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}// 这个代码暗含一个约定, 客户端发过来的请求, 得是文本数据, 同时, 还得带有空白符作为分割. (比如换行这种)//next():当输入到空白符结束String request=scanner.next();//2.根据请求计算响应String response=process(request);//3. 把响应写回客户端,把OutputStream用PrintWriter(此处的PrintWriter相当于Scanner)包裹一下,便于发送数据//将outputStream和PrintWriter关联起来PrintWriter writer=new PrintWriter(outputStream);//使用 PrintWriter 的 println 方法,打印到输出流中 把响应返回给客户端.//此处用 println, 而不是 print 就是为了在结尾加上 \n . 方便客户端读取响应, 使用 scanner.next 读取.writer.println(response);//这里还需要加一个 "刷新缓冲区" 操作.将缓冲区的数据强制输出,用于清空缓冲区writer.flush();//日志 记录当前的请求和响应System.out.printf("[%s:%d]  req: %s,resp: %s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}} finally {clientSocket.close();}}//回显,只需要再返回这个字符串public String process(String requset){return requset;}public static void main(String[] args) throws IOException {TcpEachServer tcpEachServer=new TcpEachServer(9090);tcpEachServer.start();}
}

上述过程中的一些思路

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


相关文章:

JavaEE-网络编程套接字(UDP/TCP)

下面写一个简单的UDP客户端服务器流程 思路&#xff1a; 对于服务器端&#xff1a;读取请求&#xff0c;并解析–> 根据解析出的请求&#xff0c;做出响应(这里是一个回显&#xff0c;)–>把响应写回客户端 对于客户端&#xff1a;从控制台读取用户输入的内容–>从控制…...

微服务技术栈-Gateway服务网关

文章目录 前言一、为什么需要网关二、Spring Cloud Gateway三、断言工厂和过滤器1.断言工厂2.过滤器3.全局过滤器4.过滤器执行顺序 四、跨域问题总结 前言 在之前的文章中我们已经介绍了微服务技术中eureka、nacos、ribbon、Feign这几个组件&#xff0c;接下来将介绍另外一个组…...

函数形状有几种定义方式;操作符infer的作用

在 TypeScript 中&#xff0c;函数形状可以用多种方式进行定义。下面介绍了几种常用的函数形状定义方式&#xff1a; 函数声明&#xff1a; function add(a: number, b: number): number {return a b; }在函数声明中&#xff0c;我们直接使用 function 关键字来声明函数&…...

Java / MybatisPlus:JSON处理器的应用,在实体对象中设置对象属性,对象嵌套对象

1、数据库设计 2、定义内部的实体类 /*** Author lgz* Description* Date 2023/9/30.*/ Data // 静态构造staticName&#xff0c;方便构造对象并赋予属性 AllArgsConstructor(staticName "of") NoArgsConstructor ApiModel(value "亲友", description …...

力扣 -- 1027. 最长等差数列

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int longestArithSeqLength(vector<int>& nums) {int nnums.size();int ret2;unordered_map<int,int> hash;//这里可以先把nums[0]存进哈希表中&#xff0c;方便后面i从1开始遍历hash[num…...

正则验证用户名和跨域postmessage

正则验证用户名 字母数字符号大小写8-14匹配用户名的 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, initial-scale1"><title>form</title> …...

jsbridge实战1:xcode swift 构建iOS app

[[toc]] 环境安装 macOs: 10.15.5 xcode: 11.6 demo:app 创建 hello world iOS app 创建工程步骤 选择&#xff1a;Create a new Xcode project选择&#xff1a;iOS-> single View App填写&#xff1a; project name: swift-app-helloidentifer: smile 包名language: s…...

零基础部署nginx mysql springboot

参考&#xff1a;写给开发人员看的Docker干货&#xff0c;零基础部署nginx mysql springboot 一、连接linux 阿里云 参考&#xff1a;部署到Linux 可能需要购买&#xff1a;购买链接 二、安装docker # 先切换到root用户下 sudo su# 更新apt-get&#xff0c;保证apt-get最新…...

6-3 模式匹配

description 给出主串s和模式串t&#xff0c;其长度均不超过1000。本题要求实现一个函数BF(string s, string t)&#xff0c;求出模式串t在主串s中第一次出现的位置&#xff08;从0开始计算&#xff09;&#xff0c;如果在s中找不到t&#xff0c;则输出-1。 函数接口定义&…...

SQL JOIN 时 USING 和 ON 的异同

在数据表做 join 时&#xff0c;即可以用 using&#xff0c;也可以用 on。有什么异同点呢。 ON 是更加普遍的用法&#xff0c;可以连接表 On 一个字段&#xff0c;多个字段&#xff0c;甚至一个条件表达式。举例 SELECT * FROM world.City JOIN world.Country ON (City.Cou…...

安全学习_开发相关_JNDI介绍(注入)RMILDAP服务

文章目录 参考&本节目的JNDI概念-RMI&LDAP服务调用检索&#xff1a;在RMI服务中调用了InitialContext.lookup()的常用类有&#xff1a;在LDAP服务中调用了InitialContext.lookup()的常用类有&#xff1a; JNDI注入-使用工具生成远程调用JNDI远程调用-工具&#xff08;j…...

C#学生选课及成绩查询系统

一、项目背景 学生选课及成绩查询系统是一个学校不可缺少的部分&#xff0c;传统的人工管理档案的方式存在着很多的缺点&#xff0c;如&#xff1a;效率低、保密性差等&#xff0c;所以开发一套综合教务系统管理软件很有必要&#xff0c;它应该具有传统的手工管理所无法比拟的…...

【C语言】利用数组处理批量数据(一维数组和二维数组)

前言:在前面学习的程序中使用的变量都属于基本类型&#xff0c;例如整型、字符型、浮点型数据&#xff0c;这些都是简单的数据类型。对于简单的问题&#xff0c;使用这些简单的数据类型就可以了。但是对于有些需要处理的数据&#xff0c;只用以上简单的数据类型是不够的&#x…...

WPF中, 如何将控件的触发事件绑定到ViewModel

在DataGrid 等控件中, 有很多这种带闪电符号的触发事件. 如果用传统的事件驱动, 则直接在后台中建立 一个private PropertyChanged(Sender s, EventAgars Args) 即可. 但是如果需要绑定到ViewModel的话? 应该怎么做? 带闪电符号的触发事件 实现viewModel绑定前端触发事件的…...

解决Qt msvc编译器 中文显示乱码问题

第一步&#xff1a;代码文件选择用utf8编码带bom。第二步&#xff1a;在有中文汉字的代码文件顶部加一行&#xff08;一般是cpp文件&#xff09; #pragma execution_character_set(“utf-8”) 可以考虑放在head.h中&#xff0c;然后需要的地方就引入head头文件就行&#xff0c;…...

JAVA面经整理(7)

一)什么是AQS&#xff1f; 1)AQS也被称之为是抽象同步队列&#xff0c;它是JUC包底下的多个组件的底层实现&#xff0c;Lock&#xff0c;CountDownLatch和Semphore底层都使用到了AQS AQS的核心思想就是给予一个等待队列和同步状态来实现的&#xff0c;它的内部使用一个先进先出…...

CentOS7使用技巧

1、防火墙相关 关闭防火墙 systemctl stop firewalld 关闭防火墙开机自启 systemctl disable firewalld.service 查看防火墙状态 systemctl status firewalld...

Nature Machine Intelligence | “化学元素知识+功能提示”双驱动,探索分子预测新方法

论文题目&#xff1a;Knowledge graph-enhanced molecular contrastive learning with functional prompt 论文链接&#xff1a;https://doi.org/10.1038/s42256-023-00654-0 项目地址&#xff1a;GitHub - HICAI-ZJU/KANO: Code and data for the Nature Machine Intelligence…...

CppCheck静态代码检查工具教程【Windows和Linux端】

目录 1、背景 2、特性介绍 2.1、检查结果 2.2、检查范围 2.3、支持的检查规则&#xff08;列举一些&#xff09;: 2.4、自定义规则 3、linux 端 4、windows 端 1、背景 最近调研了几款 c/c 代码静态检查工具&#xff0c;包括 cppcheck、cpplint、cppdepend、splint、ts…...

W25Q128芯片手册精读

文章目录 前言1. 概述2. 特性3. 封装类型和引脚配置3.1 8焊盘WSON 8x6 mm3.2其他封装 4. 引脚描述4.1 片选4.2 串行数据输入输出4.3 写保护4.4 保持脚4.5 时钟 5. 块图6. 功能描述6.1 SPI功能6.1.1 标准SPI6.1.2 双通道SPI6.1.3 四通道SPI6.1.4 保持功能 6.2 写保护6.2.1 写保护…...

Java 开发 日志技术

1.概述为什么要在程序中记录日志呢&#xff1f;便于追踪应用程序中的数据信息、程序的执行过程。便于对应用程序的性能进行优化。便于应用程序出现问题之后&#xff0c;排查问题&#xff0c;解决问题。便于监控系统的运行状态。2.日志框架JUL&#xff1a;这是JavaSE平台提供的官…...

基于FLUX.2-klein-base-9b-nvfp4的Java后端服务集成指南

基于FLUX.2-klein-base-9b-nvfp4的Java后端服务集成指南 最近在做一个内容创作平台的后台重构&#xff0c;产品经理提了个需求&#xff0c;希望用户上传的草图或者简单的线框图&#xff0c;能自动转换成更精美的概念图。这要是放在以前&#xff0c;要么找设计师手动处理&#…...

M2LOrder模型轻量化对比:Web端与移动端部署可行性评估

M2LOrder模型轻量化对比&#xff1a;Web端与移动端部署可行性评估 最近在折腾一个挺有意思的事儿&#xff0c;就是把一个原本跑在服务器上的AI模型&#xff0c;想办法塞到手机里或者浏览器里。这个模型叫M2LOrder&#xff0c;主要干的是情感分析的活儿。你可能会想&#xff0c…...

WarcraftHelper:魔兽争霸3兼容性问题的全方位解决方案

WarcraftHelper&#xff1a;魔兽争霸3兼容性问题的全方位解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 问题发现&#xff1a;现代系统下的经…...

终极免费方案:3分钟掌握ViGEmBus虚拟游戏手柄驱动的完整部署与应用

终极免费方案&#xff1a;3分钟掌握ViGEmBus虚拟游戏手柄驱动的完整部署与应用 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否曾为游戏不支持你的手柄…...

PDF-Parser-1.0零售业应用:促销海报信息提取

PDF-Parser-1.0零售业应用&#xff1a;促销海报信息提取 1. 引言 零售行业的促销活动总是让人又爱又恨。爱的是能带来销量增长&#xff0c;恨的是每次活动都要处理海量的促销海报——设计、印刷、分发&#xff0c;最后还要手动录入成千上万的商品信息、价格数据和活动规则。一…...

Qwen3-ASR-1.7B部署教程:基于device_map=‘auto‘的GPU智能分配实践

Qwen3-ASR-1.7B部署教程&#xff1a;基于device_mapauto的GPU智能分配实践 想不想把电脑变成一个能听懂人话的智能助手&#xff1f;无论是会议录音、视频字幕&#xff0c;还是采访记录&#xff0c;都能快速、准确地转成文字&#xff0c;而且完全在本地运行&#xff0c;不用担心…...

Electron应用打包体积优化实战:从30MB瘦身到15MB,我的electron-builder.yml配置清单

Electron应用打包体积优化实战&#xff1a;从30MB瘦身到15MB 最近在优化一个Electron应用的打包体积时&#xff0c;发现初始生成的安装包竟然达到了30MB。经过一系列配置调整和优化&#xff0c;最终成功将体积缩减到15MB。这个过程让我深刻体会到&#xff0c;electron-builder…...

攻克Atlas OS中Xbox应用登录错误0x89235107的完整方案

攻克Atlas OS中Xbox应用登录错误0x89235107的完整方案 【免费下载链接】Atlas &#x1f680; An open and lightweight modification to Windows, designed to optimize performance, privacy and security. 项目地址: https://gitcode.com/GitHub_Trending/atlas1/Atlas …...

技术深度:Windows任务栏透明化引擎TranslucentTB架构原理与高级配置指南

技术深度&#xff1a;Windows任务栏透明化引擎TranslucentTB架构原理与高级配置指南 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB Tran…...