【JavaEE】网络编程socket
1.❤️❤️前言~🥳🎉🎉🎉
Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。
如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的内容感兴趣,记得关注我👀👀以便不错过每一篇精彩。
当然,如果在阅读中发现任何问题或疑问,我非常欢迎你在评论区留言指正🗨️🗨️。让我们共同努力,一起进步!
加油,一起CHIN UP!💪💪
🔗个人主页:E绵绵的博客
📚所属专栏:1. JAVA知识点专栏
深入探索JAVA的核心概念与技术细节
2.JAVA题目练习
实战演练,巩固JAVA编程技能
3.c语言知识点专栏
揭示c语言的底层逻辑与高级特性
4.c语言题目练习
挑战自我,提升c语言编程能力
5.Mysql数据库专栏
了解Mysql知识点,提升数据库管理能力
6.html5知识点专栏
学习前端知识,更好的运用它
7. css3知识点专栏
在学习html5的基础上更加熟练运用前端
8.JavaScript专栏
在学习html5和css3的基础上使我们的前端使用更高级、
9.JavaEE专栏
学习更高阶的Java知识,让你做出网站
📘 持续更新中,敬请期待❤️❤️
2.简单理解socket
之前提过在网络编程中,应用层到运输层需要显式调用 API,而运输层到网络层以及后续层的通信通常是自动处理的,不需要开发者主动调用 API,反过来也是同理。
这里显示调用的API就是socket(套接字) ,只有调用了它,数据才能运输成功。
由于传输层提供了两个最核心的协议:UDP TCP。
因此,socket api 中也提供了两种风格来面对UDP和TCP。(传输层用哪种协议就用哪种风格去应对)
对于socket 不仅是个API,本质上是一种特殊的文件.Socket 就属于是把"网卡"这个设备,给抽象成了文件了往 socket 文件中写数据,就相当于通过网卡发送数据.从 socket 文件读数据,就相当于通过网卡接受数据
3.TCP和UDP的差别(初识)
首先在了解socket用两种风格去面对UDP和TCP时,我们还要先知道udp和tcp的区别:
TCP的特点:
有连接
可靠传输
面向字节流
全双工
UDP的特点:
无连接
不可靠传输
面向数据报
全双工
连接:
此处说的"连接"不是物理意义的连接,而是抽象,虚拟的连接。
计算机中,这种 抽象 的连接是很常见的,此处的连接本质上就是建立连接的双方,各自保存对方的信息,两台计算机建立连接,就是双方彼此保存了对方的关键信息(ip和端口)
所以这也意味着如果协议是tcp的话,必须要先建立好连接才能传输信息,如果是udp,就不用建立连接就能传输消息。
可靠传输/ 不可靠传输:
网络上存在的"异常情况"是非常多的,无论使用什么样的软硬件的技术手段无法100%保证网络数据能够从A一定传输到。此处谈到的"可靠传输",尽可能的完成数据传输。虽然无法确保数据到达对方,至少可以知道,当前这个数据对方是不是收到了。
此处谈到的可靠传输,主要指的是发的数据到没到,发送方能够清楚的感知到。
面向字节流/面向数据报
面向字节流:此处谈到的字节流和文件中的字节流完全一致—— TCP(网络中传输数据的基本单位就是字节)
面向数据报:udp每次传输的基本单位是一个数据报(由一系列的字节构成的),它是特定的结构(之前讲过)。
全双工/半双工:
全双工通信允许数据同时在两个方向上传输。这意味着通信双方可以同时发送和接收数据,而不会互相干扰。
半双工通信允许数据在两个方向上传输,但不能同时进行。通信双方只能交替地发送和接收数据。
这只是简单的讲述一下,后面讲网络原理会讲到更多的本质内容。
4.socket面对udp
udp时的socket相较于tcp,要相对简单,我们先讲这个
DatagramSocket API
DatagramSocket 是UDP时的Socket,用于发送和接收UDP数据报。
DatagramSocket 构造方法
DatagramSocket 方法:
DatagramPacket API
DatagramPacket是UDP Socket发送和接收的数据报(UDP面向数据报,每次发送接收数据的基本单位,就是一个UDP数据报)
DatagramPacket 构造方法:
由于udp是没建立连接的,所以每次发送都要标明要发送的对方ip和端口。(如果建立了连接就不需要发送ip和端口)
DatagramPacket 方法:
构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。
实现回显服务器和客户端
注:这里编写的客户端服务器是一个简单 UDP 版本的服务器,称之为:回显服务器。
一个普通的服务器: 收到请求,根据请求计算响应(业务逻辑),返回响应。
回显服务器: 省略了普通服务器的 “根据请求计算响应”(这里的响应一般非常复杂),这里只是为了演示 socket api 的用法。
这里有一个重点要说下:
对于一个服务器来讲,我们需要让其绑定一个明确的端口号,因为在服务器在网络传输中处于一个被动的状态,没有一个明确的端口号,客户端就无法寻找到请求的服务器。
而对于一个客户端来说,我们可以让其随机分配一个端口号给他,不要指定,因为客户端是客户使用,不像我们程序员知道怎么分配端口,客户不清楚怎么分配端口,万一客户指定的端口被别人占用就会报错,它还不知道怎么修改,所以采用随机分配。(随机分配的都是没被占用的端口号)
以后的服务器客户端 端口号都遵循这规定
服务器端的逻辑如下:
创建套接字:创建一个
DatagramSocket
对象,并绑定到指定的端口(10003),用于接收和发送数据报。接收数据报:在
while (true)
循环中,创建一个DatagramPacket
对象,用于接收客户端发送的数据报。调用datagramSocket.receive(datagramPacket)
方法等待并接收数据报。处理数据:将接收到的数据报中的字节数组转换为字符串,然后调用
process
方法处理该字符串。在这个例子中,process
方法只是简单地返回传入的字符串本身。发送响应:将处理后的字符串转换为字节数组,并创建一个新的
DatagramPacket
对象,包含要发送的数据、目标地址和端口(即客户端的地址和端口)。使用datagramSocket.send(datagramPacket1)
方法将响应数据报发送回客户端。循环处理:上述步骤在
while (true)
循环中不断重复,服务器持续等待接收新的数据报并响应,直到程序被手动终止。
public class Serve {public static void main(String[] args) throws IOException,InterruptedException {System.out.println("服务器上线");DatagramSocket datagramSocket=new DatagramSocket(10003);while(true){DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);datagramSocket.receive(datagramPacket);String string=new String(datagramPacket.getData(),0,datagramPacket.getLength());byte[] bytes1=process(string).getBytes();DatagramPacket datagramPacket1 = new DatagramPacket(bytes1,bytes1.length,new InetSocketAddress(datagramPacket.getAddress(),datagramPacket.getPort()));datagramSocket.send(datagramPacket1);}}public static String process(String string){return string;}
}
客户端设计逻辑:
创建套接字:创建一个
DatagramSocket
对象,用于发送和接收数据报。这个套接字没有绑定到特定的端口,因此会使用一个临时端口。读取用户输入:使用
Scanner
从控制台读取用户输入的字符串。发送数据报:
将用户输入的字符串转换为字节数组。
创建一个
DatagramPacket
对象,包含要发送的数据、目标地址和端口。使用
DatagramSocket
发送数据报。接收响应:
创建一个
DatagramPacket
对象,用于接收服务器的响应。使用
DatagramSocket
接收数据报。将接收到的字节数组转换为字符串并打印到控制台。
循环处理:上述步骤在
while (true)
循环中不断重复,直到程序被手动终止。
public class Client {public static void main(String[] args) throws IOException {System.out.println("客户端启动");Scanner scanner=new Scanner(System.in);DatagramSocket datagramSocket=new DatagramSocket();while(true){String string=scanner.next();byte[] bytes=string.getBytes();DatagramPacket datagramPacket1 = new DatagramPacket(bytes,bytes.length,new InetSocketAddress("192.168.50.173",10003));datagramSocket.send(datagramPacket1);DatagramPacket datagramPacket=new DatagramPacket(new byte[4096],4096);datagramSocket.receive(datagramPacket);String string1=new String(datagramPacket.getData(),0,datagramPacket.getLength());System.out.println(string1);}}
}
对于这里我们要特殊说几个点:
1.对于字节数组内部存储数据报并不可能是全部都占用了,肯定有空闲空间,所以在将该字节数组变为字符串时我们肯定要把空闲空间给划掉,这时候就用datagrampacket.getlength ()得到有效长度,从而就可以忽略掉,否则会引发bug
2.仔细观察代码,发现该服务器可以同时支持多个客户端
这里有个疑问,一段代码为什么会能实现多个窗口呢?一般不是只能一段代码实现一个?这玩意我们是可以修改的。
通过这样修改,我们就能一段代码生成多个实例对象,多个窗口(客户端)。
3.对于该DatagramSocket虽然是文件,但是并不需要close,因为Datagramsocket是全程跟随该进程的,当进程结束时,我们才不会用DatagramSocket,进程只要还在运行,它依然还会用。该进程结束时文件描述表自然就销毁了,根本不用再添一个close。
5.socket面对tcp
ServerSocket
ServerSocket 是创建TCP服务端Socket的API。
ServerSocket 构造方法:
ServerSocket 方法:
因为tcp是有连接的,所以在一个客户端给服务器传输信息前,我们需要先建立连接,这样才能传输信息,这时候就需要用到servesocket了。
当创建好servesocket后,如果有客户端想和服务器建立连接,发送了连接请求,这个时候服务器的应用程序是不需要做出任何操作,由服务器的系统内核直接就完成了连接建立的流程(内部是三次握手从而建立连接,之后会讲),这样客户端和服务器之间建立了逻辑上的连接,这个连接在内核中以连接对象的形式存在。我们就将该连接对象放入已完成连接队列中(accept队列)。创建好的连接对象就会在该内核的队列中(这个队列是每个 serverSocket 都有一个这样的队列) 排队.
而该服务器要想和已经连接好的客户端进行通讯的话,还需要通过accept
函数从accept队列
中取出连接对象,通过该对象就创建socket用于通信。当我们accept时 如果连接对象在队列中不存在则会堵塞,有的话则会接受且创建一个socket对象用于通讯。我们可以认为上述的模型是一个生产者消费者模型。
socket
Socket 可以是客户端Socket,也可以是服务器中通过连接对象建立的 Socket。 不管是客户端还是服务端的Socket,都是双方建立连接以后,用来双方进行通讯的工具
这个不仅是客户端的socket的构造方法,还是客户端的连接建立请求。
以下是它的普通方法
这里的输入流和输出流就是我们发送消息的工具,它们是普通的字节流,我们之前文件io里学到的所有方法在这里也全能用,通过该输入流读取数据就能读取到另一个主机发送的数据,同理输出流就往里面写数据就能发送到另一个主机的输入流里。
实现回显服务器和客户端
这里实现的相比udp复杂一点
服务器端的逻辑如下:
服务器启动:
创建一个
ServerSocket
对象,绑定到指定的端口(10002),并监听客户端连接。打印 "服务器启动" 表示服务器已启动并正在等待客户端连接。
接受客户端连接:
调用
serverSocket.accept()
方法等待并接受客户端的连接请求。创建一个新的
Socket
对象,表示与客户端的连接。处理客户端任务:
调用
startTask
方法处理客户端的请求。在
startTask
方法中,获取客户端的输入流和输出流。读取客户端请求并发送响应:
使用
Scanner
从输入流读取客户端发送的数据。使用
PrintWriter
向输出流发送响应数据。在循环中不断读取客户端发送的数据,直到
scanner.hasNext()
返回false
(相当于客户端断开连接,之后会特殊说明这里的细节)。对于每次读取的数据,调用
process
方法进行处理(在这个例子中,process
方法只是简单地返回传入的字符串)。将处理后的字符串发送回客户端。
关闭连接:
在
finally
块中关闭客户端套接字,确保资源被正确释放。
public class TcpServe {public static void main(String[] args) throws IOException {System.out.println("服务器启动");ServerSocket serverSocket = new ServerSocket(10002);Socket socket = serverSocket.accept();startTask(socket);}public static void startTask(Socket socket) throws IOException {try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {Scanner scanner = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);printWriter.flush();while (true) {if (!scanner.hasNext())break;String string = scanner.next();String string1 = process(string);printWriter.println(string1);printWriter.flush();}} catch (Exception e) {e.printStackTrace();} finally {socket.close();}}public static String process(String string) {return string;}}
客户端的逻辑如下:
客户端启动:
创建一个
Socket
对象,连接到指定的服务器地址(192.168.50.173)和端口(10002)。打印 "客户端上线" 表示客户端已启动并正在连接服务器。
获取输入输出流:
获取
Socket
对象的输入流和输出流,用于接收服务器的响应和发送客户端的请求。读取用户输入并发送请求:
使用
Scanner
从控制台读取用户输入的字符串。使用
PrintWriter
将用户输入的字符串发送到服务器。接收服务器响应:
使用
Scanner
从输入流读取服务器发送的响应。将服务器的响应打印到控制台。
循环处理:
在
while (true)
循环中不断读取用户输入,发送请求,接收响应,直到程序被手动终止或出现异常。关闭连接:
在
finally
块中关闭客户端套接字,确保资源被正确释放。
public class TcpClient {public static void main(String[] args) throws IOException {System.out.println("客户端上线");Socket socket = new Socket("192.168.50.173", 10002);try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {Scanner scanner = new Scanner(System.in);Scanner scanner1 = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);while (true) {String string = scanner.next();printWriter.println(string);printWriter.flush();System.out.println(scanner1.next());}} catch (Exception e) {e.printStackTrace();} finally {socket.close();}}
}
这样我们就实现了一个tcp通信:
但这里还是要说几个特殊的点:
1.这里由于我们采用的是printwrite,所以要用flush冲刷数据,否则可能有bug
2.在 TCP 网络编程中,Scamner.hasHext() 方法的行为与它在处理本地输入(如控制台输入或文件输入)时的行为有所不同。
这里由于scanner是跟另一个主机的输出流联系在一块,所以没有明确的消息边界。因此,在执行Scanner.hasnext()时如果该输入流没数据那么该方法就会阻塞,直到输入流中有数据可用则返回出true。如果客户端断开了连接,连接的输出流则结束了,断开了连接,此时就有明确的消息边界,Scanmer.hasNext()方法就因为没数据会返回 false,所以退出。(有消息边界时没数据则返回false,有数据则返回true;没消息边界时没数据则堵塞,有数据则返回true,不可能返回false)
3.对于该程序,只支持单个客户端,不支持多个客户端,如果想要达到多个,则要用多线程。
public class TcpServe {public static void main(String[] args) throws IOException {System.out.println("服务器启动");ServerSocket serverSocket = new ServerSocket(10010);while (true) {Socket socket = serverSocket.accept();Thread thread = new Thread(() -> {try {TcpServe.startTask(socket);} catch (Exception e) {e.printStackTrace();}});thread.start();}}public static void startTask(Socket socket) throws IOException {try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {Scanner scanner = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);printWriter.flush();while (true) {if (!scanner.hasNext())break;String string = scanner.next();String string1 = process(string);printWriter.println(string1);printWriter.flush();}} catch (Exception e) {e.printStackTrace();} finally {socket.close();}}public static String process(String string) {return string;}}
如果我们程序线程创建销毁太频繁了,还可以用线程池,这样能提高效率
public class TcpServe {public static void main(String[] args) throws IOException {System.out.println("服务器启动");ServerSocket serverSocket = new ServerSocket(10017);ExecutorService executorService = Executors.newCachedThreadPool();while (true) {Socket socket = serverSocket.accept();executorService.submit(() -> {try {TcpServe.startTask(socket);} catch (Exception e) {e.printStackTrace();}});}}public static void startTask(Socket socket) throws IOException {try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {Scanner scanner = new Scanner(inputStream);PrintWriter printWriter = new PrintWriter(outputStream);printWriter.flush();while (true) {if (!scanner.hasNext())break;String string = scanner.next();String string1 = process(string);printWriter.println(string1);printWriter.flush();}} catch (Exception e) {e.printStackTrace();} finally {socket.close();}}public static String process(String string) {return string;}}
4.对于socket以及它带的两个字节流文件我们都需要手动close,因为它们并不是全程跟随整个程序,有可能中途这些文件就不用了,所以就需要close对应的socket文件和字节流文件,否则一直不关而我们一直使用该程序,文件就会持续累积导致文件泄露问题。
而servesocket就不需要,因为它跟之前的Datagramsocket是全程跟随的,所以没必要多此一举。
对于这双方通信我们现在还是只限于一个主机内部,如果要两个主机进行交流就需要部署一个云服务器或者在一个局域网内部才能进行交流。
相关文章:
【JavaEE】网络编程socket
1.❤️❤️前言~🥳🎉🎉🎉 Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的…...
第J3周:DenseNet121算法实现01(Pytorch版)
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目标 具体实现 (一)环境 语言环境:Python 3.10 编 译 器: PyCharm 框 架: Pytorch (二)具体步骤…...
在Ubuntu20.04上交叉编译能在Windows上运行的Qt5应用
参考链接: https://blog.csdn.net/Interview_TC/article/details/146050419 https://bugreports.qt.io/browse/QTBUG-82592 重要设置 sudo update-alternatives --config x86_64-w64-mingw32-g 选择后缀带posix的,(/usr/bin/x86_64-w64-min…...
C语言中,memmove和memcpy的区别?
文章目录 1. 内存重叠处理memcpy:memmove: 2. 性能差异总结 在C语言中,memmove和memcpy均用于内存块的复制,但关键区别在于对内存重叠的处理: 1. 内存重叠处理 memcpy: 假设源(src࿰…...
小程序API —— 54 路由与通信 - 编程式导航
在小程序中实现页面的跳转,有两种方式: 声明式导航:navigator 组件编程式导航:使用小程序提供的 API 编程式导航 API 提供了五个常用的 API 方法: wx.navigateTo():保留当前页面,跳转到应用内…...
2025 使用docker部署centos7容器并且需要centos7容器能通过ssh登录SSH 登录的CentOS7容器
以下是使用 Docker 部署可 SSH 登录的 CentOS7 容器的步骤: 1.创建 Dockerfile(保存为 Dockerfile.centos7): vim Dockerfile.centos7 #复制如下内容 FROM centos:7# 备份原有的 yum 源配置文件 RUN mv /etc/yum.repos.d/CentO…...
docker安装向量数据库Milvus及可视化工具 Attu
前置条件 1.安装了docker 2.服务器网络正常,可以连接到容器下载地址 3.服务器磁盘空间正常,docker磁盘占用过大,请参考docker容量占用过大解决办法 一、下载yml文件 可在文章资源下载或者自行下载:下载yml 下载这个单机版本的…...
从模拟到现实:Sensodrive高精度力反馈技术赋能物流运输的高效与安全
在现代物流行业中,司机短缺、二氧化碳排放增加和利润空间紧张等问题日益凸显。为应对这些挑战,Sensodrive的SensoWheel和SensoPedals产品在自驾卡车中的应用,提供了更为高效的运输解决方案,有效缓解了这些问题。 Fernride公司利用…...
无需qt-creator,使用Trae从0到1生成qt的开发、构建、调试环境
一、安装 Qt 开发环境 确保已经安装了 Qt,没有安装的可以自己在网上搜索怎么安装,安装时可选择不安装qt creator,但是qt开发库和编译器要安装,这里我选择的编译器是MinGW, 安装好以后,记录下qt开发库和Min…...
整理和总结微信小程序的高频知识点
前言 近期萌生了一些想法,感觉可以做一个小程序作为产出。 但小程序做得比较少,因此边做边复习。整理和总结了一些高频知识点和大家一起分享。 一、模板和组件 1.1模板(Template) 优势 简单灵活:模板定义和使用都较…...
VMware主机换到高配电脑,高版本系统的问题
原来主机是i3 ,windows7系统,vmware 14.0,虚机系统是ubuntu 14.04。目标新机是i7 14700KF,windows11系统。原以为安装虚拟机,将磁盘文件,虚拟机配置文件拷贝过去可以直接用。 新目标主机先安装了vmware 15,运行原理虚机࿰…...
“锈化”Python:用Rust重塑Python生态的六大工具深度解析
前言:为何“锈化”Python? Python以其简洁的语法和强大的生态系统成为数据科学、Web开发和自动化领域的首选语言。然而,随着项目规模和性能需求的增长,Python的一些传统工具在速度、内存效率和安全性上面临瓶颈。近年来ÿ…...
6.3考研408数据结构中BFS与DFS的易错点及难点解析
一、广度优先算法(BFS)易错点 队列操作失误 未正确处理节点入队顺序(如未按层序逐层扩展),导致结果混乱。在出队后未立即标记节点为已访问,可能引发重复访问(尤其在存在环的图中)。示…...
在Ubuntu上安装MEAN Stack的4个步骤
在Ubuntu上安装MEAN Stack的4个步骤为:1.安装MEAN;2.安装MongoDB;3.安装NodeJS,Git和NPM;4.安装剩余的依赖项。 什么是MEAN Stack? 平均堆栈一直在很大程度上升高为基于稳健的基于JavaScript的开发堆栈。…...
如何通过Odoo 18创建与配置服务器操作
如何通过Odoo 18创建与配置服务器操作 服务器操作是Odoo实现业务流程自动化的核心工具,允许你在服务器端执行自动化任务,通常由按钮点击或自动化工作流等事件触发。这些操作使用 Python 编写,能够执行复杂的业务逻辑,从而增强 Od…...
【QGIS_Python】在QGIS的Python控制台生成SHP格式点数据并显示标注
参考文章: 「GIS教程」使用DeepSeek辅助QGIS快速制图 | 麻辣GIS 示例代码说明:使用参考文章中的省会城市坐标点,左侧增加一列城市序号code, 图层标注显示 code 城市名称,同时在指定路径下生成对应SHP格式点数据。 import os fr…...
torcharrow gflags版本问题
问题描述 其实仍然是很简单的编译问题,但是又弄了一整个下午加几乎整个晚上,进度缓慢,又吸取了教训,因而还是来记录一下。 在试图使用torcharrow进行推荐系统模拟的时候,撰写的python程序报错:ERROR: flag…...
Spring IoC DI入门
一、Spring,Spring Boot和Spring MVC的联系及区别 Spring是另外两个框架的基础,是Java生态系统的核心框架,而SpringMVC是Spring 的子模块,专注于 Web 层开发,基于 MVC 设计模式(模型-视图-控制器ÿ…...
Vala编程语言教程-语言元素
语言元素 方法 在Vala中,函数无论是否定义在类内部均称为方法。下文将统一使用“方法”这一术语。 int method_name(int arg1, Object arg2) {return 1; } 此代码定义了一个名为 method_name 的方法,接受两个参数(一个整数值,一…...
数据可信安全流通实战,隐语开源社区Meetup武汉站开放报名
隐语开源社区 Meetup 系列再出发!2025 年将以武汉为始发站,聚焦"技术赋能场景驱动",希望将先进技术深度融入数据要素流转的各个环节,推动其在实际应用场景中落地生根,助力释放数据要素的最大潜能!…...
windows 10 系统配置Node
目录 什么是Node.js 什么是Npm Node.js环境搭建 下载 解压 配置环境变量 npm配置 如何运行下载的Node.js项目 什么是Node.js 在 Node.js 之前,JavaScript 只能运行在浏览器中,作为网页脚本使用,为网页添加一些特效,或者和…...
2025年Postman的五大替代工具
虽然Postman是一个广泛使用的API测试工具,但许多用户在使用过程中会遇到各种限制和不便。因此,可能需要探索替代解决方案。本文介绍了10款强大的替代工具,它们能够有效替代Postman,成为你API测试工具箱的一部分。 什么是Postman&…...
城市街拍人像自拍电影风格Lr调色教程,手机滤镜PS+Lightroom预设下载!
调色教程 城市街拍人像自拍的电影风格 Lr 调色,是利用 Adobe Lightroom 软件,对在城市街景中拍摄的人像自拍照片进行后期处理,使其呈现出电影画面般独特的视觉质感与艺术氛围。通过一系列调色操作,改变照片的色彩、明暗、对比等元…...
HTML图像标签的详细介绍
1. 常用图像格式 格式特点适用场景JPEG有损压缩,文件小,不支持透明适合照片、复杂图像PNG无损压缩,支持透明(Alpha通道)适合图标、需要透明背景的图片GIF支持动画,最多256色简单动画、低色彩图标WebP谷歌开…...
C++进阶——红黑树的实现
目录 1、红黑树的概念 1.1 红黑树的定义 1.2 红黑树的规则 1.3 为什么没有一条路径会比其他路径长出两倍 1.4 红黑树的性能 2、红黑树的实现 2.1 红黑树的结构 2.2 红黑树的插入 2.2.1 红黑树插入一个值的大概过程 2.2.2 情况1:变色 2.2.3 情况2ÿ…...
Linux 文件操作-标准IO函数1-文件指针、文件缓冲区(行缓冲、全缓冲、无缓冲)的验证
目录 1.文件指针 2.文件缓冲区 2.1 行缓冲 2.2. 全缓冲 2.3. 无缓冲 3. 程序验证: (1)main.c执行test1(),打印hello world,不加 \n 换行符 (2)刷新缓冲区方法1:使用\n (3&am…...
中国历史文化名城分布矢量数据
中国,这片古老而厚重的土地,承载着上下五千年的文明,从北国的冰天雪地到南疆的热带雨林,从东海之滨的波涛汹涌到西域大漠的风沙漫天,无数的历史文化名城如繁星般散布其间。 它们是岁月长河中沉淀下来的瑰宝࿰…...
蓝桥杯十天冲刺-day1(日期问题)
日期问题 基础循环遍历模板 对于蓝桥杯所有的日期问题遍历,都可以使用的上 for(year2000;year<2022;year) for(month1;month<12;month) for(day1;day<31;day) {if(month1||month3||month5||month7||month8||month10||month12);else if(month2){if((year…...
漏洞知识点《Tornado框架中RequestHandler的对象》
Tornado框架中RequestHandler的所有对象 [SUPPORTED_METHODS, _INVALID_HEADER_CHAR_RE, __class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __init_subclass__, __le__, __lt__, __module__,…...
动态规划(6.不同路径II)
题目链接:63. 不同路径 II - 力扣(LeetCode) 解法: 本题为不同路径的变型,只不过有些地方有「障碍物」,只要在「状态转移」上稍加修改就可解决。 状态表示: 对于这种Γ路径类」的问题…...
【算法学习】最小公倍数问题
前言: 求最小公倍数的两种算法: 求两个正整数的最小公倍数,比如3和5的最小公倍数是15,6和8的最小公倍数是24。 本片讨论如何求两个数的最小公倍数,第一种方法是通过最大公约数来求,第二种方法是累加法。 由…...
Spring Boot 整合 Apache Flink 教程
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 Spring Boot 整合 Apache Flink 教程 一、背景与目标 Apache Flink 是一个高性能的分布式流处理框架,而Spring Boot提供了快速构建企业级应用的…...
进制转换(R转十)(1290. 二进制转换十进制、1292. 十六进制转十进制、1291. 八进制转十进制、1405. 小丽找潜在的素数)
题单地址:题单中心-东方博宜OJ 这里以二进制转十进制为例(按位加权求和法) 1290. 二进制转换十进制 问题描述 请将一个 25 位以内的 2 进制正整数转换为 1010 进制! 输入 一个 25 位以内的二进制正整数。 输出 该数对应的…...
通过启用Ranger插件的Hive审计日志同步到Doris做分析
以下是基于Apache Doris的Ranger Hive审计日志同步方案详细步骤,结合审计日志插件与数据导入策略实现: 一、Doris环境准备 1. 创建审计日志库表 参考搜索结果的表结构设计,根据Ranger日志字段调整建表语句: CREATE DATABASE IF…...
Node.js框架Express、Koa、Koa2、Egg 和 NestJS 的对比分析
以下是 Express、Koa、Koa2、Egg 和 NestJS 的对比分析,从多个维度梳理它们的区别和适用场景: 1. 历史背景与定位 框架背景与定位ExpressNode.js 早期框架,灵活轻量,生态丰富,适合快速开发简单应用。KoaExpress 原班团…...
蓝桥杯--冲刺题单--随时更新
冲刺题单 感谢up主溶金落梧桐(uid:40733116),我是看了他的视频后总结的。 简单模拟(循环数组日期进制) 1.蓝桥19723–分布式队列 package datasimulation;import java.util.Scanner;public class Test3 {//计算数组…...
新一代电子数据取证专家 | 苏州龙信信息科技有限公司
本文关键词:电子取证、手机取证、计算机取证、云取证 关于我们About us 苏州龙信信息科技有限公司专注于电子数据取证、大数据、信息安全等领域,核心业务主要涵盖取证工具研发、大数据融合分析、案件技术支持、取证能力培训等,先后为执法部门…...
SSRF 攻击与防御:从原理到落地实践
1. 什么是 SSRF? SSRF(Server-Side Request Forgery) 是一种常见的Web安全漏洞。当服务器提供了某种对外请求的功能,如“URL 参数直接转发请求”,攻击者就可以通过精心构造的URL,让服务器“自己”去访问特…...
socks 协议介绍
SOCKS协议详解 一、基本定义与核心功能 SOCKS(Socket Secure)是一种网络传输协议,主要用于通过代理服务器转发客户端与目标服务器之间的通信请求。其核心功能包括隐藏用户真实IP地址、穿透防火墙限制以及支持多种网络协议(如TCP…...
不使用负压电源,ADC如何测量正负压?
电路图来自ZLinear的开源数据采集板卡DL8884_RFN,是一个比较常见的电压偏置采集法 对电路进行分析,所以说可以先看下采集卡的模拟输入部分的参数如下: 通道数量: 8通道单端输入/4通道差分输入 分辨率: 16位逐次逼近型(SAR) ADC 采样速率: 40…...
服务的拆分数据的迁移
参考: 数据迁移调研...
强推 Maven多镜像源快速切换工具,GUI操作超便捷
引言 在开发过程中,配置Maven的settings.xml文件以优化依赖下载速度是一个常见的需求。然而,手动编辑XML文件不仅繁琐,还容易出错。本文将介绍如何使用Python和Tkinter构建一个图形界面工具,帮助开发者快速、安全地切换Maven镜像…...
Qt6.8实现麦克风音频输入音频采集保存wav文件
一.本文目的 实现在Qt中接收麦克风数据并保存为WAV文件,使用QAudioInput来录音,并使用QFile来保存数据到WAV文件。 开发环境:QT6.8 本文用极简代码实现,核心代码只需不到100行。 二.代码实现...
自动驾驶AEB误触发率评估的必要测试里程估计
文章目录 一 问题背景与行业挑战二 数学建模框架2.1 基础假设2.2 贝叶斯推断流程先验分布选择: 使用 Γ \Gamma Γ分布作为 λ \lambda λ的共轭先验参数 α 0 \alpha_0 α0和 β 0 \beta_0 β0的工程物理意义可靠性判断条件 三 数值求解方法1. 无信息先验场景 ( α 0 1 ,…...
python3 -m http.sever 8080加载不了解决办法
解决方法很多,本文设置各种处理方法,逻辑上需要根据你的自身情况选择 我会告诉你遇到这种问题怎么做,根据具体症状处理 如需转载,标记出处 背景: 1。如图 2.。域名访问不了 http://www.meiduo.site:8080/register.html 上面的域名访问不了,下面的倒是正常 http://127…...
BYU-YOLO数据格式准备
BYU - Locating Bacterial Flagellar Motors 2025(在3D断层扫描图像中定位细菌鞭毛马达) 一、数据介绍 1.竞赛介绍 在本次竞赛中,您的任务是在3D断层扫描图像中找到鞭毛马达的中心位置。断层扫描图像是物体的三维体积表示。每个断层扫描图像作为一个独立的目录提供,其中…...
java NIO中的FileSystems工具类可以读取本地文件系统,ZIP/JAR等,无需解压处理,还可以复制文件
在Java NIO(java.nio.file包)中,FileSystems 是一个工具类,用于操作和管理文件系统。它提供了静态方法来获取或创建文件系统实例,并支持自定义文件系统实现。以下是其核心功能和用法: 1. 核心功能 (1) 获取…...
群体智能优化算法-模拟退火优化算法(Simulated Annealing, SA,含Matlab源代码)
摘要 模拟退火(SA)算法是一种基于物理退火过程的全局优化算法,其核心思想来源于热力学中的退火过程:将材料加热到高温后再缓慢冷却,使其分子结构趋于最低能量状态,从而获得稳定结构。SA 算法利用 Metropol…...
knowledge-微前端(多个前端应用聚合的一个应用架构体系,每个小的应用可独立运行,独立开发,独立部署上线)
1.前言 微前端,将一个大的前端应用拆分为多个小型的,独立开发的前端应用,每一个小型的应用都可以单独的开发,部署和运行。这种结构允许不同的团队使用不同的技术栈来开发应用的不同部分,提高开发的效率与灵活性。 2.实…...
目标检测中归一化的目的?
在目标检测任务中,归一化坐标和尺寸时需要除以图像的宽度和高度,主要有以下几个原因: 1. 统一尺度 不同图像可能具有不同的宽度和高度。通过将坐标和尺寸除以图像的宽度和高度,可以将所有图像的标注信息统一到相同的尺度范围([0, 1])。这使得模型在训练和推理时能够处理…...