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

网络编程-

文章目录

    • 网络编程套接字
    • UDP/TCP的api使用


网络编程套接字

socket,是操作系统给应用程序(传输层给应用层)提供的api,Java也对这个api进行了封装。

socket提供了两组不同的api,UDP有一套,TCP有一套,本文主要介绍api的使用.

这里介绍TCP和UDP的区别:
在这里插入图片描述
连接:通信双方各自保存对方的信息,就是连接.两个通信实体之间建立的一条可靠的、有序的、双向的通信通道。

可靠传输和不可靠传输:可靠传输是发送方可以知道消息有没有被接收方收到

面向字节流:网络中传输的数据的基本单位是字节

面向数据报:每次传输的基本单位是数据报

全双工:一个信道可以双向通信,就像公路一样是双向车道

UDP/TCP的api使用

Java把系统原生的api进行了封装,操作系统中有一类文件叫做scoket文件,它抽象的表示了"网卡"这样的设备,通过操作scoket文件就可以对网卡进行操作.

通过网卡发送数据,就是写scoket文件.
通过网卡接收数据,就是读socket文件.

UDP scoket api的使用

DatagramScoket是UDP scoket,用于接收和发送数据报.

核心的类有两个:
1.DatagramScoket

DatagramScoket是UDP scoket,用于接收和发送数据报.
DatagarmScoket的构造方法

方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(port就是端口号)

DatagramScoket方法

方法名说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacket p)从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()关闭数据报套接字

在这里插入图片描述
这里的DatagramPacket p是作为输出型参数的

小知识:
输出型参数:输出型参数是一个变量,函数会修改它的值,并将修改后的值传递回调用者。调用者可以通过这个参数获取函数处理后的数据。就像是我们自己带饭盒去食堂吃饭,饭盒就相当于DatagramPacket,打饭的阿姨会帮我们把饭盒装满饭菜,此时打饭的阿姨就是void receive.

2.DatagramPacket

UDP面向数据报,每次发送接收数据的基本单位,就是一个UDP数据报.

构造方法:

方法说明
DatagramPacket(byte[] buf, int length)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组buf中,接收指定的长度(length)
DatagramPacket(byte[] buf,int offset,int length,SocketAddress address)构造一个DatagramPacket以用来接收数据报,接收的数据保存在字节数组buf中,接收指定的长度(length),address表示指定的目的主机的ip和端口号

常用方法:

方法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号,或者从发送的数据报中,获取接收端主机的端口号
byte[] getData()获取数据报中的数据

利用上述的方法及概念我们实现一个回显服务器程序;

package net;/*
服务器*/import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket=null;//服务器一般都是要自己指定端口号public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {//服务器需要不停的处理请求,所以我们这里用while循环while (true){//1.等待客户端发送请求,并用DatagramPacket保存,如果没有请求,就进入阻塞.DatagramPacket requstPacket=new DatagramPacket(new byte[4399],4399);socket.receive(requstPacket);//2.将收到的请求构造成字符串,便于后边做出响应的处理String requst=new String(requstPacket.getData(),0,requstPacket.getLength());//3.通过接收的数据,服务器做出响应,process就是具体做出响应的逻辑//这里的回显服务器我们直接返回客户端的输入即可,没什么深层次的逻辑String response=process(requst);//4.将响应后的数据报构造出并且发送//requstPacket.getSocketAddress()就是和服务器通信的对端的ip和端口.//这里就是把请求中的源ip和源端口,作为响应的目的ip和目的端口DatagramPacket resonsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requstPacket.getSocketAddress());socket.send(resonsePacket);}}private String process(String requst) {return requst;}public static void main(String[] args) throws IOException {UdpEchoServer server=new UdpEchoServer(9090);server.start();}
}
/*
客户端
*/
package net;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket=null;//目标服务器的IP和端口private String serverIP;private int serverPOrt;//客户端一般可以使用系统随机分配的端口号public UdpEchoClient(String serverIP,int serverPOrt) throws SocketException {this.serverIP=serverIP;this.serverPOrt=serverPOrt;socket=new DatagramSocket();}public void start() throws IOException {Scanner scanner=new Scanner(System.in);while (true){if (!scanner.hasNext()){break;}//将从控制台读取到的数据存入requstString requst=scanner.next();//1.将requst构成数据报,并发送给服务器DatagramPacket requstPacket=new DatagramPacket(requst.getBytes(),requst.getBytes().length, InetAddress.getByName(serverIP),serverPOrt);socket.send(requstPacket);//2.等待服务器返回响应,构造数据报进行接收,并进行输出DatagramPacket responsePacket=new DatagramPacket(new byte[4399],4399);socket.receive(responsePacket);String response=new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {//"127.0.0.1"通用,代表本机端口号UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);client.start();}
}

代码分析:

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

TCP socket api的使用
TCP是面向字节流的,传输的基本单位是字节.

连接建立:从客户端Socket的构造方法发送连接请求,服务器的SerevrSocket监听到请求后并且调用accept()方法,这样就建立了连接,然后accept()方法在服务器中会生成一个新的Socket对象用来进行通信.

api介绍:
ServerSocket

构造方法:

方法签名说明
ServerSocket(int port)创建⼀个服务端流套接字Socket,并绑定到指定端⼝

方法:

方法说明
Socket accept()开始监听指定端⼝(创建时绑定的端⼝),有客⼾端连接后,返回一个Socket对象,并且基于Socket建立与客户端的连接,没有就阻塞等待
void close()关闭套接字

Socket

构造方法:

方法说明
Socket(String host, int port)创建⼀个客⼾端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接

方法:

方法说明
InetAddress getInetAddress()返回套接字锁连接的地址
InputStream getInputStream()返回此套接字的输⼊流
OutputStream getOutputStream()返回此套接字的输出流

ServerSocket只能在服务器中使用,而Socket既可以在服务器中使用也可以在客户端使用.

TCP是有连接的,就类似需要客户端拨打电话,服务器来接听.

接下来我们用回显服务器案例来介绍TCP的api的使用以及是如何通信的.

首先我们编写一下服务器程序.

 private ServerSocket requstSocket=null;public TcpEchoServer(int port) throws IOException {requstSocket=new ServerSocket(port);}

通过ServerSocket提供的构造方法,给服务器分配一个端口号(这里我们需要注意,服务器是必须要指定端口号的,而客户端系统自己分配端口号就可以)

服务器的ServerSocket是用来监听请求的,如果有客户端发送请求,那么ServerSocket就会感知到

服务器:

 public void start() throws IOException {/*当ServerSocket监听到有客户端发来请求后,会调用accept()方法一旦连接建立,accept()方法就会返回一个新的Socket对象,这个Socket就是专门用来与该客户端进行通信的*/Socket clientSocket=requstSocket.accept();//把处理请求和返回相应的逻辑这里我们放到这个方法中来实现processConntion(clientSocket);}

当ServerSocket监测到有客户端发来连接的请求,ServerSocket会调用accept()方法,accept()方法会返回一个新的Socket对象,这就算是建立了连接而这个新的对象就是用来与客户端通信

上述过程就像是客户端的Socket想要通过服务器的ServerSocket认识服务器中的Socket.于是客户端的Socket就请求服务器的ServerSocket帮忙牵个线,搭个桥.服务器的ServerSocket就把服务器的Socket的电话号码给了客户端,而客户端的构造方法就类似于给服务器拨通了电话,而当前只是在响铃,而accept()方法就类似接听,只有调用accept()的方法后才算真正建立连接

在这里插入图片描述

private void processConntion(Socket clientSocket) {try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream()){Scanner scanner=new Scanner(inputStream);while (true){if (!scanner.hasNext()){break;}String requst=scanner.next();String response=process(requst);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String requst) {return requst;}
try(InputStream inputStream=clientSocket.getInputStream();OutputStream outputStream=clientSocket.getOutputStream())

InputStream inputStream=clientSocket.getInputStream();就是从网卡内读数据

OutputStream outputStream=clientSocket.getOutputStream()就是往网卡内写数据

TCP中操作socket文件,对其进行读写(InputStream,OutputStream),就是在操作网卡,操作系统把网卡抽象成了一个文件.就像看电视,我们只需要操作遥控器即可,而不需要直接去电视脸上操作

客户端

public TcpEchoClient(String serverIP,int serverPort) throws IOException {socket=new Socket(serverIP,serverPort);}

执行上述代码就会和对应的服务器进行tcp的连接建立流程(在系统内核中)
内核走完流程,服务器这边就会从accept()返回,于是就可以通信了.

public void start() throws IOException {try (InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){Scanner scannerConsle=new Scanner(System.in);Scanner scannernetWork=new Scanner(inputStream);while (true){if (!scannerConsle.hasNext()){break;}String requst=scannerConsle.next();PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(requst);printWriter.flush();String response=scannernetWork.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}finally {socket.close();}}
Scanner scannerConsle=new Scanner(System.in);Scanner scannernetWork=new Scanner(inputStream);

在客户端上,scannerConsle是在控制台中读取数据,也就是我们用户输入的时候读取数据,并且转变为String 发送给服务器(就是通过OutputStream写入操作网卡的文件).

而scannernetWork就是在服务器做出响应后,通过inputStream读取网卡上的数据 最终打印出结果.

PrintWriter

PrintWriter 是 Java 中的一个类,位于 java.io 包中,用于以文本形式写入输出数据。它继承了 Writer 抽象类,提供了多种方法来方便地写入字符和字符串到文件或其他输出流中.

printWriter.flush();

这个方法的作用是刷新缓冲区.因为IO都是比较低效的操作,一次一次读写,太麻烦.缓冲区就将先把数据放到内存缓冲区中,等攒够了数据一起发送,这样就变得高效了,而printWriter.flush();就是将缓存区刷新,将数据一点一点发送出去,不用等到满了一股脑发出去.

在客户端运行完毕之后我们要cloose()

  socket.close();

在这里插入图片描述

TCP服务器客户端执行流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上述客户端代码还存在一个问题:
如果有多个客户端发送连接请求,我们就会发现第一个客户端连接上服务器之后,服务器会从accept这里返回,进入具体处理请求的processConntion方法,接下来在具体处理请求方法的内部scanner.hasNext()处阻塞,等待客户端发送请求,此时如果有客户端发送请求,hasNextt继续向下执行,构造String,计算响应.返回响应给客户端.执行完上述操作后继续循环,等待客户端发送请求.

上面这种情况,如果是很多个客户端一起执行,即使其他客户端在内核已经建立了连接,但是由于服务器一直在processConntion方法中为第一个发送请求的客户端服务,一直在processConntion方法循环处理请求,所以其他的客户端无法执行到accept()方法,只是在内核建立连接,没有调用accept方法就不能算真正意义上的连接.其他的客户端也就无法执行.

针对上述问题我们如何改进?
就要用到我们之前学到的多线程,一个线程处理连接,另一个线程处理请求返回响应的逻辑.
但是如果有很多客户端,每次发送请求的时候都要创建一个新的线程,处理完成后销毁,对于系统资源的开销是比较大的,所以我们这里使用线程池.

完整代码展示:

/*
服务器
*/
package net;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;public class TcpEchoServer {private ServerSocket socket=null;public TcpEchoServer(int port) throws IOException {socket=new ServerSocket(port);}public void start() throws IOException {ExecutorService pool= Executors.newCachedThreadPool();while (true){Socket cilentSocket =socket.accept();pool.submit(new Runnable() {@Overridepublic void run() {processConnetion(cilentSocket);}});}}private void processConnetion(Socket cilentSocket) {try (InputStream inputStream=cilentSocket.getInputStream();OutputStream outputStream=cilentSocket.getOutputStream()){Scanner scanner=new Scanner(inputStream);while (true){if (!scanner.hasNext()){break;}String requst=scanner.next();String response=process(requst);PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(response);printWriter.flush();}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String requst) {return requst;}public static void main(String[] args) throws IOException {TcpEchoServer server=new TcpEchoServer(9090);server.start();}
}
/*
客户端
*/
package net;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;public TcpEchoClient(String serverIP,int serverPort) throws IOException {socket=new Socket(serverIP,serverPort);}public void start() throws IOException {try (InputStream inputStream=socket.getInputStream();OutputStream outputStream=socket.getOutputStream()){Scanner scannerCon=new Scanner(System.in);Scanner scannerNet=new Scanner(inputStream);while (true){if (!scannerCon.hasNext()){break;}String requst=scannerCon.next();PrintWriter printWriter=new PrintWriter(outputStream);printWriter.println(requst);printWriter.flush();String response=scannerNet.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}finally {socket.close();}}public static void main(String[] args) throws IOException {TcpEchoClient client=new TcpEchoClient("127.0.0.1",9090);client.start();}}

相关文章:

网络编程-

文章目录 网络编程套接字UDP/TCP的api使用 网络编程套接字 socket,是操作系统给应用程序(传输层给应用层)提供的api,Java也对这个api进行了封装。 socket提供了两组不同的api,UDP有一套,TCP有一套&#x…...

基于单片机的常规肺活量SVC简单计算

常规肺活量 SVC(Slow Vital Capacity)是指尽力吸气后缓慢而又完全呼出的最大气量。 成年男性的肺活量通常在 3500-4000ml 之间,成年女性的肺活量通常在 2500-3000ml 之间。 单片机一般通过外接流量传感器,使用ADC高速采集的方式…...

【PostgreSQL】PG在windows下的安装

一、准备 通过官网下载安装文件,官方下载路径如下: https://www.postgresql.org/download/windows/ 二、安装 双击postgresql-17.3-1-windows-x64.exe文件,启动安装,进入安装步骤,点击Next 选择PG安装路径&#xff…...

电动汽车电池监测平台系统设计(论文+源码+图纸)

1总体设计 本次基于单片机的电池监测平台系统设计,其整个系统架构如图2.1所示,其采用STC89C52单片机作为控制器,结合ACS712电流传感器、TLC1543模数转换器、LCD液晶、DS18B20温度传感器构成整个系统,在功能上可以实现电压、电流、…...

基于和声搜索(Harmony Search, HS)的多中心点选址优化算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于和声搜索(Harmony Search, HS)的多中心点选址优化算法matlab仿真。可以设置多个不同的中心点。 2.测试软件版本以及运行结果展示 matlab2022a/matlab2024b版…...

单链表的概念,结构和优缺点

1. 概念 链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 2. 单链表的结构 单链表是由一系列节点组成的线性结构,每个结点包含两个域。:数据域和指针域。 数据域用来…...

SpringBoot+数据可视化的奶茶点单购物平台(程序+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统介绍 本奶茶点单购物平台搭建在 Spring Boot 框架之上,充分利用其强大的依赖管理机…...

深入理解 Vue3 中 ref 与 reactive 的区别及应用

深入理解 Vue3 中 ref 与 reactive 的区别及应用 在 Vue3 的开发世界里,响应式编程是其核心特性之一,而ref与reactive作为实现响应式的关键 API,理解它们的区别和适用场景对于开发者来说至关重要。本文将带你深入剖析这两个 API,…...

TDengine 客户端连接工具 taos-Cli

简介工具获取运行命令行参数 基础参数高级参数 数据导出/导入 数据导出数据导入 执行 SQL 脚本使用小技巧 TAB 键自动补全设置字符列显示宽度其它 错误代码表 简介 TDengine 命令行工具(以下简称 TDengine CLI)是用户操作 TDengine 实例并与之交互最简…...

Linux(ubuntu)下载ollama速度慢解决办法

国内安装Ollama都很慢,因为一直卡在下载中,直接通过官网的链接地址下载方法: curl -fsSL https://ollama.com/install.sh | sh速度大概是10min下载1%,完全不能接受啊! 其中很好的一个加速方式是通过使用github文件加速…...

Mac安装JD-GUI

Mac安装反编译工具步骤如下: 打开官网https://java-decompiler.github.io/ 选择下载mac的安装包解压下载好的压缩包,点击JD-GUI安装 有可能会遇到如下错误。请先检查是否安装JDK,通过java -version命令查看是否是1.8版本的jdk如果jdk没问题&…...

Jenkins 配置 Git Parameter 四

Jenkins 配置 Git Parameter 四 一、开启 项目参数设置 勾选 This project is parameterised 二、添加 Git Parameter 如果此处不显示 Git Parameter 说明 Jenkins 还没有安装 Git Parameter plugin 插件,请先安装插件 Jenkins 安装插件 三、设置基本参数 点击…...

【AI】Docker中快速部署Ollama并安装DeepSeek-R1模型: 一步步指南

【AI】Docker中快速部署Ollama并安装DeepSeek-R1模型: 一步步指南 一、前言 为了确保在 Docker 环境中顺利安装并高效运行 Ollama 以及 DeepSeek 离线模型,本文将详细介绍整个过程,涵盖从基础安装到优化配置等各个方面。通过对关键参数和配置的深入理解…...

Python 自然语言处理(NLP)和文本挖掘的常规操作过程

Python 自然语言处理(NLP)和文本挖掘 自然语言处理(NLP)和文本挖掘是数据科学中的重要领域,涉及对文本数据的分析和处理。Python 提供了丰富的库和工具,用于执行各种 NLP 和文本挖掘任务。以下是一些常见的…...

传统数组 vs vector和list

传统的数组: int arr[10]; 传统的数组有以下的缺点: 1)长度不可修改 2)内存分配 局部数组:把数组定在函数内, 数组便是局部变量,故会被分配在栈上 但栈的大小是有限制的 ,故其在内存中不能超…...

CRMEB 多商户版v3.0.1源码全开源+PC端+Uniapp前端+搭建教程

一.介绍 crmeb多商户是一套B2B2C商家入驻模式的平台多商户商城系统,系统支持平台自营、联营、招商等多种运营模式,可满足企业新零售、批发、分销、预售、O2O、多店、商铺入驻等各种业务需求。 后端全开源、uniapp多端可编译! 二、搭建教程…...

【ESP32】ESP-IDF开发 | WiFi开发 | HTTPS服务器 + 搭建例程

1. 简介 1.1 HTTPS HTTPS(HyperText Transfer Protocol over Secure Socket Layer),全称安全套接字层超文本传输协议,一般理解为HTTPSSL/TLS,通过SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信…...

Vue2 中使用 UniApp 时,生命周期钩子函数总结

在 Vue2 中使用 UniApp 时,生命周期钩子函数是一个重要的概念。它允许开发者在特定的时间点运行代码,管理组件的生命周期。以下是 Vue2 中 UniApp 常用的生命周期钩子函数总结: 1. beforeCreate 说明: 组件实例刚被创建,此时数据…...

如何在 Vue 3 中使用 Vue Router 和 Vuex

在 Vue 3 中使用 Vue Router 1. 安装 Vue Router 在项目根目录下,通过 npm 或 yarn 安装 Vue Router 4(适用于 Vue 3): npm install vue-router4 # 或者使用 yarn yarn add vue-router42. 创建路由配置文件 在 src 目录下创建…...

Fiori APP配置中的Semantic object 小bug

在配置自开发程序的Fiori Tile时,需要填入Semantic Object。正常来说,是需要通过事务代码/N/UI2/SEMOBJ来提前新建的。 但是在S4 2022中,似乎存在一个bug,即无需新建也能输入自定义的Semantic Object。 如下,当我们任…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...