网络编程、UDP、TCP、三次握手、四次挥手
一、初识网络编程
网络编程的概念:在网络通信协议下,不同计算机上运行的程序,进行的数据传输。
应用场景:即时通信、网游对战、金融证券、国际贸易、邮件等等。
不管是什么场景,都是计算机和计算机之间通过网络进行数据传输。
Java中可以使用java.net包下的技术开发出常见的网络应用程序。
二、常见的软件架构
(一)B/S架构
概念:只需要一个浏览器,用户通过不同的网址,可以访问不同的服务器。例如京东和淘宝。
优缺点:
- 不需要开发客户端,只需要开发服务端
- 用户不需要下载,打开浏览器就能使用
- 如果应用过大,用户体验受到影响
(二)C/S架构
概念:在用户本地需要下载并安装客户端程序,在远程有一个服务端程序。例如QQ、Steam。
优缺点:
- 画面可以做的非常精美,用户体验好
- 需要开发客户端,也需要开发服务端
- 用户需要下载和更新的时候太麻烦
有些软件,例如京东和淘宝,既又C/S架构,也有B/S架构。
三、网络编程三要素
(一)IP
IP:(Internet Protocol)是互联网协议地址,也称IP地址,是设备在网络中的地址,是唯一的标识。常见的IP分为:IPv4、IPv6
1.IPv4
IPv4:(Internet Protocol version4)是互联网通信协议第四版。 采用32为地址长度,分成4组,每组取值范围是0~255,一共有42亿多,为了方便记忆,最后采用点分十进制表示法,例如:192.168.1.66。但是ipv4已经分配完毕了,所以需要ipv6进行补充。
IPv4的地址分类形式:
- 公网地址(万维网使用)和私有地址(局域网使用)。
- 192.168.开头的就是私有地址,范围是192.168.0.0--192.168.255.255,专门为组织机构内部使用,以此节省IP。
特殊IP地址:127.0.0.1,也可以是localhost:是回送地址,也称本地回环地址,又称本机IP,永远只会寻找当前所在本机。
检查网络常用的CMD命令:
- ipconfig:查看本机IP地址
- ping:检查网络是否连通
2.IPv6
IPv6:(Internet Protocol version6)是互联网通信协议第六版。采用128位地址长度,分成8组。IPv6一共有2^128次方个IP,采用冒分十六进制表示法:

目前也有很多APP支持IPv6。
3.InetAddress的使用
public class MyInetAddressDemo1 {public static void main(String[] args) throws UnknownHostException {/*static InetAddress getByName(String host) 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址String getHostName() 获取此IP地址的主机名String getHostAddress() 返回文本显示中的IP地址字符串*/// 1.获取InetAddress的对象// IP的对象 一台电脑的对象InetAddress address = InetAddress.getByName("PC-20240723RWZC");System.out.println(address); // PC-20240723RWZC/192.168.0.4String hostName = address.getHostName();System.out.println(hostName); // PC-20240723RWZCString hostAddress = address.getHostAddress();System.out.println(hostAddress); // 192.168.0.4}
}
(二)端口号
端口号:是应用程序在设备中唯一的标识。一个端口号只能被一个应用程序使用。
由两个字节表示的整数,取值范围:0~65535。其中0~1023的端口号用于一些知名的网络服务或者应用,我们使用1024以上的端口号即可。
以下是一些常见服务使用的端口号列表:这些端口号被IANA(Internet Assigned Numbers Authority)分配给特定的服务,并且广为人知。它们在网络通信中扮演着重要的角色,确保数据能够准确地发送到正确的服务。
- 21端口:FTP 文件传输服务。
- 22端口:SSH 远程连接服务。
- 23端口:TELNET 终端仿真服务。
- 25端口:SMTP 简单邮件传输服务。
- 53端口:DNS 域名解析服务。
- 80端口:HTTP 超文本传输服务。
- 110端口:POP3(E-mail)。
- 123端口:NTP(网络时间协议)。
- 135、137、138、139端口:局域网相关默认端口。
- 161端口:SNMP(简单网络管理协议)。
- 389端口:LDAP(轻量级目录访问协议)。
- 443端口:HTTPS服务器。
- 465端口:SMTP(简单邮件传输协议)。
- 873端口:rsync。
- 989端口:FTPS。
- 993端口:IMAPS。
- 995端口:POP3S。
- 1080端口:SOCKS代理协议服务器常用端口号。
- 1433端口:MS SQL*SERVER数据库server。
- 1521端口:Oracle 数据库。
- 3306端口:MYSQL数据库端口。
- 3389端口:WIN2003远程登录。
- 5432端口:postgresql数据库端口。
- 6379端口:Redis数据库端口。
- 8080端口:TCP服务端默认端口、JBOSS、TOMCAT。
(三)协议
1.协议概述
协议:是指数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。


2.UDP协议
2.1UDP协议介绍
UDP协议又叫用户数据报协议(User Datagram Protocol),是面向无连接通信协议,不管是否已经连接成功,都会直接发送数据。
特点是:速度块,有大小限制,一次最多发送64K,数据不安全,易丢失数据。
UDP协议适用场景:网络会议、语音通话、在线视频,丢失数据没有太大的影响。
2.2使用UDP协议发送数据
步骤:
- 创建发送端的DatagramSocket对象
- 数据打包(DatagramPacket)
- 发送数据
- 释放资源
代码实现UDP协议发送数据:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class SendMessageDemo {public static void main(String[] args) throws IOException {// UDP协议发送数据// 1.创建DatagramSocket对象// 细节:绑定端口,以后就是通过这个端口往外发送// 空参:所有可用的端口中随机一个进行使用// 有参:指定端口号进行绑定DatagramSocket datagramSocket = new DatagramSocket();// 2.打包数据String str = "hello world";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("127.0.0.1");DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, address, 10086);// 3.发送数据datagramSocket.send(datagramPacket);// 4.释放资源datagramSocket.close();}
}
2.3使用UDP协议接收数据
步骤:
创建接收端的DatagramSocket对象
接收打包好的数据
解析数据包
释放资源
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;public class ReceiveMessageDemo {public static void main(String[] args) throws IOException {// UDP协议接收数据// 1.创建DatagramSocket对象// 细节:在接收的时候,一定要绑定端口,而且绑定的端口一定要跟发送的端口保持一致DatagramSocket datagramSocket = new DatagramSocket(10086);// 2.接收数据包byte[] bytes = new byte[1024];DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);// 该方法是阻塞的,程序执行到这一步的时候,会在这里等待发送端发送消息datagramSocket.receive(datagramPacket);// 3.解析数据包byte[] data = datagramPacket.getData();InetAddress address = datagramPacket.getAddress();int length = datagramPacket.getLength();int port = datagramPacket.getPort();SocketAddress socketAddress = datagramPacket.getSocketAddress();int offset = datagramPacket.getOffset();System.out.println("接收到的数据:" + new String(data, 0, length));System.out.println("该数据是从:" + address + "这台电脑中的" + port + "端口发出的");System.out.println(socketAddress);System.out.println("数据偏移量:" + offset);// 4.释放资源datagramSocket.close();}
}
实现过程:
先启动接收程序,再启动发送程序,运行结果:

2.4使用UDP协议实现聊天室
案例需求
UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
public class SendMessageDemo {public static void main(String[] args) throws IOException {// 1.创建对象DatagramSocket的对象DatagramSocket datagramSocket = new DatagramSocket();// 2.打包数据Scanner scanner = new Scanner(System.in);InetAddress address = InetAddress.getByName("127.0.0.1");while (true) {System.out.println("请输入消息:");String str = scanner.nextLine();if ("886".equals(str)) {System.out.println("程序终止!");break;}byte[] bytes = str.getBytes();DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, address, 10086);// 3.发送数据datagramSocket.send(datagramPacket);}// 4.释放资源datagramSocket.close();}
}
public class ReceiveMessageDemo {public static void main(String[] args) throws IOException {// 1.创建对象DatagramSocket的对象DatagramSocket datagramSocket = new DatagramSocket(10086);// 2.接收数据包byte[] bytes = new byte[1024];DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);while (true) {datagramSocket.receive(datagramPacket);// 3.解析数据包byte[] data = datagramPacket.getData();int length = datagramPacket.getLength();String ip = datagramPacket.getAddress().getHostAddress();String hostName = datagramPacket.getAddress().getHostName();int port = datagramPacket.getPort();// 4.打印数据System.out.println(hostName + "电脑的" + ip + ":" + port + "发送消息:" + new String(data, 0, length));}}
}
运行结果:


这里的hostName是activate.netsarang.com的原因是:在某些情况下,如果系统或网络环境中的 hosts 文件(在Windows中位于C:\Windows\System32\drivers\etc\hosts,在Unix/Linux系统中通常位于/etc/hosts)中有相应的条目,那么系统会直接从 hosts 文件中获取主机名,而不是去查询DNS。
我本地的host文件:找到第一个主机名返回

还可以设置多窗口聊天:


2.5UDP的三种通信方式
2.5.1单播——一对一通信(One-to-One)
在这种模式下,一个UDP套接字(客户端)向另一个UDP套接字(服务器)发送数据。客户端知道服务器的IP地址和端口号,可以直接向服务器发送数据包。服务器监听指定的端口,接收来自客户端的数据包。这种模式是最简单的UDP通信方式,适用于客户端和服务器之间的直接通信。
2.5.2组播——一对多通信(One-to-Many)
在一对多通信中,一个服务器向多个客户端发送数据。服务器使用相同的数据包发送给所有已知客户端的IP地址和端口号。这种模式常用于广播服务,如网络广播、在线游戏或多媒体流服务。服务器不需要为每个客户端维护一个单独的连接,而是向所有客户端广播数据。
组播地址:224.0.0.0~239.255.255.255
其中224.0.0.0~224.0.0.255为预留的组播地址
组播发送端代码:
public class SendMessageDemo {public static void main(String[] args) throws IOException {//创建MulticastSocket对象MulticastSocket ms = new MulticastSocket();// 创建DatagramPacket对象String s = "hello world !";byte[] bytes = s.getBytes();InetAddress address = InetAddress.getByName("224.0.0.1");int port = 10000;DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, address, port);// 调用MulticastSocket发送数据方法发送数据ms.send(datagramPacket);// 释放资源ms.close();}
}
组播接收端代码:
public class ReceiveMessageDemo1 {public static void main(String[] args) throws IOException {// 1. 创建MulticastSocket对象MulticastSocket ms = new MulticastSocket(10000);// 2. 将当前本机,添加到224.0.0.1的这一组当中InetAddress address = InetAddress.getByName("224.0.0.1");ms.joinGroup(address);// 3. 创建DatagramPacket数据包对象byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);// 4. 接收数据ms.receive(dp);// 5. 解析数据byte[] data = dp.getData();int len = dp.getLength();String ip = dp.getAddress().getHostAddress();String name = dp.getAddress().getHostName();System.out.println("ip为:" + ip + ",主机名为:" + name + "的人,发送了数据:" + new String(data, 0, len));// ip为:192.168.0.4,主机名为:PC-20240723RWZC的人,发送了数据:hello world !// 6. 释放资源ms.close();}
}
接收端可以创建多个,但要保证每一个接收端都要将当前本机,添加到224.0.0.1的这一组当中。这样,发送端发送数据,多个接收端就可以同时接收到了。
2.5.3广播——多对多通信(Many-to-Many)
在多对多通信中,多个客户端之间可以直接相互通信,而不需要通过一个中心服务器。每个客户端都可以发送和接收来自其他客户端的数据包。这种模式适用于需要点对点通信的应用,如即时消息、文件共享或P2P网络。在这种模式下,每个客户端都扮演着发送者和接收者的角色。
广播地址:255.255.255.255
// 发送端
public class ClientDemo {public static void main(String[] args) throws IOException {// 1. 创建发送端Socket对象(DatagramSocket)DatagramSocket ds = new DatagramSocket();// 2. 创建存储数据的箱子,将广播地址封装进去String s = "广播 hello";byte[] bytes = s.getBytes();InetAddress address = InetAddress.getByName("255.255.255.255");int port = 10000;DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);// 3. 发送数据ds.send(dp);// 4. 释放资源ds.close();}
}// 接收端
public class ServerDemo {public static void main(String[] args) throws IOException {// 1. 创建接收端的Socket对象(DatagramSocket)DatagramSocket ds = new DatagramSocket(10000);// 2. 创建一个数据包,用于接收数据DatagramPacket dp = new DatagramPacket(new byte[1024],1024);// 3. 调用DatagramSocket对象的方法接收数据ds.receive(dp);// 4. 解析数据包,并把数据在控制台显示byte[] data = dp.getData();int length = dp.getLength();System.out.println(new String(data,0,length));// 5. 关闭接收端ds.close();}
}
3.TCP协议
3.1TCP协议介绍
TCP协议:又叫传输控制协议(Transmission Control Protocol),是面向连接的通信协议。是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,通过Socket产生IO流来进行网络通信,通信之前要保证连接已经建立。
特点是:速度慢,没有大小限制,数据安全。
TCP协议适用场景:对于数据有非常高的要求,不能丢失任何数据,例如下载软件、文字聊天、发送邮件。
3.2使用TCP协议发送和接收数据
public class Client {public static void main(String[] args) throws IOException {// TCP协议,发送数据// 1.创建Socket对象// 细节:在创建对象的同时会连接服务端;如果连接不上,代码会报错Socket socket = new Socket("127.0.0.1", 10001);// 2.可以从连接通道中获取输出流OutputStream os = socket.getOutputStream();// 写出数据os.write("hello world".getBytes());// 3.释放资源os.close();socket.close();}
}public class Server {public static void main(String[] args) throws IOException {// TCP协议,接收数据// 1.创建对象ServerSocketServerSocket serverSocket = new ServerSocket(10001);// 2.监听客户端的连接Socket socket = serverSocket.accept();// 3.从连接通道中获取输入流读取数据InputStream is = socket.getInputStream();int len;while ((len = is.read()) != -1) {System.out.print((char) len);}// 4.释放资源is.close();socket.close();}
}
先运行Server服务器,再运行Client客户端,运行结果:

3.3解决TCP传输过程中的中文乱码问题
上面的代码使用的是字节流传输,在传输中文时会产生乱码,我们可以使用BufferReader来接收:
public class Server2 {public static void main(String[] args) throws IOException {// TCP协议,接收数据// 1.创建对象ServerSocketServerSocket serverSocket = new ServerSocket(10001);// 2.监听客户端的连接Socket socket = serverSocket.accept();// 3.从连接通道中获取输入流读取数据InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));int len;while ((len = br.read()) != -1) {System.out.print((char) len);}// 4.释放资源is.close();socket.close();}
}
运行结果:


3.4三次握手

3.5四次挥手

相关文章:
网络编程、UDP、TCP、三次握手、四次挥手
一、初识网络编程 网络编程的概念:在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件等等。 不管是什么场景,都是计算机和计算机之间通过网络进行…...
程序员的生活周刊 #7:耐克总裁被裁记
0. 庙宇 这张图来自 Tianshu Liu, 被树木环绕的宝塔庙宇 1. 耐克总裁 耐克最近的总裁 John Donahoe 干了 5 年,终于被裁掉了。 这位总裁即不了解球鞋文化,也没有零售经验,但不懂事的董事会还是聘用它,寄托把耐克从运…...
sparkSQL的UDF,最常用的regeister方式自定义函数和udf注册方式定义UDF函数 (详细讲解)
- UDF:一对一的函数【User Defined Functions】 - substr、split、concat、instr、length、from_unixtime - UDAF:多对一的函数【User Defined Aggregation Functions】 聚合函数 - count、sum、max、min、avg、collect_set/list - UDTF:…...
【Ubuntu20】VSCode Python代码规范工具配置 Pylint + Black + MyPy + isort
常用工具: 在 Ubuntu20 下,有以下常见的 Python 代码工具: 静态分析工具: Pylint 和 Flake8 功能范围:Pylint功能非常强大,能够检查代码质量、潜在错误、代码风格、复杂度等多个方面, 并生成详细的报…...
游戏提示错误:xinput1_3.dll缺失?四种修复错误的xinput1_3.dll文件
在计算机的运行过程中,我们可能会遇到各种各样的问题,其中与“xinput1_3.dll”相关的问题也并不罕见。“xinput1_3.dll”是一个在许多游戏和多媒体应用程序运行过程中可能会用到的动态链接库文件。当我们启动某些游戏时,可能会突然弹出一个错…...
YOLOv11融合IncepitonNeXt[CVPR2024]及相关改进思路
YOLOv11v10v8使用教程: YOLOv11入门到入土使用教程 一、 模块介绍 论文链接:https://arxiv.org/abs/2303.16900 代码链接:https://github.com/sail-sg/inceptionnext 论文速览:受 ViT 长距离建模能力的启发,大核卷积…...
[Web安全 网络安全]-学习文章汇总导航(持续更新中)
文章目录: 一:学习路线资源 1.路线 2.资源 二:工具 三:学习笔记 1.基础阶段 2.进阶阶段 四:好的参考 五:靶场 博主对网络安全很感兴趣,但是不知道如何取学习,自己一步一步…...
Docker Compose部署Rabbitmq(Docker file安装延迟队列)
整个工具的代码都在Gitee或者Github地址内 gitee:solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb github:GitHub - ZeroNing/solomon-parent: 这个项目主要是…...
SpringBoot+FileBeat+ELK8.x版本收集日志
一、准备环境 1、ElasticSearch:8.1.0 2、FileBeat:8.1.0 3、Kibana:8.1.0 4、logstach:8.1.0 本次统一版本:8.1.0,4个组件,划分目录,保持版本一致。 说明:elasticsearch和kib…...
本地模型导入ollama
文章目录 Modelfile模板导入到 ollama Modelfile模板 在本地模型目录下创建 Modelfile FROM ./qwen2.5-7b-instruct-q4_k_m.gguf# 设定温度参数为1 [更高的更具有创新性,更低的更富有连贯性] PARAMETER temperature 1 # 将上下文窗口大小设置为4096,这…...
scala Map训练
Map实训内容: 1.创建一个可变Map,用于存储图书馆中的书籍信息(键为书籍编号,值为包含书籍名称、作者、库存数量的元组),初始化为包含几本你喜欢的书籍信息。 2.使用 操作符添加两本新的书籍到图书馆集合中。 3.根据书籍编号查询某一本特定的书籍信息&…...
WorkFlow源码剖析——Communicator之TCPServer(下)
WorkFlow源码剖析——Communicator之TCPServer(下) 前言 系列链接如下: WorkFlow源码剖析——GO-Task 源码分析 WorkFlow源码剖析——Communicator之TCPServer(上) WorkFlow源码剖析——Communicator之TCPServer&…...
数据结构与算法分析:专题内容——动态规划2之例题讲解(代码详解+万字长文+算法导论+力扣题)
一、最长公共子序列 在生物应用中,经常需要比较两个(或多个)不同生物体的 DNA。一个 DNA 串由一串称为碱基(base)的分子组成,碱基有腺嘌呤、鸟嘌呤、胞嘧啶和胸腺嘧啶 4 种类型。我们用英文单词首字母表示 4 种碱基,这样就可以将一个 DNA 串…...
【Qt】QTreeView 和 QStandardItemModel的关系
QTreeView 和 QAbstractItemModel(通常是其子类,如 QStandardItemModel 或自定义模型)是 Qt 框架中的两个关键组件,它们之间存在密切的关系。 关系概述 QTreeView: QTreeView 是一个用于显示和编辑层次数据的视图小部…...
containerd配置私有仓库registry
机器ip端口regtisry192.168.0.725000k8s-*-------k8s集群 1、镜像上传 rootadmin:~# docker push 192.168.0.72:5000/nginx:1.26.1-alpine The push refers to repository [192.168.0.72:5000/nginx] 6961f0b8531c: Pushed 3112cd521249: Pushed d3f50ce9b5b5: Pushed 9efaf2eb…...
深入解析语音识别中的关键技术:GMM、HMM、DNN和语言模型
目录 一、高斯混合模型(GMM)与期望最大化(EM)算法二、隐马尔可夫模型(HMM)三、深度神经网络(DNN)四、语言模型(LM)五、ASR系统的整体工作流程结论 在现代语音…...
C++循环引用
C循环引用指的是两个或多个类之间互相引用对方,形成一个循环的引用关系。 循环引用的问题: 编译错误:编译器在编译过程中会按照包含关系依次编译每个文件,当编译ClassA时,它会尝试包含ClassB.h文件,而…...
dayseven-因果分析-图模型与结构因果模型
在数学上,“图”(graph)是顶点(vertex,也可以称为节点)和边(edge)的集合,表示为图G(V,E),其中V是节点的集合,E是边的集合,图中的节点之间通过边相连(也可以不相连&…...
并发编程(8)—— std::async、std::future 源码解析
文章目录 八、day81. std::async2. std::future2.1 wait()2.2 get() 八、day8 之前说过,std::async内部的处理逻辑和std::thread相似,而且std::async和std::future有密不可分的联系。今天,通过对std::async和std::future源码进行解析&#x…...
稻米分类和病害检测数据集(猫脸码客 第237期)
稻米分类图像数据集:推动农业智能化发展的关键资源 在农业领域,稻米作为世界上最重要的粮食作物之一,其品种繁多,各具特色。然而,传统的稻米分类方法往往依赖于人工观察和经验判断,不仅耗时费力࿰…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
