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

Java 网络编程

1.UDP和TCP

UDP和TCP是传输层协议中最核心的两种协议

他们的特点分别是

UDP: 无连接,不可靠传输,面向数据报,全双工

TCP: 有连接,是可靠传输,面向字节流,全双工

有无连接

有连接:就好比两个人打电话,打电话的一方发出连接请求,被打电话的一方选择确认连接,此时双方才能进行通话

无连接:就好比QQ,微信发消息,发消息的一方不需要和另一方取得连接就可以发送消息

可靠传输

在网络通信中,是没办法保证100%传输成功的

不可靠传输:发送出去就不管了

可靠传输:发送方能知道信息是否传出去了

面向数据报/面向字节流

面向数据报:以数据报为单位进行接发

面向字节流:以字节为单位进行接发,类似于文件读写

全双工

一个通信通道,可以双向传输(既可以接收,也可以发送)

半双工:可以发也可以收,但是不可以同时进行

2.实现UDP版本的服务器和客户端

为方便,此处实现的服务器为回显服务器(服务器的响应和请求相同),TCP也是一样的

首先要认识几个类

2.1 DatagramSocket

使用此类,表示一个socket对象,有了一个socket对象就可以对另一台主机进行通信了

注意:在操作系统中,socket会当做文件来处理,会存放到文件描述符表中

构造方法:

1.DatagramSocket(int port)

里面传入一个端口号(1024~65535),可以确定端口

2.DatagramSocket()

操作系统会随机分配一个空闲的端口

方法:

void receive(DatagramPacket p)

用来接收数据报,此时要传入一个空的DatagramPacket对象,内容及数据会存放到DatagramPacket对象中

void send(DatagramPacket p)

用来发送数据报,数据要提前存放在DatagramPacket对象中

2.2 DatagramPacket

表示UDP中传输的一个报文,可以指定一些数据进去

构造方法:

DatagramPacket(byte[] buf,int length)

里面放一个byte数组作为缓冲区,length是要存放的长度

DatagramPacket(byte[] buf,int length,SocketAddress address)

和上面的相比,多了一个address参数,该参数可以传入IP和端口号

方法:

InetSddress getAddress()

获取IP地址

int getPort()

获取端口号

byte[] getData()

获取数据报中的数据

2.3 编写UDP版本的服务器

首先搭建好一个大体框架,并在构造方法中创建出一个DatagramSocket对象

注意:构造时要传入一个端口号,因为在网络通信中,服务器是被动方,如果端口号为随机,那么此时客户端就不知道服务器的端口号,也就无法进行通信了

public class UdpEchoServer {private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() {}
}

然后在start中实现具体的服务器代码

首先是一个while(true)循环包含整个方法体,因为大多数服务器需要全天24h不断的去处理请求

之后大致分四步:

1.读取客户端发来的请求

            //receive 方法的参数是一个输出型参数,需要构建好一个空白的 DatagramPacket 对象,让receive去补充DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//如果客户端发来了请求,receive就能顺利读出来请求,如果没有请求就会进入阻塞socket.receive(requestPacket);//将数组中的数据转化为字符串,方便读取String request = new String(requestPacket.getData(),0,requestPacket.getLength());

2.根据请求,构建响应

    String response = process(request);

process方法为处理响应的方法(就是将请求直接返回去)

    public String process(String request) {return request;}

3.返回响应

//此处DatagramPacket 的参数就不能是空的数组了,因为要将响应的字符串返回去//send的参数也是DatagramPacket//在receive时,requestPacket中已经存放了 客户端的IP地址和端口号DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);

4.打印信息(可有可无)

System.out.printf("[%s:%d] req: %s;resp : %s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);

打印内容为(从左到右): 客户端的IP,客户端的端口号,请求,响应

整体代码如下:

public class UdpEchoServer {private DatagramSocket socket = null;public 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);//4. 打印这次请求响应的处理过程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 server = new UdpEchoServer(9090);server.start();}
}

2.4 编写UDP版本的客户端

构建框架,相比于服务器,客户端在构造方法处还需要传入服务器的端口号和IP

public class UdpEchoClient {private DatagramSocket socket = null;private String serverIP = null;private int serverPort = 0;public UdpEchoClient(String serverIP,int serverPort) throws SocketException {socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;}public void start() {}
}

start中的具体实现

仍然是一个while循环包含方法体

循环内容大致分四步:

1.从控制台构建请求

            //该句在循环外,如果每次循环都去创建Scanner太耗效率了Scanner scanner = new Scanner(System.in);System.out.print(">");String request = scanner.next();//判断是否要退出if(request.equals("exit")) {System.out.println("goodbye");break;}

2.发送请求

            // 构造一个 DatagramPacket 对象 此时该对象的参数要传入客户端的 IP(serverIP) 和 端口(serverPort)// 此处的IP需要的是一个32的整数形式,需要使用 InetAddress.getByName 进行一个转换DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);socket.send(requestPacket);

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 class UdpEchoClient {private DatagramSocket socket = null;private String serverIP = null;private int serverPort = 0;public UdpEchoClient(String serverIP,int serverPort) throws SocketException {socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner = new Scanner(System.in);while(true) {//1.从控制台读取要发送的请求System.out.print(">");String request = scanner.next();if(request.equals("exit")) {System.out.println("goodbye");break;}//2.构造成一个UDP请求,并发送DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);socket.send(requestPacket);//3.读取UDP服务器的响应,并解析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 client = new UdpEchoClient("127.0.0.1",9090);client.start();}
}

3.实现TCP版本的服务器和客户端

3.1 ServerSocket

ServerSocket是专门给服务器(TCP)使用的socket对象

构造方法:

ServerSocket(int port)

构建一个socket并指定端口号

方法:

Socket accept()

开始监听指定端口,当有客户端绑定时,返回一个Socket对象并建立连接,否则,则进入阻塞等待

3.2 Socket

既会给客户端提供服务,也会给服务器提供服务(TCP)

构造方法:

Socket(String host,int port)

构造一个Socket对象,并与传入的端口号和IP进行连接

方法:

InputStream getInputStream()

返回一个与该Socket连接相关连的InputStream 对象

OutputStream getOutputStream()

返回一个与该Socket相关连的OutputStream 对象

3.3 编写TCP版本的服务器

首先是一个大体的框架,将ServerSocket对象打包好

public class TcpEchoServer {private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() {}//处理连接public void processConnection(Socket clientSocket) {}//处理请求public String process(String request) {return request;}
}

在连接的处理时,首先要连接上资源(InputStream 读,OutputStream 写)

然后将以下四个步骤循环执行

1.读取请求

2.根据请求构造响应

3.返回响应

4.打印请求和响应(可有可无)

由于分段解释比较杂乱,此处将整个处理连接过程的代码全部给出

//处理连接public void processConnection(Socket clientSocket) {//打印日志 -- 客户端的IP和端口号System.out.printf("[%s:%d] 客户端上线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {Scanner scanner = new Scanner(inputStream);while(true) {//1.读取请求if (!scanner.hasNext()) {//此时没有下一个数据(客户端关闭了连接)System.out.printf("[%s:%d] 客户端下线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}String request = scanner.next();//2.根据请求构造响应String response = process(request);//3.返回响应//可以使用 OutputStream 将字符串转化为字节数组传入//也可以使用字符流 PrintWrite 来转换//将 OutputStream 对象放入 PrintWrite 的对象参数中 就可以通过 PrintWrite 来输出PrintWriter printWriter = new PrintWriter(outputStream);//此处将数据写入,使用println换行 方便对端接收解析printWriter.println(response);//flush 用来刷新缓冲区printWriter.flush();//4.打印请求和响应System.out.printf("[%s:%d] req:%s resp:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);} finally {try {//由于每一次客户端进行连接时都会创建一个 clientSocket 出来//而 Socket 属于文件 会占用文件描述符表clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}

在start中也需要一个循环去不断接收客户端的连接请求(此处使用的是单线程模式,如果上一个客户端的请求没有处理完,是无法处理下一个的)

//单线程版本public void start() throws IOException {System.out.println("服务器启动");while(true) {//使用 clientSocket 来和客户端交流Socket clientSocket = serverSocket.accept();//使用该方法处理连接processConnection(clientSocket);}}

整体代码如下:

多线程版本和线程池版本的start一并放到下面的代码中

public class TcpEchoServer {private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}//线程池版本/*public void start() throws IOException {System.out.println("服务器启动");while(true) {//创建线程池ExecutorService threadPool = Executors.newCachedThreadPool();//使用 clientSocket 来和客户端交流Socket clientSocket = serverSocket.accept();threadPool.submit(new Runnable() {@Overridepublic void run() {processConnection(clientSocket);}});}}*///多线程版本/*public void start() throws IOException {System.out.println("服务器启动");while(true) {//使用 clientSocket 来和客户端交流Socket clientSocket = serverSocket.accept();//使用多线程来处理Thread t = new Thread(() -> {processConnection(clientSocket);});t.start();}}*///单线程版本public void start() throws IOException {System.out.println("服务器启动");while(true) {//使用 clientSocket 来和客户端交流Socket clientSocket = serverSocket.accept();//使用该方法处理连接processConnection(clientSocket);}}//处理连接public void processConnection(Socket clientSocket) {//打印日志 -- 客户端的IP和端口号System.out.printf("[%s:%d] 客户端上线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {Scanner scanner = new Scanner(inputStream);while(true) {//1.读取请求if (!scanner.hasNext()) {//此时没有下一个数据(客户端关闭了连接)System.out.printf("[%s:%d] 客户端下线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}String request = scanner.next();//2.根据请求构造响应String response = process(request);//3.返回响应//可以使用 OutputStream 将字符串转化为字节数组传入//也可以使用字符流 PrintWrite 来转换//将 OutputStream 对象放入 PrintWrite 的对象参数中 就可以通过 PrintWrite 来输出PrintWriter printWriter = new PrintWriter(outputStream);//此处将数据写入,使用println换行 方便对端接收解析printWriter.println(response);//flush 用来刷新缓冲区printWriter.flush();//4.打印请求和响应System.out.printf("[%s:%d] req:%s resp:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);} finally {try {//由于每一次客户端进行连接时都会创建一个 clientSocket 出来//而 Socket 属于文件 会占用文件描述符表clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer tcpEchoServer = new TcpEchoServer(9090);tcpEchoServer.start();}
}

3.4 编写TCP版本的客户端

首先是大体框架

public class TcpEchoClient {private Socket socket = null;public TcpEchoClient(String serverIP,int serverPort) throws IOException {//下面这个构造语句就会触发TCP建立连接//里面需要传服务器的IP和端口号socket = new Socket(serverIP,serverPort);}public void start() {}
}

start中实现请求的传输和获取响应

首先是资源的创建(InputStream 读,OutputStream 写)

然后套入循环执行

分为四步(大部分和服务器相似):

1.获取请求

2.发送请求

3.接收响应

4.打印响应(可有可无)

public void start() {System.out.println("客户端启动");try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while(true) {//1.从键盘获取用户请求Scanner scanner = new Scanner(System.in);System.out.print(">");String request = scanner.next();if(request.equals("exit")) {System.out.println("goodbye");break;}//2.发送请求到服务器PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(request);//刷新 确保数据发送了出去printWriter.flush();//3.接收服务器返回的响应Scanner respScanner = new Scanner(inputStream);String response = respScanner.next();//4.打印响应System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}

整体代码如下:

public class TcpEchoClient {private Socket socket = null;public TcpEchoClient(String serverIP,int serverPort) throws IOException {//下面这个构造语句就会触发TCP建立连接//里面需要传服务器的IP和端口号socket = new Socket(serverIP,serverPort);}public void start() {System.out.println("客户端启动");try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while(true) {//1.从键盘获取用户请求Scanner scanner = new Scanner(System.in);System.out.print(">");String request = scanner.next();if(request.equals("exit")) {System.out.println("goodbye");break;}//2.发送请求到服务器PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(request);//刷新 确保数据发送了出去printWriter.flush();//3.接收服务器返回的响应Scanner respScanner = new Scanner(inputStream);String response = respScanner.next();//4.打印响应System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",9090);tcpEchoClient.start();}
}

相关文章:

Java 网络编程

1.UDP和TCPUDP和TCP是传输层协议中最核心的两种协议他们的特点分别是UDP: 无连接,不可靠传输,面向数据报,全双工TCP: 有连接,是可靠传输,面向字节流,全双工有无连接有连接:就好比两个人打电话,打电话的一方发出连接请求,被打电话的一方选择确认连接,此时双方才能进行通话无连接…...

BEV学习记录

近期可能要经常性的开展BEV工作,打算把自己觉着不错的网站拿出来记录一下。 首先贴上来我还没有细读的一篇觉着不错的文章。 自动驾驶感知新范式——BEV感知经典论文总结和对比(上)_苹果姐的博客-CSDN博客_bev视角 开山之作--LSS ECCV 202…...

Webrtc Native C++切换音频输入源

modules/audio_device/audio_device_impl.cc #include “api/audio_options.h” #include “modules/audio_device/include/factory.h” // 创建一个 AudioDeviceModule 对象 auto audio_device_module = webrtc::AudioDeviceModule::Create( webrtc::AudioDeviceModule::kPl…...

裸辞5个月,面试了37家公司,终于找到理想工作了

上半年裁员,下半年裸辞,有不少人高呼裸辞后躺平真的好快乐!但也有很多人,裸辞后的生活五味杂陈。 面试37次终于找到心仪工作 因为工作压力大、领导PUA等各种原因,今年2月下旬我从一家互联网小厂裸辞,没想…...

Mybatis-plus@DS实现动态切换数据源应用

目录1 DS实现动态切换数据源原理2 不可在事务中切换数据库分析解决3 原因解析1 DS实现动态切换数据源原理 首先mybatis-plus使用com.baomidou.dynamic.datasource.AbstractRoutingDataSource继承 AbstractDataSource接管数据源;具体实现类为com.baomidou.dynamic.d…...

SpringBoot的创建和使用

SpringBoot是什么?SpringBoot诞生的目的就是为了简化Spring开发,而相对于Spring,SpringBoot算是一个很大的升级,就如同汽车手动挡变成了自动挡。Spring:SpringBoot:SpringBoot的优点SpringBoot让Spring开发…...

居家电话客服宝典

客服分类从销售的流程来分,客服分为售前和售后。售前一般都带有销售性质,工资主要靠提成,售后一般是解答问题,工资主要看服务质量和差评量。从工作模式来分,客服分为在线客服和热线客服。在线客服以打字聊天为主&#…...

开发方案设计

1、开发流程产品需求设计-->需求粗评-->做设计方案-->粗估时-->需求细评-->排期-->开发-->提测、修bug-->code review-->上线设计方案主要是写实现思路、模块划分code review:完善代码,发现未考虑到的边界问题2、具体实现方案…...

文件路径模块pathlib

文件路径模块pathlib 文章目录文件路径模块pathlib1.概述2.创建路径2.1.创建非windos平台路径2.2.动态拼接路径joinpath2.3.替换文件名称 with_name2.4.创建固定目录2.5.创建文件夹和文件1.创建多级目录mkdir2.创建空文件3.路径解析3.1.根据路径分隔符解析路径parts3.2.获取父级…...

spring cloud篇——什么是服务熔断?服务降级?服务限流?spring cloud有什么优势?

文章目录一、spring cloud 有什么优势二、服务熔断2.1、雪崩效应2.2、DubboHystrixCommand三、服务降级四、服务限流4.1、限流算法4.2、应用级限流4.3、池化技术4.4、分布式限流4.5、基于Redis 功能的实现限流4.6、基于令牌桶算法的实现4.6.1 、Java实现一、spring cloud 有什么…...

Tomcat构建

软件架构C/S:Client/Server.需要安装才能使用。B/S:Brower/Server。有浏览器就可以。资源分类动态资源:每个用户访问相同的资源后,得到的结果可能不一样,称为动态资源。动态资源被访问后,先转换为静态资源,再被浏览器解…...

入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现)

入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现) 一、网络构建 1.1 问题导入 如图所示,数字五的图片作为输入,layer01层为输入层,layer02层为隐藏层,找出每列最大值对应索引为输…...

预算砍砍砍,IT运维如何降本增效

疫情短暂过去,一个乐观的共识正在蔓延:2023年的互联网,绝对不会比2022年更差。 “降本”是过去一年许多公司的核心策略,营销大幅缩水、亏损业务大量撤裁,以及层出不穷的裁员消息。而2023年在可预期的经济复苏下&#…...

10.Jenkins用tags的方式自动发布java应用

Jenkins用tags的方式自动发布java应用1.配置jenkins,告诉jenkins,jdk的安装目录,maven的安装目录2.构建一个maven项目指定构建参数,选择Git Paramete在源码管理中,填写我们git项目的地址,调用变量构建前执行…...

2023新华为OD机试题 - 相同数字的积木游戏 1(JavaScript)

相同数字的积木游戏 1 题目 小华和小薇一起通过玩积木游戏学习数学。 他们有很多积木,每个积木块上都有一个数字, 积木块上的数字可能相同。 小华随机拿一些积木挨着排成一排,请小薇找到这排积木中数字相同且所处位置最远的 2 块积木块,计算他们的距离。 小薇请你帮忙替她…...

重构之改善既有代码的设计(一)

1.1 何为重构,为何重构 第一个定义是名词形式: 重构(名词):对软件内部结构的一种调整,目的是在不改变「软件可察行为」前提下,提高其可理解性,降低修改成本。 「重构」的另一个用…...

Kotlin data class 数据类用法

实验数据 {"code":1,"message":"成功","data":{"name":"周杰轮","gender":1} }kotlin数据类使用方便提供如下内部Api: equals()/hashCode()对 toString() componentN()按声明顺序与属性相…...

随笔-老子不想牺牲了

18年来到这个项目组,当时只有8个人,包括经常不在的架构师和经理。当时的工位在西区1栋A座,办公桌很宽敞。随着项目的发展,入职的人越来越多,项目的工位也是几经搬迁。基本上每次搬迁时,我的工位都是挑剩下的…...

三种查找Windows10环境变量的方法

文章目录一.在设置中查看二. 在我的电脑中查看三. 在资源管理器里查看一.在设置中查看 在系统中搜索设置 打开设置,在设置功能里,点击第一项 系统 在系统功能里,左侧菜单找到关于 在关于的相关设置里可以看到高级系统设置 点击高级系…...

STM32单片机DS18B20测温程序源代码

OLED液晶屏电路接口DS18B20电路接口STM32单片机DS18B20测温程序源代码#include "sys.h"#define LED_RED PBout(12)#define LED_GREEN PBout(13)#define LED_YELLOW PBout(14)#define LED_BLUE PBout(15)#define DS18B20_IO_IN() {GPIOA->CRL&0XFFFFFFF0;GPIOA…...

java日志查看工具finder介绍

目录 一、finder介绍 二、单节点部署 1、服务器需要安装Tomcat,以2.82.16.35为例 2、进入Tomcat下目录webapps下,创建FIND目录,进入FIDN目录 3、下载findweb插件,解压缩 4、登录页面,配置 5、添加日志路径 三、…...

手写现代前端框架diff算法-前端面试进阶

前言 在前端工程上,日益复杂的今天,性能优化已经成为必不可少的环境。前端需要从每一个细节的问题去优化。那么如何更优,当然与他的如何怎么实现的有关。比如key为什么不能使用index呢?为什么不使用随机数呢?答案当然…...

【半监督医学图像分割 2022 MICCAI】CLLE 论文翻译

文章目录【半监督医学图像分割 2022 MICCAI】CLLE 论文翻译摘要1. 简介2. 方法2.1 半监督框架概述2.2 监督局部对比学习2.3 下采样和块划分3. 实验4. 结论【半监督医学图像分割 2022 MICCAI】CLLE 论文翻译 论文题目:Semi-supervised Contrastive Learning for Labe…...

vivo官网App模块化开发方案-ModularDevTool

作者:vivo 互联网客户端团队- Wang Zhenyu 本文主要讲述了Android客户端模块化开发的痛点及解决方案,详细讲解了方案的实现思路和具体实现方法。 说明:本工具基于vivo互联网客户端团队内部开源的编译管理工具开发。 一、背景 现在客户端的业…...

Python基础-数据类型之数字类型

变量中的变量值是用来存储事物状态的,事物的状态分成不同的种类(例如:人的姓名、年龄,身高、职位、工资等),因此变量值有多种不同的数据类型。 age 18 # 用整型记录年龄 salary 3.1 # 用浮点型记录…...

基于Web的6个完美3D图形WebGL库

现代前端、游戏和Web开发正是WebGL可以转化为数字杰作的东西。使用GPU绘制在浏览器屏幕上生成的矢量元素,WebGL创建交互式Web图形,从而获得用户体验。视觉元素的质量和复杂性使该工具在HTML或CSS等其他方法中脱颖而出。WebGL基础WebGL不是一个图形套件。…...

界面组件DevExpress Reporting v22.2 - 增强的Web报表组件UI

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表。DevExpress Reporting v22.2版本已正式发布&…...

初学vector

目录 string的收尾 拷贝构造的现代写法: 浅拷贝: 拷贝构造的现代写法: swap函数: 内置类型有拷贝构造和赋值重载吗? 完善拷贝构造的现代写法: 赋值重载的现代写法: 更精简的现代写法&…...

Windows10 安装wsl2、Ubuntu相关操作

Windows10 安装wsl2、Ubuntu相关操作 安装wsl2 查看本机windows版本: 键盘上按下winr,输入winver,查看系统版本。必须运行 windows 10 版本 2004 及更高版本(内部版本 19041 及更高版本)或 windows 11。满足版本要求后&#xf…...

SpringBoot简单使用MongoDB

MongoDB介绍 SpringBoot简单使用MongoDB 一、配置步骤 1、application.yml 2、pom 3、entity 4、mapper 二、案例代码使用 1、库 前期准备上一篇安装MongoDB地址http://t.csdn.cn/G4oYJ 跟关系型数据库概念对比 Mysql MongoDB Database(数据库) Datab…...

网站上传到虚拟空间/沈阳seo

VC++开发常用功能一系列文章 (欢迎订阅,持续更新...) 软键盘界面如下: 置于桌面窗口最顶层: 置顶介绍: if (hwnd = FindWindow(NULL, szTitle)){// Bring it to the top of Z order and active it.BringWindowToTop (hwnd);// Bring key input into this window.SetForeg…...

中建国际建设有限公司官网/网站推广优化业务

1、安装前须知版本:mysql-5.7.24平台:Linux环境:Centos 72、安装前的必要检查和准备(不要遗漏任何一步骤)(1)、检查系统是否已经安装过mysql[rootlocalhost /]# rpm -qa | grep mysql例如下图所展示,就存在两个记录[rootlocalhost…...

B2B第三方网站建设的流程/百度搜索优化平台

DTOJ 2700:hello world 解题报告 2017.11.06 第一版 ——由翱翔的逗比w原创题目信息: 题目描述 输出hello world 输出 hello world 样例输出 hello world 思路: 利用标准输出字符串“hello world”。 注意: hello world单词需拼…...

大型b2b电子商务平台开发/seo整站优化系统

小米公布的三季度业绩显示,国际业务收入同比增长112.7%,这已增速远超其整体营收的增速,当季其整体营收同比增长49.1%,海外业务的快速增长推动其海外营收占比创下新高达到43.9%,在当前的环境下,能带动中国出…...

小叮当网站建设/怎样推广app别人才愿意下载

近年来随着人们生活条件的不断提高,人们的饮食得到了很大的改善,但是在生活的同时,人们却容易患上了疾病,就比如说高血压近年来关于高血压的问题一直在不断的出现,而且高血压也越来越呈现出年轻化的趋势。对于患有高血…...

亚马逊全球开店官方网站/广州市疫情最新

众所周知,度度熊喜欢的字符只有两个:B 和D。 今天,它发明了一个游戏:D游戏。 度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列(等差数列百科)中的公差D。 这个游戏…...