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.局部静态变量。定义在函数中,只初始化一次,不像普通的局部…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
