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的开发中,有一个很重要!很重要!很重要!的东西,叫做网络套接字,它被广泛的用来二次开发服务,比如大数据中台的服务链路调用等。 它的实现原理是依靠三次握手来完成通信的建立,…...
mapbox基础,测面功能实现
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️Turf 框架二、🍀测面功能实现1. ☘️实现思路2. ☘️代码样例一、🍀…...
如何通过设置失效时间清除本地存储的数据
一、使用localStorage和时间戳(JavaScript) 1. 原理 localStorage是浏览器提供的一种在本地存储数据的方式,数据没有过期时间限制。但是可以通过自己记录时间戳来模拟数据过期的功能。在存储数据时,同时存储一个时间戳ÿ…...
【QT】找不到qwt_plot.h
系统环境: linux 20.04 qt 6.7.2 cmake 3.22 原因: Qwt没有正式的FindQwt.cmake,Qwt也没有提供QwtConfig.cmake。而且cmake不支持qmake的配置特性,也不支持读取mkspecs (.prf)文件。也就是说cmake构建的qt项目不可用qwt。 解决步…...
程序员如何培养技术领导力?
文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…...
C# 设计模式(创建型模式):原型模式
C# 设计模式(创建型模式):原型模式 引言 在面向对象的设计中,创建型模式关注于对象创建的方式和复杂度。原型模式(Prototype Pattern)是其中一种创建型设计模式,它允许通过复制现有的实例来创…...
Python自学 - 函数初步(内置函数、模块函数、自定义函数)
1 Python自学 - 函数初步(内置函数、模块函数、自定义函数) 1.1 内置函数 几乎所有的编程都会提供一些内置函数,以便完成一些最基本的任务,Python提供了丰富的内置函数,熟悉内置函数可以给工作带来极大便利。 Python官方的内置函数介绍网…...
Mono里运行C#脚本21—mono_image_init_name_cache
前面分析了怎么样加载mscorlib.dll文件,然后把文件数据读取到内存。 接着下来,就会遇到加载整个C#的类型系统,比如System. Object,大体类型如下图所示: 在对CIL编译之前,需要把这些类型全部加载到内存里,以便快捷地访问它们。 mono_image_init_name_cache函数就是完成…...
MySQL中distinct和group by去重的区别
MySQL中distinct和group by去重的区别 在MySQL中,我们经常需要对查询结果进行去重,而DISTINCT和GROUP BY是实现这一功能的两种常见方法。虽然它们在很多情况下可以互换使用,但它们之间还是存在一些差异的。接下来,我们将通过创建测…...
快速上手大模型的对话生成
本项目使用0.5B小模型,结构和大模型别无二致,以方便在如CPU设备上快速学习和上手大模型的对话上传 #mermaid-svg-Z86hUiQZ0hg9BVji {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Z86hUiQZ0h…...
SpringCloud(一)--SpringCloud简介
一. 引言 在微服务架构日益盛行的今天,Spring Cloud凭借其简单易用、功能强大的特性,成为了众多开发者的首选。本文仅为学习所用,联系侵删。 二. SpringCloud概述 2.1 定义 Spring Cloud是一系列框架的有序集合,它巧妙地…...
常见的 Redis 面试题
1. Redis 是什么?它解决了哪些问题? Redis 是一个开源的内存数据结构存储系统,可以用作数据库、缓存和消息中间件。它主要用于解耦应用程序的不同组件或服务,支持高吞吐量和低延迟的消息传递。解决了系统之间的同步调用导致的性能…...
面试准备备备备
职业技能 放到简历的黄金位置(HR刷选简历的重要参考) 基本准则:写在简历上的必须能聊,不然就别写 参考公式:职业技能 必要技术 其他技术 针对性的引导面试官(让他问一些你想让他问的) 寻找合…...
GeoIP + Nginx:实现网站的地域访问控制
1. 引言 在全球化的互联网环境中,地域访问控制已成为许多企业和个人网站管理的重要需求。通过限制特定地区的访问,网站管理员可以保护资源、提高安全性并优化用户体验。本文将介绍如何使用GeoIP和Nginx实现地域访问控制,并提供两种情况的详细…...
打造三甲医院人工智能矩阵新引擎(一):文本大模型篇--基于GPT-4o的探索
一、引言 当今时代,人工智能技术正以前所未有的速度蓬勃发展,深刻且广泛地渗透至各个领域,医疗行业更是这场变革的前沿阵地。在人口老龄化加剧、慢性疾病患病率上升以及人们对健康需求日益增长的大背景下,三甲医院作为医疗体系的核…...
算法题之将列表的数据复制到另一个列表中
方法一:for循环遍历list1中的每个元素append方法将元素逐个添加到list2列表中 list1 [‘q’,‘efe’,‘reb’,‘yhh’,2]list2 []for i in list1:list2.append(i) print(list2) 方法二:python列表自带copy方法,调用copy方法可以得到原列表的…...
Docker图形化界面工具Portainer最佳实践
前言 安装Portainer 实践-基于Portainer安装redis-sentinel部署 Spring Boot集成Redis Sentinel 前言 本篇文章笔者推荐一个笔者最常用的docker图形化管理工具——Portainer。 安装Portainer 编写docker-compose文件 Portainer部署的步骤比较简单,我们还是以…...
在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件
在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件 一、RTP流与WAV文件格式二、实现步骤三、伪代码示例四、C语言示例代码五、关键点说明六、总结在Linux操作系统上,从媒体服务器(如Media Server,简称MS)获取RTP(Real-time Transport Protocol)流…...
栈及栈的操作
栈及栈的操作 栈结构 栈是一种只能在一端进行插入或删除操作的数据结构。栈有两个基本的操作:入栈和出栈。 入栈:将一个新的元素放到栈顶。 出栈:从栈顶取出一个元素。栈顶的元素总是最后入栈,需要出栈时,又最先被从栈中取出。栈的操作规则:LIFO(Last…...
YOLOv10-1.1部分代码阅读笔记-utils.py
utils.py ultralytics\nn\modules\utils.py 目录 utils.py 1.所需的库和模块 2.def _get_clones(module, n): 3.def bias_init_with_prob(prior_prob0.01): 4.def linear_init(module): 5.def inverse_sigmoid(x, eps1e-5): 6.def multi_scale_deformable_attn_py…...
JDK8源码分析Jdk动态代理底层原理
本文侧重分析JDK8中jdk动态代理的源码,若是想看JDK17源码分析可以看我的这一篇文章 JDK17源码分析Jdk动态代理底层原理-CSDN博客 两者之间有着略微的差别,JDK17在JDK8上改进了不少 目录 源码分析 过程 生成的代理类大致结构 本文侧重分析JDK8中jdk…...
springboot配置并使用RestTemplate
目录 一、RestTemplate配置 1、将RestTemplate初始化为Bean 2、使用HttpClient作为RestTemplate客户端 (1)引入HttpClient依赖 (2)修改RestTemplate配置类 3、设置拦截器 (1)新增拦截器类 …...
【MySQL关于数据库和表结构的增删查改】
数据库和表结构的基本语法 数据库命令关于字符集语法 表操作语法创建表查看表结构修改表修改表名增加字段同时修改字段名和字段数据类型仅修改字段数据类型删除字段 删除表 备份和恢复备份恢复 mysql -h 127.0.0.1 -P 3306 -u root -p mysql -u root -h 和 -p 默认 进入MySQL程…...
Linux 服务器启用 DNS 加密
DNS 加密的常用协议包括 DNS over HTTPS (DoH)、DNS over TLS (DoT) 和 DNSCrypt。以下是实现这些加密的步骤和工具建议: 1. 使用 DoH (DNS over HTTPS) 工具推荐: cloudflared(Cloudflare 提供的客户端)doh-client(…...
2025年,测试技能支棱起来。
你是否曾为提升自己的测试技能而烦恼?在这个日新月异的技术时代,2025年已经悄然而至,软件测试行业的需求和挑战也在不断变化。那么,如何在这个竞争激烈的环境中脱颖而出,成为一名更加优秀的测试工程师呢? …...
HTML5实现好看的二十四节气网页源码
HTML5实现好看的新年春节元旦网站源码 前言一、设计来源1.1 主界面1.2 关于我们界面1.3 春季节气界面1.4 夏季节气界面1.5 秋季节气界面1.6 冬季节气界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的二十四节气网页源码,春季节气…...
每天你好20250103(距离春节26天!!!)
亲爱的朋友们,大家早上好! 🌞 今天是 1 月 3 日,星期五,2025 年的第三天,同时也是第 1 周的第五天,农历乙巳[蛇]年十一月十四日。祥龙辞岁去,瑞蛇迎春来,在这曙光初照的…...
【音频伴奏分离】UVR5软件介绍
Ultimate Vocal Remover 5 (UVR5) 是一款功能强大的AI人声伴奏音频分离软件,它能够利用深度学习模型从音频文件中分离出人声和伴奏。UVR5在音乐制作、音频编辑、学习等多种场景中都非常有用。以下是UVR5的一些主要特点和使用方法: 主要特点:…...
安卓触摸事件的传递
setOnTouchListener()返回值的副作用(触摸事件是否继续往下或往后传递)如下: 返回值效果是否往下层view传递是否往当前view的后续监听传递true该pointer离开屏幕前的后续所有触摸事件都会传递给该TouchListener否否false该pointer离开屏幕前…...
51c视觉~合集40
我自己的原文哦~ https://blog.51cto.com/whaosoft/12951385 #SparX 港大提出SparX:强化Vision Mamba和Transformer的稀疏跳跃连接机制 本文分享香港大学计算和数据科学学院俞益洲教授及其研究团队发表于 AAAI 2025 的论文——SparX,一种强化 Visio…...
25年1月更新。一图流Windows 上搭建 Python 开发环境:Python + PyCharm 安装全攻略(文中有安装包不用官网下载)
引言 随着 Python 在数据科学、Web 开发、自动化脚本等多个领域的广泛应用,越来越多的开发者选择它作为首选编程语言。而 PyCharm 作为一个功能强大的集成开发环境(IDE),为 Python 开发者提供了极大的便利。本文将详细介绍如何在 …...
C# 设计模式的六大原则(SOLID)
C# 设计模式的六大原则(SOLID) 引言 在面向对象编程中,设计模式提供了高效、可复用和可维护的代码结构。SOLID原则是软件设计中的一组重要原则,用于确保代码具有良好的可维护性、可扩展性和灵活性。SOLID是五个设计原则的首字母…...
MQ-导读
什么是MQ? MQ是一款消息中间件,通常被称为"消息队列",用于分布式架构中上下文的异步通信。 举个例子 就拿登录来说,用户在登录的时候需要去进行一些其他的操作,比如风控、短信、记录日志,如果采用同步的方式…...
Spring MVC的@ResponseBody与@RequestBody
ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端。 RequestBody注解用于读取http请求的内容(字符串),通过springmv…...
常见硬件及其对应的驱动模块列表
常见硬件及其对应的驱动模块列表 1. 电机类 硬件设备驱动模块功能步进电机ULN2003、A4988、DRV8825提供电流和电压,控制步进和方向直流电机L298N、L293D、TB6612FNG提供双向电流控制,实现正反转和调速伺服电机无(直接 PWM 控制)控…...
IDEA开发Java应用的初始化设置
一、插件安装 如下图所示: 1、Alibaba Java Coding Guidelines 2.1.1 阿里开发者规范,可以帮忙本地自动扫描出不符合开发者规范的代码,甚至是代码漏洞提示。 右击项目,选择《编码规约扫描》,可以进行本地代码规范扫…...
系统架构师考试-ABSD基于架构的设计方法
概念 ABSD是体系结构驱动,是指构成体系结构的软件构件和类的组合驱动的。 ABSD强调由商业、质量和功能需求的组合驱动软件架构设计。使用ABSD方法,设计活动可以从项目总体功能框架明确就开始,并且设计活动的开始并不意味着需求抽取和分析活…...
Node.js入门html,css,js 30年了nodejs环境 09年出现 15
Node.js入门 html,css,js 30年了 nodejs环境 09年出现 15年 nodejs为我们解决了2个方面的问题: 【锦上添花】让我们前端工程师拥有了后端开发能力(开接口,访问数据库) - 大公司BFF(50)【✔️】前端工程…...
2025跨年倒计时
<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>2025年跨年倒计时</title><style>/* 页…...
淘宝京东电商商品SKU信息抓取API测试实战指南
在电商平台的商品管理中,SKU(Stock Keeping Unit,库存单位)信息扮演着至关重要的角色。它不仅关乎商品的库存管理,还直接影响到消费者的购买决策。为了高效地获取并验证电商平台(如淘宝、京东)上…...
SAP财务凭证的更改、冲销的方式
文章目录 一、财务凭证更改二、财务凭证冲销 【SAP系统研究】 #SAP #FICO #SAP财务 一、财务凭证更改 (1)已经过账的财务凭证 FB02:过完帐的允许更改的地方有限,只有凭证抬头文本、参照、分配、文本、原因代码等。 ࿰…...
RepPoints: Point Set Representation for Object Detection
CornerNet论文阅读整理-CSDN博客 可变形卷积(Deformable Conv)原理解析与torch代码实现-CSDN博客 RepPoints(本质是可变形卷积DCN)再理解-CSDN博客 简介: 时间:2019 会议:ICCV 作者:Ze Yang,Shaohui Liu,…...
高效使用AI完成编程项目任务的指南:从需求分析到功能实现
随着人工智能工具的普及,即便是零编程基础或基础薄弱的用户,也可以借助AI完成许多技术任务。然而,要高效地使用AI完成编程任务,关键在于如何清晰表达需求,并逐步引导AI实现目标。 在本文中,我们将通过开发…...
Linux命令——RPM与yum
文章目录 一、RPM包命令1.安装和升级包2.删除包3.查询包信息4.验证和检查5.其他操作 二、yum安装器1.安装包2.更新包3.卸载包4.查询和搜索5.清理缓存6.其他操作 一、RPM包命令 1.安装和升级包 命令解释rpm -ivh package.rpm安装一个 RPM 包,显示详细信息和进度条r…...
C++软件设计模式之责任链模式
责任链模式的动机与意图 动机: 在软件开发中,经常会遇到需要处理一系列请求或事件的情况。这些请求可能需要经过多个处理对象,每个对象根据其职责决定是否处理请求或将其传递给下一个对象。责任链模式(Chain of Responsibility P…...
Spring Cloud Security集成JWT 快速入门Demo
一、介绍 JWT (JSON Web Token) 是一种带有绑实和信息的简单标准化机制,在信息通信中用于验证和信息传递。尤其在应用中使用Spring Cloud实现分布式构建时,JWT可以作为一种无状态验证原理的证明。 本文将进一步描述如何在Spring Cloud Security中集成JW…...
Python 爬虫
一、创建项目 1.双击打开pycharm,点击新建项目 2.项目设置- 勾选[继承全局站点软件包]- 勾选[可用于所有项目]- 取消勾选[创建main.py欢迎脚本]- 点击创建 3.项目名称右键--新建--python文件 4.输入文件名--回车二、编辑代码 # 导入请求模块 import requests # 如…...
【PCIe 总线及设备入门学习专栏 4.1 -- PCI 总线的地址空间分配】
文章目录 Overview 本文转自:https://blog.chinaaet.com/justlxy/p/5100053219 Overview PCI 总线具有32位数据/地址复用总线,所以其存储地址空间为 2324GB。也就是PCI上的所有设备共同映射到这4GB上,每个PCI设备占用唯一的一段PCI地址&…...
虚拟电厂搭建指南:绿虫仿真设计软件的助力
在虚拟电厂的搭建中,绿虫仿真设计软件起着重要作用。 绿虫光伏仿真软件是一款综合性辅助工具,能为虚拟电厂中的光伏项目提供精准数据支持。它所提供的项目选址地气象数据,涵盖海拔、辐照、风速、温度等,数据源为 Meteonorm &…...
开源漏洞管理工具--Faraday
前言 在现代安全领域,面临着两个主要的挑战:一是设计出智能化的方式来获取新信息,二是有效地跟踪和管理发现的内容,以便不断改善修复工作。为了解决这些问题,Faraday应运而生,它能够帮助您专注于漏洞的发现…...