Java网络套接字
在Java的开发中,有一个很重要!很重要!很重要!的东西,叫做网络套接字,它被广泛的用来二次开发服务,比如大数据中台的服务链路调用等。
它的实现原理是依靠三次握手来完成通信的建立,也是TCP(传输控制协议)连接建立过程中的一个重要机制。TCP是一种可靠的、面向连接的传输层协议,它在正式传输数据之前,需要通过三次握手来建立一个可靠的连接。这个过程涉及到客户端和服务器之间的交互,具体步骤如下:、
第一次握手:客户端向服务器发送一个SYN(同步序列编号)报文段,请求建立连接。这个报文段中,SYN标志位被设置为1,同时客户端会随机生成一个初始序列号(seq)作为自己的起始序号,并将其发送给服务器。此时,客户端进入SYN_SEND状态,等待服务器的确认。
第二次握手:服务器收到客户端的SYN报文段后,会回复一个SYN-ACK(同步-确认)报文段给客户端。在这个报文段中,SYN和ACK标志位都被设置为1,表示服务器同意建立连接,并同步自己的序列号。同时,服务器会确认客户端的序列号,即在ACK字段中填写客户端的序列号加1(作为确认号ack)。此时,服务器进入SYN_RCVD状态。
第三次握手:客户端收到服务器的SYN-ACK报文段后,会发送一个ACK(确认序列编号)报文段给服务器,以确认连接建立。在这个报文段中,ACK标志位被设置为1,同时确认号ack为服务器的序列号加1。此时,客户端和服务器都进入ESTABLISHED状态,表示连接已经成功建立,可以开始传输数据了。
三次握手的目的和意义在于:
确保双方通信能力正常:通过三次握手,客户端和服务器可以相互确认对方的发送和接收能力是否正常,从而确保连接的可靠性。
同步双方初始序列号:在三次握手过程中,双方会交换并确认各自的初始序列号,这是为了后续数据传输时能够正确地进行序号匹配和确认。
防止已失效的连接请求:三次握手还可以防止因网络延迟或丢包等原因导致的已失效的连接请求被错误地接受。
总的来说,三次握手是TCP连接建立过程中的一个关键步骤,它确保了连接的可靠性和双方通信能力的正常性。在开发Java网络套接字时,理解并掌握三次握手的原理和实现方式是非常重要的。
涉及到的类都在java.net包下,如果你是刚接触套接字,你可以用下面这个最简单的案例来感受一下套接字的能力
首先准备一个服务端:
package one;import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的服务端,用来处理所有客户端的链接请求 <br/>* ServerSoc*/
public class ServerSoc {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(9000);System.out.println("等待连接。。。。。");//accept方法会阻塞进程,检测到有客户端连接则放行Socket s1 = ss.accept();System.out.println("连接成功");//向客户端输出一句话,因此这里获取对客户端的输出流OutputStream os = s1.getOutputStream(); //获得输出流byte[] b = "客户端,客户端,我是服务器,收到请回答".getBytes();os.write(b);os.flush();//必须刷一下,不然写不进去//关闭资源os.close();s1.close(); ss.close();//关闭自己} catch (IOException e) {e.printStackTrace();}}}
然后是客户端:
package one;import java.io.InputStream;
import java.net.Socket;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的客户端,用来链接服务端,面向用户操作 <br/>* ClientSoc*/
public class ClientSoc {public static void main(String[] args) {try {Socket s = new Socket("127.0.0.1", 9000);//客户端要读取服务端的信息,所以这里获取连接中的输入流InputStream is = s.getInputStream();byte[] b = new byte[100];//读取int num = is.read(b);String msg = new String(b, 0, num);System.out.println(msg);//关资源is.close();s.close();} catch (Exception e) {e.printStackTrace();}}}
启动的时候,要先启动服务端,然后在启动客户端,你就可以看到如下的输出


同样的,客户端也可以在接收完信息后,给服务端也写一句话,你只需要在上面的代码中加上各自的输入和输出流即可
服务端:
package one;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的服务端,用来处理所有客户端的链接请求 <br/>* ServerSoc*/
public class ServerSoc {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(9000);System.out.println("等待连接。。。。。");//accept方法会阻塞进程,检测到有客户端连接则放行Socket s1 = ss.accept();System.out.println("连接成功");//向客户端输出一句话,因此这里获取对客户端的输出流OutputStream os = s1.getOutputStream(); //获得输出流byte[] b = "客户端,客户端,我是服务器,收到请回答".getBytes();os.write(b);os.flush();//必须刷一下,不然写不进去/*服务端这里多了从客户端读消息的输入流也就是上面的代码向客户端写一句话之后服务端从连接的客户端中获取输入流从而等待客户端给服务端发送的信息*/InputStream in = s1.getInputStream();byte[] b1 = new byte[100];int read = in.read(b1);String msg = new String(b1, 0, read);System.out.println(msg);//关闭资源in.close();os.close();s1.close();ss.close();} catch (IOException e) {e.printStackTrace();}}}
客户端:
package one;import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的客户端,用来链接服务端,面向用户操作 <br/>* ClientSoc*/
public class ClientSoc {public static void main(String[] args) {try {Socket s = new Socket("127.0.0.1", 9000);//客户端要读取服务端的信息,所以这里获取连接中的输入流InputStream is = s.getInputStream();byte[] b = new byte[100];//读取int num = is.read(b);String msg = new String(b, 0, num);System.out.println(msg);/*客户端这里在接收完服务端的信息后向服务端写入一条信息*/OutputStream out = s.getOutputStream();byte[] b1 = "服务器,服务器,我是客户端,收到请回答".getBytes();out.write(b1);out.flush();//必须刷一下,不然写不进去//关资源out.close();is.close();s.close();} catch (Exception e) {e.printStackTrace();}}}
同样的,先启动服务端,然后启动客户端连接,就会得到如下输出


上面这两个案例,可以让你很方便的了解到Java提供的网络套接字能力,当然这不是全部,你还可以获取客户端的ip等等,这些都可以办到。但是上面的案例中有着写入顺序的限制,也就是无论那边都不能同时先发信息或接受,不然流就拥堵了
那么怎么能够实现基本的双向通道?来实现一对一正常对话的效果,可以用如下的代码实现
服务端:
package one;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的服务端,用来处理所有客户端的链接请求 <br/>* ServerSoc*/
public class ServerSoc {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(9000);System.out.println("等待连接。。。。。");//accept方法会阻塞进程,检测到有客户端连接则放行Socket s1 = ss.accept();System.out.println("连接成功");//获取来自客户端的输入和输出流,向客户端发送与接收信息BufferedReader in = new BufferedReader(new InputStreamReader(s1.getInputStream()));PrintWriter out = new PrintWriter(s1.getOutputStream());Scanner input = new Scanner(System.in);//服务端获取控制台输入的扫描器while(true){//服务端先开始写信息发给客户端String serverMsg = input.nextLine();out.println(serverMsg);out.flush();//发送完消息后,进入等待发消息的状态String clientMsg = in.readLine();System.out.println(clientMsg);}//关闭资源
// in.close();
// out.close();
// s1.close();
// ss.close();} catch (IOException e) {e.printStackTrace();}}}
客户端:
package one;import java.io.*;
import java.net.Socket;
import java.util.Scanner;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的客户端,用来链接服务端,面向用户操作 <br/>* ClientSoc*/
public class ClientSoc {public static void main(String[] args) {try {Socket s = new Socket("127.0.0.1", 9000);//客户端一样,获取服务端的输入和输出流,向服务端端发送与接收信息BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter out = new PrintWriter(s.getOutputStream());Scanner input = new Scanner(System.in);//服务端获取控制台输入的扫描器while(true){//等待服务端发来的消息String serverMsg = in.readLine();System.out.println(serverMsg);//接收完消息,进入向服务端写数据的状态String clientMsg = input.nextLine();out.println(clientMsg);out.flush();}//关资源
// out.close();
// in.close();
// s.close();} catch (Exception e) {e.printStackTrace();}}}
启动还是一样的顺序,先器服务端,并先由服务端发送消息


上面的案例,虽然初步的让服务端和客户端都能发送和接收消息,但是很明显,仍然没有摆脱需要有一方先写,不能一起先写的限制,而且还是只能一句一句的来,因为用的是死循环,当然至于那一方先写是你自己决定的。那么怎么能够彻底摆脱这个问题,这就要用到多线程了,你可以把接收信息的流程放在子线程里面,如下
服务端:
package one;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的服务端,用来处理所有客户端的链接请求 <br/>* ServerSoc*/
public class ServerSoc {public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(9000);System.out.println("等待连接。。。。。");//accept方法会阻塞进程,检测到有客户端连接则放行Socket s1 = ss.accept();System.out.println("连接成功");//获取客户端的输入和输出流,向客户端发送与接收信息BufferedReader in = new BufferedReader(new InputStreamReader(s1.getInputStream()));PrintWriter out = new PrintWriter(s1.getOutputStream());Scanner input = new Scanner(System.in);//服务端获取控制台输入的扫描器/*将双方的接收放在子线程中*/new Thread(new Runnable() {@Overridepublic void run() {String clientMsg = null;try {while (true){clientMsg = in.readLine();System.out.println(clientMsg);}} catch (IOException e) {throw new RuntimeException(e);}}}).start();//主线程正常进入死循环写信息while(true){String serverMsg = input.nextLine();out.println(serverMsg);out.flush();}//关闭资源
// in.close();
// out.close();
// s1.close();
// ss.close();} catch (IOException e) {e.printStackTrace();}}}
客户端:
package one;import java.io.*;
import java.net.Socket;
import java.util.Scanner;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的客户端,用来链接服务端,面向用户操作 <br/>* ClientSoc*/
public class ClientSoc {public static void main(String[] args) {try {Socket s = new Socket("127.0.0.1", 9000);//客户端一样,获取服务端的输入和输出流,向服务端端发送与接收信息BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter out = new PrintWriter(s.getOutputStream());Scanner input = new Scanner(System.in);//服务端获取控制台输入的扫描器/*将双方的接收放在子线程中*/new Thread(new Runnable() {@Overridepublic void run() {String clientMsg = null;try {while (true){clientMsg = in.readLine();System.out.println(clientMsg);}} catch (IOException e) {throw new RuntimeException(e);}}}).start();//主线程正常进入死循环写信息while(true){String clientMsg = input.nextLine();out.println(clientMsg);out.flush();}//关资源
// out.close();
// in.close();
// s.close();} catch (Exception e) {e.printStackTrace();}}}
这次启动服务端和客户端后,就可以实现畅通无阻的对话了


上面的案例始终是但对单的,那么怎么实现群聊呢?其实现在就很简单了,不需要动客户端,让它保持现状,只需要改造一下服务端即可。上面的所有案例中,服务端其实有点不务正业了,只不过为了简化代码,强行给它写了手动输入并发送的代码,兼职一个客户端的身份相互直接对话,但其实它只需要负责接收客户端的消息,并按照要求发给所有客户端连接即可,要完成这样的流程需要对服务端做出如下更改
首先抽离服务端中所有的客户端流程,并编写所有服务端业务
package one;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的服务端,用来处理所有客户端的链接请求 <br/>* ServerSoc*/
public class ServerSoc {//服务端持有一个所有链接的容器集合public static ArrayList<Socket> connections = new ArrayList<Socket>();//服务端群发信息方法,参数是要发送的消息public static void sendAll(String s) throws IOException {if (connections != null) {for (int i = 0;i<connections.size();i++) { //遍历Socket集合//获取每个socket的输出流PrintWriter pw = new PrintWriter( connections.get(i).getOutputStream() );//使用每个输出流发送同一条消息pw.println(s);pw.flush();//这里有个重点!!不能关流,因为要不停的监听消息并发送,所以不能再这里关流}}}public static void main(String[] args) {try {ServerSocket ss = new ServerSocket(9000);//服务端等待所有的连接while (true){System.out.println("等待新连接。。。。。");//accept检测到链接之后将这个套接字对象放入容器并且为每个连接启动一个监听读取的线程Socket s1 = ss.accept();connections.add(s1);new ServerThreadForClient(s1).start();System.out.println("连接成功,当前所以连接如下--》");System.out.println(connections);}} catch (IOException e) {e.printStackTrace();}}}
为每一个连接启动一个监听消息的线程类:
package one;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: <br/>* ServerThreadForClient 用来承载服务端对每个连接的发送消息处理*/
public class ServerThreadForClient extends Thread{private Socket s = null;public ServerThreadForClient(Socket adds){this.s = adds;}/*** 描述: 为一个连接启动发出消息的监听 <br/>* 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 参数: <br/>* 返回值: <br/>*/@Overridepublic void run() {try {BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));String clientMsg = null;while (true){clientMsg = in.readLine();//调用服务端的方法向所有的客户端发送消息ServerSoc.sendAll(clientMsg);}} catch (IOException e) {throw new RuntimeException(e);}}
}
客户端保持不变:
package one;import java.io.*;
import java.net.Socket;
import java.util.Scanner;/*** 作者: wangyang <br/>* 创建时间: 2025/1/2 <br/>* 描述: 网络套接字的客户端,用来链接服务端,面向用户操作 <br/>* ClientSoc*/
public class ClientSoc {public static void main(String[] args) {try {Socket s = new Socket("127.0.0.1", 9000);System.out.println("客户端连接服务器成功");//客户端一样,获取服务端的输入和输出流,向服务端端发送与接收信息BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter out = new PrintWriter(s.getOutputStream());Scanner input = new Scanner(System.in);//服务端获取控制台输入的扫描器/*将双方的接收放在子线程中*/new Thread(new Runnable() {@Overridepublic void run() {String clientMsg = null;try {while (true){clientMsg = in.readLine();System.out.println(clientMsg);}} catch (IOException e) {throw new RuntimeException(e);}}}).start();//主线程正常进入死循环写信息while(true){String clientMsg = input.nextLine();out.println(clientMsg);out.flush();}} catch (Exception e) {e.printStackTrace();}}}
启动服务端后,启动多个客户端,就可以看到如下效果



到此,Java套接字的基本应用就介绍完了,可以自己以此为基础衍生很多有意思的小程序,市面上也有很多现成的类库和架构,来完成不同的能力,比如上面的socket其实是一种二进制接口,想要完成丰富的能力需要写很复杂的代码,而Springboot提供了websocket用来在web的基础上完成套接字的实现,从而实现在线客服等能力的支持
相关文章:
Java网络套接字
在Java的开发中,有一个很重要!很重要!很重要!的东西,叫做网络套接字,它被广泛的用来二次开发服务,比如大数据中台的服务链路调用等。 它的实现原理是依靠三次握手来完成通信的建立,…...
2025差旅平台推荐:一体化降本30%
医药行业因其高度专业化的特点,同时在运营过程中又极为依赖供应链和销售网络,因此差旅管理往往成为成本控制的重要环节。本期,我们以差旅平台分贝通签约伙伴——某知名药企为例,探讨企业如何通过差旅一体化管理,在全流…...
多个DataV遍历生成
DataV是数据可视化工具 与Echart类似 相对Echart图标边框 装饰可选官网DataV 安装 npm install kjgl77/datav-vue3main.ts import DataVVue3 from kjgl77/datav-vue3 app.use(DataVVue3)多个DataV遍历生成 Vue3viteDataV为例:<template><div w50rem h25rem flex&qu…...
mysql_real_connect的概念和使用案例
mysql_real_connect 是 MySQL C API 中的一个函数,用于建立一个到 MySQL 数据库服务器的连接。这个函数尝试建立一个连接,并根据提供的参数进行连接设置。 概念 以下是 mysql_real_connect 函数的基本概念: 函数原型:MYSQL *my…...
Python性能分析深度解析:从`cProfile`到`line_profiler`的优化之路
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在软件开发过程中,性能优化是提升应用质量和用户体验的关键环节。Python作为广泛应用的高级编程语言,其性能分析工具为开发者提供了强大的…...
Momentum Contrast for Unsupervised Visual Representation Learning论文笔记
文章目录 论文地址动量队列对比学习的infoNCE loss为什么需要动量编码器对比学习moco方法中的动量Encoder为什么不能与梯度Encoder完全相同为什么动量编码器和梯度编码器不能完全相同?总结: 我理解,正负样本应该经过同一个encoder,…...
用户界面的UML建模07
4.2 抽象表示层的行为(Abstract Presentation Behaviour) AbstractForm 类定义了一组如下所示的四种操作: showForm() , getData() , sendConfirmation() 和sendCancellation()。在该阶段的设计过程(desig…...
Node.js中使用Joi 和 express-joi-validation进行数据验证和校验
在进行项目开发的过程中,很多时候系统对用户输入的数据会进行严格校验的,通常我们会以“前端校验为辅,后端校验为主”的思想进行校验处理。 后端接口校验的时候,是只能一直使用if进行逻辑判断呢,还是有更加方便的方法…...
InstructGPT:基于人类反馈训练语言模型遵从指令的能力
大家读完觉得有意义记得关注和点赞!!! 大模型进化树,可以看到 InstructGPT 所处的年代和位置。来自 大语言模型(LLM)综述与实用指南(Amazon,2023) 目录 摘要 1 引言 …...
jrc水体分类对水体二值掩码修正
使用deepwatermap生成的水体二值掩码中有部分区域由于被云挡住无法识别,造成水体不连续是使用jrc离线数据进行修正,jrc数据下载连接如下:https://global-surface-water.appspot.com/download 选择指定区域的数据集合下载如图: 使…...
营销/CDP/MA/SCRM
最近几年面向企业用户的营销系统,cdp,ma,scrm等发展迅速,下面就简单介绍一下这些系统。 架构图 架构图中显示了CDP,MA,SCRM的核心功能,其实还有基础底座的功能。 比如统一登录,权限…...
免费CDN加速,零成本提升网站速度!
1. 起因 免备案的服务器要么在海外,要么是国内通过内网穿透才能访问,这两种方法好处是免费,坏处是延迟太高,有的地区延迟能到四五百甚至超时,这样明显是不行的。 所以需套一个cdn来加速,在2024年࿰…...
2024-12-29-sklearn学习(25)无监督学习-神经网络模型(无监督) 烟笼寒水月笼沙,夜泊秦淮近酒家。
文章目录 sklearn学习(25) 无监督学习-神经网络模型(无监督)25.1 限制波尔兹曼机25.1.1 图形模型和参数化25.1.2 伯努利限制玻尔兹曼机25.1.3 随机最大似然学习 sklearn学习(25) 无监督学习-神经网络模型(无监督) 文章参考网站&a…...
RSA e与phi不互质(AMM算法进行有限域开根)
e与phi不互质 这一部分学习来自trup师傅的博客 针对CTFer的e与phi不互素的问题 - 跳跳糖 1:m^t<n from Crypto.Util.number import * from secret import flag flag bflag{*********} m bytes_to_long(flag) p getPrime(1024) q getPrime(1024) n p * q …...
网络物理互连
案例简介 美乐公司为新创建公司,公司现需要架设网络,需要下属分公司通过路由器与外网服务器联通,请使用Packet Tracer, 按照任务要求完成实验。实验中需配置设备或端口的IP地址。 1、绘制拓扑图 2、配置ip地址 3、配置路由ip R0 …...
论文研读:Text2Video-Zero 无需微调,仅改动<文生图模型>推理函数实现文生视频(Arxiv 2023-03-23)
论文名:Text2Video-Zero: Text-to-Image Diffusion Models are Zero-Shot Video Generators 1. 摘要 1.1 方法总结 通过潜空间插值, 实现动作连续帧。 以第一帧为锚定,替换原模型的self-attention,改为cross-attention 实现 保证图片整体场…...
服务端错误的处理和web安全检测
文章目录 I 服务端错误的处理业务返回码处理前端处理业务返回码nginx处理http状态码II web安全检测区分服务器类型主机扫漏III 使用 micro_httpd 搭建一个PHP站点步骤下载micro_httpd 并安装它配置micro_httpd 来服务PHP文件I 服务端错误的处理 服务端发生错误时,返回给前端的…...
鸿蒙TCPSocket通信模拟智能家居模拟案例
效果图 一、智能家居热潮下的鸿蒙契机 在当下科技飞速发展的时代,智能家居已如浪潮般席卷而来,深刻地改变着我们的生活方式。从能依据环境光线自动调节亮度的智能灯具,到可远程操控、精准控温的智能空调,再到实时监测健康数据的智…...
SQL-leetcode-197. 上升的温度
197. 上升的温度 表: Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是该表具有唯一值的列。 没有具有相同 recordDate 的不同行。 该表包…...
C++系列关键字static
文章目录 1.静态变量2.静态成员变量 1.静态变量 在C的,静态变量是一个非常有用的特性,它在程序执行期间只初始化一次,并在程序的整个执行期间都保持其值。 1.局部静态变量。定义在函数中,只初始化一次,不像普通的局部…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
MCP和Function Calling
MCP MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...
使用homeassistant 插件将tasmota 接入到米家
我写一个一个 将本地tasmoat的的设备同通过ha集成到小爱同学的功能,利用了巴法接入小爱的功能,将本地mqtt转发给巴法以实现小爱控制的功能,前提条件。1需要tasmota 设备, 2.在本地搭建了mqtt服务可, 3.搭建了ha 4.在h…...
Java多线程从入门到精通
一、基础概念 1.1 进程与线程 进程是指运行中的程序。 比如我们使用浏览器,需要启动这个程序,操作系统会给这个程序分配一定的资源(占用内存资源)。 线程是CPU调度的基本单位,每个线程执行的都是某一个进程的代码的某…...
DROPP算法详解:专为时间序列和空间数据优化的PCA降维方案
DROPP (Dimensionality Reduction for Ordered Points via PCA) 是一种专门针对有序数据的降维方法。本文将详细介绍该算法的理论基础、实现步骤以及在降维任务中的具体应用。 在现代数据分析中,高维数据集普遍存在特征数量庞大的问题。这种高维特性不仅增加了计算…...
