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

Java——网络编程套接字

目录

一、网络编程基础

1.1 为什么需要网络编程?——丰富的网络资源

二、什么是网络编程?

三、网络编程中的基本概念

3.2 请求和响应

 3.3 客户端和服务端

 常见的客户端服务端模型

四、Socket套接字

五、通信模型

5.1 Java数据报套接字通信模型

5.2 Java流套接字通信模型

 Socket编程注意事项

5.3 UDP数据报套接字编程

 示例一:

示例二:


一、网络编程基础

1.1 为什么需要网络编程?——丰富的网络资源

用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。

与本地打开视频文件类似,只是视频文件这个资源的来源是网络。

相比本地资源来说,网络提供了更为丰富的网络资源:

所谓的网络资源,其实就是在网络中可以获取的各种数据资源。

而所有的网络资源,都是通过网络编程来进行数据传输的。

二、什么是网络编程?

网络编程,指网络上的主机,通过 不同的进程 ,以编程的方式实现 网络通信(或称为网络数据传输)

当然,我们只要满足 进程 不同就行;所以即便是同一个主机,只要是不同进程,基于网络来传输数据, 也属于网络编程。
特殊的,对于开发来说,在条件有限的情况下,一般也都是在一个主机中运行多个进程来完成网络编程。
但是,我们一定要明确,我们的目的是提供网络上不同主机,基于网络来传输数据资源:
  • 进程A:编程来获取网络资源
  • 进程B:编程来提供网络资源

三、网络编程中的基本概念

3.1  发送端和接收端

在一次网络数据传输时:

发送端 :数据的 发送方进程 ,称为发送端。发送端主机即网络通信中的源主机。
接收端 :数据的 接收方进程 ,称为接收端。接收端主机即网络通信中的目的主机。
收发端 :发送端和接收端两端,也简称为收发端。
注意:发送端和接收端只是相对的,只是一次网络数据传输产生数据流向后的概念。

3.2 请求和响应

一般来说,获取一个网络资源,涉及到两次网络数据传输:
  • 第一次:请求数据的发送
  • 第二次:响应数据的发送。
好比在快餐店点一份炒饭:
先要发起请求:点一份炒饭,再有快餐店提供的对应响应:提供一份炒饭

 3.3 客户端和服务端

服务端 :在常见的网络数据传输场景下,把 提供服务 的一方进程,称为服务端,可以提供对外服务。
客户端 获取服务 的一方进程,称为客户端。
对于服务来说,一般是提供:
  • 客户端获取服务资源
  • 客户端保存资源在服务端

好比在银行办事:
银行提供存款服务:用户(客户端)保存资源(现金)在银行(服务端)
银行提供取款服务:用户(客户端)获取服务端资源(银行替用户保管的现金)

 常见的客户端服务端模型

最常见的场景,客户端是指给用户使用的程序,服务端是提供用户服务的程序:

1. 客户端先发送请求到服务端
2. 服务端根据请求数据,执行相应的业务处理
3. 服务端返回响应:发送业务处理结果
4. 客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果)

四、Socket套接字

概念
Socket 套接字,是由系统提供用于网络通信的技术,是基于 TCP/IP 协议的网络通信的基本操作单元。
基于Socket套接字的网络程序开发就是网络编程。
分类
Socket 套接字主要针对传输层协议划分为如下三类:
4.1  流套接字 :使用传输层 TCP 协议
TCP ,即 Transmission Control Protocol (传输控制协议),传输层协议。
以下为 TCP 的特点(细节后续再学习):
  • 有连接
  • 可靠传输
  • 面向字节流
  • 有接收缓冲区,也有发送缓冲区
  • 大小不限
对于字节流来说,可以简单的理解为,传输数据是基于 IO 流,流式数据的特征就是在 IO 流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。
4.2. 数据报套接字 :使用传输层 UDP 协议
UDP ,即 User Datagram Protocol (用户数据报协议),传输层协议。
以下为 UDP 的特点(细节后续再学习):
  • 无连接
  • 不可靠传输
  • 面向数据报
  • 有接收缓冲区,无发送缓冲区
  • 大小受限:一次最多传输64k
对于数据报来说,可以简单的理解为,传输数据是一块一块的,发送一块数据假如 100 个字节,必须一次发送,接收也必须一次接收100 个字节,而不能分 100 次,每次接收 1 个字节。

4.3 原始套接

原始套接字用于自定义传输层协议,用于读写内核没有处理的 IP 协议数据。
我们不学习原始套接字,简单了解即可。

五、通信模型

5.1 Java数据报套接字通信模型

对于 UDP 协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。
java 中使用 UDP 协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用
DatagramPacket 作为发送或接收的 UDP 数据报。对于一次发送及接收 UDP 数据报的流程如下:

 

以上只是一次发送端的 UDP 数据报发送,及接收端的数据报接收,并没有返回的数据。也就是只有请求,没有响应。对于一个服务端来说,重要的是提供多个客户端的请求处理及响应,流程如下:

 

5.2 Java流套接字通信模型

 Socket编程注意事项

 

1. 客户端和服务端:开发时,经常是基于一个主机开启两个进程作为客户端和服务端,但真实的场
景,一般都是不同主机。
2. 注意目的 IP 和目的端口号,标识了一次数据传输时要发送数据的终点主机和进程
3. Socket 编程我们是使用流套接字和数据报套接字,基于传输层的 TCP UDP 协议,但应用层协议,
也需要考虑,这块我们在后续来说明如何设计应用层协议。
4. 关于端口被占用的问题
如果一个进程 A 已经绑定了一个端口,再启动一个进程 B 绑定该端口,就会报错,这种情况也叫端
口被占用。对于 java 进程来说,端口被占用的常见报错信息如下:

 

此时需要检查进程B绑定的是哪个端口,再查看该端口被哪个进程占用。以下为通过端口号查进程的方式:

  • cmd输入 netstat -ano | findstr 端口号 ,则可以显示对应进程的pid。如以下命令显
    示了 8888 进程的 pid
  • 在任务管理器中,通过pid查找进程

 解决端口被占用的问题

  • 如果占用端口的进程A不需要运行,就可以关闭A后,再启动需要绑定该端口的进程B
  • 如果需要运行A进程,则可以修改进程B的绑定端口,换为其他没有使用的端口。

5.3 UDP数据报套接字编程

DatagramSocket API

DatagramSocket UDP Socket ,用于发送和接收 UDP 数据报。
DatagramSocket 构造方法:

 DatagramSocket 方法:

 DatagramPacket API

DatagramPacket UDP Socket 发送和接收的数据报。
DatagramPacket 构造方法:

 DatagramPacket 方法:

 构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创

建。
InetSocketAddress API
InetSocketAddress SocketAddress 的子类 )构造方法:

 

示例一:

实现一个基于TCP的回显服务

客户端:

mport 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 {// 定义一个用于客户端的Socket对象private Socket clientSocket;/*** 初始化客户端的Socket** @param serverIp 服务器IP地址* @param serverPort 服务器的端口号* @throws IOException*/public TCPEchoClient (String serverIp, int serverPort) throws IOException {this.clientSocket = new Socket(serverIp, serverPort);}public void start () throws IOException {System.out.println("客户端已启动...");// 获取Socket中的输入输出流try (InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {// 循环处理用户的输入while (true) {System.out.println("->");// 接收用户的输入内容Scanner requestScanner = new Scanner(System.in);String request = requestScanner.nextLine();// 发送用户的请求PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(request);// 强制刷新缓冲区printWriter.flush();// 接收服务器的响应Scanner responseScanner = new Scanner(inputStream);// 获取响应数据String response = responseScanner.nextLine();// 打印响应内容System.out.println("接收到服务器的响应:" + response);}} catch (IOException e) {e.printStackTrace();} finally {clientSocket.close();}}public static void main(String[] args) throws IOException {TCPEchoClient client = new TCPEchoClient("127.0.0.1", 9999);client.start();}
}

服务端:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ProtocolException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.MessageFormat;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 基于TCP的服务器程序* @Date 2023-05-23*/
public class TCPEchoServer {// 声明一个用于服务端的Socket对象private ServerSocket server;/*** 通过指定端口号实例化服务** @param port 端口号* @throws IOException*/public TCPEchoServer(int port) throws IOException {if (port < 1025 || port > 65535) {throw new RuntimeException("端口号要在 1025 ~ 65535之间.");}// 实例化ServerSocket并指定端口号this.server = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动成功...");// 创建一个线程池ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 10, 1, TimeUnit.SECONDS,new LinkedBlockingQueue<>(10));// 循环接收客户端的连接while (true) {Socket clientSocket = server.accept();// 每接收到一个新连接请求,就创建一个新的子线程
//            Thread thread = new Thread(() -> {
//                // 处理Socket中的数据
//                try {
//                    processConnections(clientSocket);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            });
//            // 启动线程
//            thread.start();// 提交任务到线程池中poolExecutor.submit(() -> {try {processConnections(clientSocket);} catch (IOException e) {e.printStackTrace();}});}}// 处理数据private void processConnections(Socket clientSocket) throws IOException {// 打印日志String clientInfo = MessageFormat.format("[{0}:{1}] 客户端已上线", clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(clientInfo);// 处理数据之前要获取一下输入输出流try (InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {// 循环处理用户的请求while (true) {// 通过Scanner读取用户请求中的数据Scanner requestScanner = new Scanner(inputStream);if (!requestScanner.hasNextLine()) {// 日志clientInfo = MessageFormat.format("[{0}:{1}] 客户端已下线.", clientSocket.getInetAddress(),clientSocket.getPort());System.out.println(clientInfo);break;}// 获取真实的用户请求数据String request = requestScanner.nextLine();// 根据请求计算响应String response = process(request);// 把响应写回客户端PrintWriter printWriter = new PrintWriter(outputStream);// 写入输出流printWriter.println(response);// 强制刷新缓冲区printWriter.flush();// 打印日志clientInfo = MessageFormat.format("[{0}:{1}], request: {2}, response: {3}",clientSocket.getInetAddress(), clientSocket.getPort(), request, response);System.out.println(clientInfo);}} catch (IOException e) {e.printStackTrace();} finally {clientSocket.close();}}private String process(String request) {System.out.println("收到新消息:"  + request);Scanner scanner = new Scanner(System.in);String response = scanner.nextLine();return response;}public static void main(String[] args) throws IOException {TCPEchoServer server = new TCPEchoServer(9999);server.start();}
}

示例二:

实现一个基于UDP的回显服务:

客户端:

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*** @Date 2023-05-20*/
public class UDPEchoClient {// 定义一个用于客户端的DatagramSocketprivate DatagramSocket client;// 定义服务器的IP地址private String serverIp;// 定义服务器的端口号private int port;private SocketAddress address;/*** 构造方法,指定服务器的Ip地址和端口号** @param serverIp 服务器IP* @param port 端口号*/public UDPEchoClient (String serverIp, int port) throws SocketException {this.client = new DatagramSocket();this.serverIp = serverIp;this.port = port;this.address = new InetSocketAddress(serverIp, port);}public void start () throws IOException {System.out.println("客户端已启动.");// 循环接收用户的输入Scanner scanner = new Scanner(System.in);while (true) {System.out.println("->");// 接收用户输入String request = scanner.next();// 1. 把请求内容包装成DatagramPacketDatagramPacket requestPacket = new DatagramPacket(request.getBytes(StandardCharsets.UTF_8),request.getBytes().length, address);// 2. 发送数据client.send(requestPacket);// 3. 接收响应DatagramPacket responsePacket = new DatagramPacket(new byte[1024], 1024);// 4. 在receive方法中填充响应数据client.receive(responsePacket);// 5. 解析响应数据String response = new String(responsePacket.getData(), 0, responsePacket.getLength(), "UTF-8");// 6. 打印日志System.out.printf("request: %s, response: %s.\n", request, response);}}public static void main(String[] args) throws IOException {UDPEchoClient client = new UDPEchoClient("127.0.0.1", 9999);// 启动服务client.start();}}

服务端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;/*** UDP 回显服务器** @Date 2023-05-20*/
public class UDPEchoServer {// 定义一个用于服务器端的DatagramSocketprivate DatagramSocket server;/*** 构造方法,完成服务器的初始化* @param port 端口号*/public UDPEchoServer (int port) throws Exception {if (port > 65535 || port < 1024) {throw new Exception("端口号必须在1024 ~ 65535之间");}// 初始化服务器端的UDP服务this.server = new DatagramSocket(port);}/*** 对外提供服务*/public void start () throws IOException {System.out.println("服务器已启动....");// 循环接收用户的请求while (true) {// 1. 创建一个用于接收请求数据的DatagramPacketDatagramPacket requestPacket = new DatagramPacket(new byte[1024], 1024);// 2. 接收请求, 把真实的内容填充到requestPacketserver.receive(requestPacket);// 3. 从requestPacket获取数据String request = new String(requestPacket.getData(), 0, requestPacket.getLength(), "UTF-8");// 4. 根据请求获取响应String response = processor (request);// 5. 把响应封装到DatagramPacketDatagramPacket responsePacket = new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),response.getBytes().length, requestPacket.getSocketAddress());// 6. 发送数据server.send(responsePacket);// 7. 打印日志System.out.printf("[%s:%d] request: %s, response: %s.\n", requestPacket.getAddress().toString(),requestPacket.getPort(), request, response);}}public String processor(String request) {return request;}public static void main(String[] args) throws Exception {// 初始化服务器UDPEchoServer server = new UDPEchoServer(9999);// 启动服务server.start();}}

简单的字典功能

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;/*** @Date 2023-05-20*/
public class UDPDictServer extends UDPEchoServer{private Map<String, String> map = new HashMap<>();/*** 构造方法,完成服务器的初始化** @param port 端口号*/public UDPDictServer(int port) throws Exception {super(port);// 初始化字典内容map.put("dog", "小狗");map.put("cat", "小猫");map.put("pig", "小猪");map.put("tiger", "大老虎");map.put("veryGood", "牛P");}@Overridepublic String processor(String request) {return map.getOrDefault(request, "查无此词");}public static void main(String[] args) throws Exception {UDPDictServer server = new UDPDictServer(9999);server.start();}
}

相关文章:

Java——网络编程套接字

目录 一、网络编程基础 1.1 为什么需要网络编程&#xff1f;——丰富的网络资源 二、什么是网络编程? 三、网络编程中的基本概念 3.2 请求和响应 3.3 客户端和服务端 常见的客户端服务端模型 四、Socket套接字 五、通信模型 5.1 Java数据报套接字通信模型 5.2 Java流…...

160套小程序源码

源码列表如下&#xff1a; AppleMusic (知乎日报) 微信小程序 d artand 今日更新求职招聘类 医药网 口碑外卖点餐 城市天气 外卖小程序 定位天气 家居在线 微信小程序-大好商城&#xff0c;wechat-weapp 微信小程序的掘金信息流 微信跳一跳小游戏源码 微票源码-demo 急救应急处…...

有效项目进度管理的 10 条规则

项目进度管理是项目中比较关键的方面之一&#xff0c;因为它将决定事情的进展方式、进展速度以及是否会取得进展。换句话说&#xff0c;它可以让你较好地控制项目&#xff0c;帮助你预测不可预测的情况&#xff0c;并使所有相关团队能够高效地协同工作。 以下是有效项目进度管…...

javaWebssh服装租赁店信息管理系统台myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh服装租赁店信息管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要 采用B/S模式开发。开发环境为TO…...

概率论:样本与总体分布,Z分数与概率

参考书目&#xff1a;《行为科学统计精要》&#xff08;第八版&#xff09;——弗雷德里克J格雷维特 数据及其样本的分布 描述一组数据分布 描述一组样本数据的分布 描述样本数据的均值和整体数据一样&#xff0c;但是样本标准差的公式除以了n-1&#xff0c;这里引入自由度的…...

【JavaSE】Java基础语法(十二):ArrayList

文章目录 1. ArrayList的构造方法和添加方法2. ArrayList类常用方法3. ArrayList存储学生对象并遍历 集合和数组的区别 : 共同点&#xff1a;都是存储数据的容器不同点&#xff1a;数组的容量是固定的&#xff0c;集合的容量是可变的 1. ArrayList的构造方法和添加方法 ArrayL…...

c++—封装:运算符重载、友元

1. 友元 &#xff08;1&#xff09;友元函数 ①是一种允许非类成员函数访问类的私有成员的一种机制&#xff1b;可以把一个函数指定为类的友元&#xff0c;也可以把整个类指定为另一个类的友元&#xff1b; ②友元函数在类作用域外定义&#xff0c;但需要在类体中进行声明&…...

【K8s】安全认证与DashBoard

文章目录 一、概述1、客户端2、认证、鉴权与准入控制 二、认证管理1、认证方式2、HTTPS证书认证 三、授权管理1、授权与RBAC2、Role 与 ClusterRole3、RoleBinding 与 ClusterRoleBinding4、案例&#xff1a;创建一个只能管理dev空间下Pods资源的账号 四、准入控制五、DashBoar…...

SpringMVC第七阶段:SpringMVC的增删改查(01)

SpringMVC的增删改查 1、准备单表的数据库 drop database if exists springmvc;create database springmvc;use springmvc; ##创建图书表 create table t_book(id int(11) primary key auto_increment, ## 主键name varchar(50) not null, ## 书名 author varchar(50) no…...

接口测试-Mock测试方法

一、关于Mock测试 1、什么是Mock测试&#xff1f; Mock 测试就是在测试过程中&#xff0c;对于某些不容易构造&#xff08;如 HttpServletRequest 必须在Servlet 容器中才能构造出来&#xff09;或者不容易获取的比较复杂的对象&#xff08;如 JDBC 中的ResultSet 对象&#…...

关于宝塔部署jar包和war包

文章目录 前言一、jar包部署二、war包部署1.maven如果打包不了使用命令打包2.安装Tomcat进行访问是否成功2.进入Tomcat目录进行配置war包 一、项目访问方法 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、jar包部署 1.其实jar包没什么讲的&…...

SpringMVC框架面试专题(初级-中级)-第十节

欢迎大家一起探讨&#xff5e;如果可以帮到大家请为我点赞关注哦&#xff5e; 截止到本节关于SpringMVC的内容已经更新完毕&#xff0c;后续会更新SpringBoot框架的面试题&#xff1b;大家在背题的时候切记不要死记硬背&#xff0c;需要理解 这是什么&#xff1f;有什么操作&a…...

PCIe TLB事务层详解过程

目录 1.What is TLP 2.PCIe 4种不同的事务 2.1.Memory事务 ​​​​​​​2.2.IO事务 2.3.Configuration事务 2.4.Message...

RK3588平台开发系列讲解(项目篇)YOLOv5部署测试

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、YOLOv5环境安装二、YOLOv5简单使用2.1、获取预训练权重文2.2、YOLOv5简单测试2.3、转换为rknn模型2.4、部署到 RK 板卡三、airockchip/yolov5简单测试3.1、转换成rknn模型并部署到板卡沉淀、分享、成长,让自己和他…...

基于变形模板的弱监督体图像分割

文章目录 Weakly Supervised Volumetric Image Segmentation with Deformed Templates摘要本文方法实验结果 Weakly Supervised Volumetric Image Segmentation with Deformed Templates 摘要 背景 有许多方法可以对网络进行弱监督训练来分割2D图像。依赖于对3D图像的2D切片的…...

python实现单例模式及其应用

单例模式是一种常见的设计模式&#xff0c;它保证一个类只能被实例化一次&#xff0c;并提供了一个全局访问点来获取这个唯一的实例。 在 Python 中&#xff0c;可以通过使用装饰器、元类或模块等方式实现单例模式。下面分别介绍这三种方法&#xff1a; 1.使用装饰器实现单例…...

SSM 如何使用 Seata 框架实现分布式事务?

SSM 如何使用 Seata 框架实现分布式事务&#xff1f; 分布式事务是现代分布式系统中必不可少的一部分&#xff0c;而 Seata 框架是一种常用的分布式事务处理方式。在 SSM 框架中&#xff0c;我们可以使用 Seata 框架来管理分布式事务。本文将介绍如何在 SSM 框架中使用 Seata …...

FreeRTOS任务相关API函数

任务创建和删除API函数 xTaskCreate() 创建任务。RAM BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //任务函数const char* const pcName, //任务名字const uint16_t usStackDepth,//任务堆栈大小void * const …...

VBA之正则表达式(42)-- 提取代码中变量名称

实例需求&#xff1a;待处理代码段如下所示&#xff0c;现在需要提取其中的变量名称。 Public pFactor As Integer Sub TestCode() Dim reg As New RegExp, a As Workbook Dim ms As VBScript_RegExp_55.MatchCollection Dim m As VBScript_RegExp_55.Match Dim i, j Dim x1, y…...

Unity Lightmapping Setting

如下图&#xff1a; Lightmapper: 使用什么硬件或算法渲染 Progressive CPU、Progressive GPU、Enlighten(新的算放目前用的比较少) 此数值会被用于分别乘以Direct Samples&#xff0c;Indirect Samples和Environment Samples这三个数值。这三个数值会被应用于…...

Android 12.0Camera2 静音时拍照去掉快门声音

1.概述 在12.0定制化开发时,在Camera2静音情况下有快门拍照声音,这就不符合使用规范了 静音的情况下拍照也不应该发出声音,所以在静音拍照流程中要求去掉快门声音 2.Camera2静音拍照去掉快门声音核心代码 Camera2拍照主要代码:/packages/apps/Camera2/src/com/android/cam…...

Win11硬盘分区

电脑重装了Win11系统&#xff0c;按WinE打开主文件夹&#xff0c;再点击此电脑&#xff0c;发现&#xff1a; 磁盘只有一个C盘。硬盘的所有空间都在该盘上了&#xff0c;那么我们怎么将其分区呢&#xff1f; Win11硬盘分区步骤&#xff1a; 步骤1&#xff1a; 按WinR输入dis…...

访客管理系统:Lobby Track Crack

Lobbytrack桌面 for 微软视窗 一个强大的、功能齐全的现场访客管理系统解决方案。在本地管理您的数据&#xff0c;网络工作站一起配置访客管理流程的各个方面。 扩展您的系统将本地 Web 模块 添加到您的 Lobbytrack 桌面系统&#xff0c;并允许您的员工使用本地 Intranet 上的 …...

Lidar AI Solution环境配置

目录 Lidar AI Solution环境配置前言1. Lidar AI Solution1.1 Pipeline overview1.2 GetStart 2. CUDA-BEVFusion2.1 3D目标检测(nuScenes验证集)2.2 演示2.3 模型和数据2.4 前置条件2.5 快速开始推理2.5.1 下载模型和数据到CUDA-BEVFusion文件夹2.5.2 配置environment.sh2.5.3…...

子串--子字符串 0528

210102 201012 A1A2…An An…A2A1 如何做&#xff0c; 翻转的是21&#xff0c;因为2>1; 翻转的是210&#xff0c;因为2>0; 翻转的是2101&#xff0c;因为2>1&#xff1b; 翻转的是21010&#xff0c;因为2>0&#xff1b; 翻转的是210102&#xff0c;因为22且1&…...

大数据教程【01.04】--excel的使用

更多信息请关注WX搜索GZH&#xff1a;XiaoBaiGPT Excel中的大数据处理 Excel是一款功能强大的电子表格软件&#xff0c;它广泛用于数据处理和分析。对于大数据处理&#xff0c;Excel提供了多种功能和工具&#xff0c;可以帮助用户处理大量的数据。在本教程中&#xff0c;我们…...

Java输入输出流

目录 一、数据流概念 1.输入输出的概念​ 2.流的概念 3.流的操作 二、常用的流分类 三、文件输入输出流 1.FileReader和FileWriter 2.FileInputStream和FileOutStream 四、复制文件 一、数据流概念 1.输入输出的概念​ 输入输出技术用于处理设备之间的数据传输&#x…...

1688商品ID采集一件代发详情页面数据

本篇博文介绍了对1688商品详情API的二次封装&#xff0c;将URL参数封装成Python函数&#xff0c;直接传入参数即可获取搜索结果&#xff0c;例如1688商品标题、价格、一件代发、sku属性和URL等。提供了详细的代码示例和接口调用Demo。 1688.item_get-获得1688商品详情数据 1.请…...

丽江“美丽县城”建设,高精度地籍免像控案例分享

一、项目背景 云南省地矿测绘院于2020年6月承接丽江市玉龙县“美丽县城”建设项目1&#xff1a;500倾斜摄影及地形图测绘项目。项目要求对玉龙县城区及其周边等约30平方公里区域进行优于3CM倾斜摄影测量。 并基于三维模型完成地形高程点、地貌、地物特征点的采集成图&#xf…...

我是如何精通软件工程的

软件工程是一个庞大且不断演化的领域&#xff0c;涉及许多创新。虽然如此&#xff0c;大多数技术 —— 如果不是全部 —— 在软件工程中往往最终汇聚为几个基本原则。工程师更好地掌握软件工程的方法是熟悉软件工程的基础知识&#xff0c;而不是那些不断变化的框架、语言或平台…...