JavaEE(系列20) -- 网络编程之UDP和TCP套接字

目录

1. 网络编程

2. UDP网络编程

2.1 DatagramSocket API

2.2 DatagramPacket API

2.3 基于UDP实现的回显服务器 

2.3.1 UDP服务器设计步骤

2.3.2 服务器代码

2.3.3 客户端代码

2.3.4 基于UDP写一个字典服务器

3. TCP网络编程

3.1 ServerSocketAPI

3.2 SocketAPI

​3.3 基于TCP实现的回显服务器 

3.3.1 TCP服务器实现步骤

3.3.2 TCP服务器代码

3.3.3 TCP客户端代码

3.3.4 TCP实现查词典的服务器 


1. 网络编程

        在网络通信中, 数据的发送是从应用层开始, 一直封装到物理层然后进行发送的, 应用层要将数据交给传输层进行封装; 而接收方拿到数据后是从物理层到应用层进行分用, 传输层要将拿到的数据再分用给应用层进行使用, 网络编程实际操作中最关键的就是我们所能控制的应用层和传输层之间的交互, 而在操作系统中提供了一组API即socket, 用来实现应用层和传输层之间的交互, Java当中把操作系统提供的API进行了进一步封装以便我们进行使用.

系统提供的Socket API 主要是两组:基于TCP协议的API 和 基于UDP协议的API

 TCP和UDP这两者的协议之间差别很大,提供的api也差异很大.下面简要概括主要的区别.

TCPUDP
有连接无连接

可靠传输

不可靠传输
面向字节流面向数据报
全双工全双工

1. 什么是有连接?

        使用TCP协议, 必须是通信双方先建立连接才能进行通信(想象打电话的场景这就是有连接), 而使用UDP协议在无连接的情况下可以进行通信(想象发微信, 短信的场景).连接并不是拿一根绳子,把两个设备绑定到一块,而是一个抽象的连接,可以理解成彼此双方记录了对方的信息.比如结婚领证,两个人在民政局进行登记结婚,然后民政局就会给双方发一个结婚证,结婚证是一式两份,供双方所有,这个就是彼此双方做了一个记录,双方进行了连接.

2. 什么是不可靠性传输?

        可靠与不可靠传输指的不是安全性质, 而是说你发送出数据后, 能不能判断对方已经收到, 如果能够确定对方是否收到则就是可靠传输, 否则就是不可靠传输.UDP进行传输,只会关注发送消息,而不会关注发送的消息有没有进行接收.TCP不仅关注发送消息本身而且关注消息是否发送到达.(但是不是说通过TCP就会百分百将消息送达,也会出现丢包的行为.)

3. 什么是全双工?

        全双工是指一条通信链路, 可以双向传输(同一时间既可以发, 也可以收); 而半双工是一条链路, 只能单向通信.

                

 4. 面向字节流和面向数据报?

        面向字节流就类文件读写数据的操作, 是 “流” 式的; 而面向数据报的话数据传输则是以一个个的 “数据报” 为基本单位(一个数据报可能是若干个字节, 是带有一定的格式的).

2. UDP网络编程

2.1 DatagramSocket API

这里receive方法参数传入的是一个空的对象, receive方法内部会对这个对象进行填充, 从而构造出结果数据, 这个参数也是一个输出型参数.

2.2 DatagramPacket API

第二个是DatagramPacket, 表示一个UDP数据报, 在UDP的服务器和客户端都需要使用到, 接收和发送的数据就是在传输DatagramPacket对象, 这就是体现了UDP面向数据报的特点.

在网络编程中, 一定要注意区分清楚服务器与客户端使用之间使用的五元组, 具体如下:

  • 源IP, 就是发送方IP.
  • 源端口, 发送方端口号, 服务器需要手动指定, 客户端让系统随机分配即可.
  • 目的IP, 接收方IP, 包含在拿到的数据报中, 服务器响应时的目的IP就在客户端发来的数据报中, 客户端发送请求时的目的IP就是服务器的IP.
  • 目的端口, 接收方端口号包含在数据报中, 服务器响应时的目的端口就在客户端发来的数据报中, 客户端发送请求时的目的端口.就是服务器的端口号
  • 协议类型, 如UDP/TCP.

2.3 基于UDP实现的回显服务器 

        正常来说服务器为客户端进行提供服务,客户端向服务器发出请求,服务端根据请求来计算响应,然后将响应发送给客户端,这个过程是正常的一个网络通信,在这里本文省略计算响应的环节,服务器将客户端发送的请求进行返回.这就是一个回显程序.

2.3.1 UDP服务器设计步骤

  • 1. 创建Socket实例对象(DatagramSocket对象),需要指定服务器的端口,因为服务器是被动请求的一段,所以得先知道端口号,才能发出请求.
  • 2. 服务器启动,读取客户端的请求,将数据填充到DatagramPacket对象中,这里的请求是包含着有客户端的地址信息(IP+端口号,通过getSocketAddress获取).
  • 3. 处理客户端请求,计算响应,这里实现的是一个回显程序,直接根据请求返回来客户端的请求即可.
  • 4. 将响应返回给客户端,需要将响应打包成DatagramPacket对象,此处打包的过程跟请求的packet是不一样的,需要指定这个包发送给谁,使用getSocketAddress()进行获取.

2.3.2 服务器代码

package UDP;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;/*** Created with IntelliJ IDEA.* Description:udp 服务端* 过程:1.客户端进行请求(requestPacket),服务端进行接收请求(receive)*     2.将请求转换成字符串*     3.根据请求进行计算响应(需要返回给客户端的数据)*     4.将相应装包成responsePacket(对比requestPacket参数多了一个requestPacket的ip和端口号(responsePacket.getSocketAddress()))*     5.将打包好的responsePacket,使用send进行发送(返回给客户端)* 1. DatagramSocket是文件(快递小哥)* 2. DatagramPacket是需要传输的数据包(快递包裹)* User: YAO* Date: 2023-05-28* Time: 20:12*/
public class udpServer {//1. 先定一个socket对象// 通过网络通信必须要有socket对象private DatagramSocket socket = null;//2. 创建构造方法// 绑定一个端口号不一定会成功,有可能被别的应用程序占用// 同一个主机,同一个端口,同一时刻,只能被一个进程绑定public udpServer(int port) throws SocketException {// 构造socket的同时,指定关联/绑定的端口socket = new DatagramSocket(port);}//3. 启动服务器public void start() throws IOException {System.out.println("服务器启动");while (true){// 每次循环,要做三件事情://1.读取请求并解析DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);  // 此时的参数为输出型参数,传入一个空的对象,交给receive内部进行填充//1.1 当服务器启动,start方法被调用就会直接执行到receive这里,如果客户端还没进行发送消息,服务器就会进如堵塞等待//1.2 为了方便处理这个请求,我们将这个请求转换成String类型
//            System.out.println(Arrays.toString(requestPacket.getData()));String request = new String(requestPacket.getData(),0,requestPacket.getLength());//在这里,使用了String类的构造函数来将字节流转换为字符串。// 该构造函数有三个参数:// 第一个参数是要转换成字符串的字节数组// 第二个参数表示从字节数组中哪个位置开始转换// 第三个参数表示要转换多少个字节。//2. 根据请求计算响应(此处省略)String response = process(request);//3. 将结果写会给客户端//   3.1 根据response字符串,构造一个返回给客户端的DatagramPacket//   3.2 和请求packet是不一样的,此处构造相应的时候,需要指定这个包要发送给谁(客户端ip和端口号)//       :使用requestPacket.getSocketAddress() 这个方法包含了ip和端口号DatagramPacket responsePacket = new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),response.getBytes().length,requestPacket.getSocketAddress());//   3.3 打包完成,进行发送socket.send(responsePacket);System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),requestPacket.getPort(),request, response);}}//4. 根据请求进行计算响应//这是一个回显程序,就是客户端发送什么,服务器会送什么,后续可以根据自己需要指定返回的内容,这个函数在服务器中为一个关键public String process(String request) {return request;}public static void main(String[] args) throws IOException {udpServer udpServer = new udpServer(9090);udpServer.start();// 此处socket结束整个main方法结束,整个进程就结束了,所以就不需要进行使用socket.close();}
}

2.3.3 客户端代码

package UDP;import java.io.IOException;
import java.net.*;
import java.util.Scanner;/*** Created with IntelliJ IDEA.* Description:udp 客户端* User: YAO* Date: 2023-05-28* Time: 20:13*/
public class udpClient {private DatagramSocket socket = null;private final String serverIP;private final int serverPort;// 客户端,需要知道服务器在哪?(IP和Port)public udpClient(String serverIP, int serverPort) throws SocketException {// 对于客户端,不需要显示关联的的端口// 不代表就是没有端口,而是系统自动分配了一个端口socket = new DatagramSocket();this.serverPort = serverPort;this.serverIP = serverIP;}public void start() throws IOException {while (true){// 1. 先从控制台读取一个字符串Scanner scanner = new Scanner(System.in);System.out.println("请输入:");String request = scanner.next();// 2. 将字符串构造成UDP packet ,并进行发送// 2.1 转换成二进制的字符数组,指定的长度,指定服务器的IP,服务器的端口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);// 4. 将响应数据进行转换成字符串String response = new String(responsePacket.getData(),0,responsePacket.getLength());System.out.printf("req: %s, resp: %s\n",request, response);}}public static void main(String[] args) throws IOException {udpClient udpClient = new udpClient("127.0.0.1",9090);udpClient.start();}
}

运行结果:

 接收多个客户端发送的请求

2.3.4 基于UDP写一个字典服务器

         上面实现的回显服务器缺乏业务逻辑, 这里在上面的代码的基础上稍作调整, 实现一个 “查词典” 的服务器(将英文单词翻译成中文解释), 这里其实就很简单了, 对于客户端的代码还可以继续使用, 服务器只需把处理请求部分的代码修改即可, 我们可以继承上面的回显服务器, 重写请求部分的代码, 英语单词和汉语解释可以由一个哈希表实现映射关系, 构成词库, 然后根据请求来获取哈希表中对应的汉语解释即可

package UDP;import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;/*** Created with IntelliJ IDEA.* Description:构建简单翻译服务器* User: YAO* Date: 2023-05-29* Time: 13:16*/
public class UdpDictServer extends udpServer{// 1.使用Map数据结构存储需要翻译的词private Map<String,String> dict = new HashMap<>();// 2.帮助父类进行构造方法public UdpDictServer(int port) throws SocketException {super(port);dict.put("dog","小狗");dict.put("cat","小猫");dict.put("fuck","卧槽");// .......可以无限的插入数据,跟有道词典相比,咱们的词典就是小.}//3.重写process方法,进行根据请求进行计算响应@Override  // 1.提高可读性(用来提示这个方法是进行重写分类的)  2.校验,编译器进行检查public String process(String request){return dict.getOrDefault(request,"该单词没有查到");}public static void main(String[] args) throws IOException {UdpDictServer udpDictServer = new UdpDictServer(9090);udpDictServer.start();}
}

3. TCP网络编程

        TCP相比于UDP有很大的不同, TCP的话首先需要通信双方成功建立连接然后才可以进行通信, TCP进行网络编程的方式和文件读写中的字节流类似, 是字节为单位的流式传输,

        对于TCP的套接字, Java提供了两个类来进行数据的传输, 一个是ServerSocket, 是专门给服务器使用的Socket对象, 用来让服务器接收客户端的连接;第二个是Socket, 这个类在客户端和服务器都会使用, 进行服务器与客户端之间的数据传输通信, TCP的传输可以类比打电话的场景, 客户端发送请求后, 服务器调用ServerSocket类的accept方法来 “建立连接” (接通电话), 建立连接后两端就可以进行通信了, Socket可以获取到文件(网卡)的输入输出流对象, 然后就可以流对象进行文件(网卡)读写了, 体现了TCP面向字节流, 全双工的特点.

3.1 ServerSocketAPI

3.2 SocketAPI

3.3 基于TCP实现的回显服务器 

3.3.1 TCP服务器实现步骤

1. 创建ServerSocket实例对象,需要指定服务器的端口

2. 启动服务器,使用accept方法和客户端进行连接,如果没有客户端进行连接,此时的accept就会进入堵塞等待

3. 接受客户端发送的请求(通过Socket获取输入流InputStream流对象来读取请求)

4. 处理客户端请求进行计算响应

5. 将响应通过客户端(通过Socket获取到OutputStream流对象发送响应)

3.3.2 TCP服务器代码

package TCP;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;/*** Created with IntelliJ IDEA.* Description:* User: YAO* Date: 2023-05-31* Time: 15:09*/
public class tcpServerFinal {private ServerSocket socket = null;public tcpServerFinal(int port) throws IOException {socket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动");// 创建线程池用来使用多线程进行处理多个客户端ExecutorService pool = Executors.newCachedThreadPool();while (true){// 接收客户端的连接Socket clientSocket  = socket.accept();pool.submit(new Runnable() {@Overridepublic void run() {// 处理客户端的连接processConnection(clientSocket );}});}}private void processConnection(Socket clientSocket ) {System.out.printf("[%s:%d]客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()){// 将字节流转换成字符流进行操作// 1. 输入(接受客户端的输入)Scanner scanner = new Scanner(inputStream);// 2.输出(写入客户端)PrintWriter printWriter = new PrintWriter(outputStream);while (true){// 1.读取请求if(!scanner.hasNext()){System.out.printf("[%s:%d] 客户端下线\n", clientSocket.getInetAddress(),clientSocket.getPort());break;}// 直接使用scanner进行读取字符串String request = scanner.next();// 2.根据请求进行计算响应String response = process(request);// 3.将响应返回给客户端  // 这里println发送是带有换行的printWriter.println(response);// 由于缓冲区的存在这里我们需要自己手动进行刷新,强行将缓冲池里的东西写入到客户端printWriter.flush();System.out.printf("[%s:%d] req: %s; resp: %s\n",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);}}private String process(String request) {return request;}public static void main(String[] args) throws IOException {tcpServerFinal tcpServerFinal = new tcpServerFinal(9090);tcpServerFinal.start();}
}

3.3.3 TCP客户端代码

package TCP;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;/*** Created with IntelliJ IDEA.* Description:* User: YAO* Date: 2023-06-01* Time: 22:29*/
public class tcpClientFinal {private Socket socket = null;public tcpClientFinal(String serverIP, int serverPort) throws IOException {socket = new Socket(serverIP,serverPort);}public void start(){Scanner scanner = new Scanner(System.in);try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {PrintWriter printWriter = new PrintWriter(outputStream);Scanner scannerFromSocket = new Scanner(inputStream);while (true){System.out.println("->: ");String request = scanner.next();printWriter.println(request);// 由于缓冲区的存在这里我们需要自己手动进行刷新,强行将缓冲池里的东西写入到服务器printWriter.flush();String response = scannerFromSocket.next();System.out.printf("req: %s; resp: %s\n", request,response);}} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {tcpClientFinal tcpClientFinal = new tcpClientFinal("127.0.0.1",9090);tcpClientFinal.start();}
}

3.3.4 TCP实现查词典的服务器 

package TCP;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;/*** Created with IntelliJ IDEA.* Description:* User: YAO* Date: 2023-06-05* Time: 15:11*/
public class tcpServerDict extends tcpServerFinal{Map<String,String> dict = new HashMap<>();public tcpServerDict(int port) throws IOException {super(port);dict.put("cat", "小猫");dict.put("dog", "小狗");dict.put("bird", "小鸟");}@Overridepublic String process(String request){return dict.getOrDefault(request,"当前单词没有查到结果");}public static void main(String[] args) throws IOException {tcpServerDict tcpServerDict = new tcpServerDict(9090);tcpServerDict.start();}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/351416.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

window专业版激活

1、管理员权限进入命令行 2、安装密钥 slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX 3、设置kms服务器 slmgr /skms zh.us.to 4、查看是否激活 slmgr /ato 转载于:https://www.cnblogs.com/Edward-Yue/p/10942884.html

电脑显示未激活Windows的解决办法

今天遇到一个问题&#xff0c;桌面显示要我激活windows&#xff0c;如下图&#xff1a; 那么接下来就分享一下我的解决办法&#xff1a; 一、鼠标右击桌面左下角windows 键&#xff0c;选择Windows PowerShell&#xff08;管理员&#xff09;&#xff0c;会出现如下页面&#x…

Windows server 2022安装与激活

1.下载 百度网盘下载 链接&#xff1a;https://pan.baidu.com/s/18c5smZPzbk0ClhEYh4LQ2w 提取码&#xff1a;w7i8 2.安装 最近版本新出的镜像官方的 EFI 文件在虚拟机上部署有问题&#xff0c;如发现不能在虚拟机内使用&#xff0c;切换虚拟机配置为 BIOS&#xff0c;而非…

查看已激活Windows的密钥

今天工作之余&#xff0c;过个快乐的周末心情很是不错&#xff0c;然后打开电脑&#xff0c;闲暇之余&#xff0c;突然想到了window密钥的问题&#xff0c;然后就写个文章记录一下Windows如何在命令行查看密钥&#xff01; 方法一&#xff1a;DOS命令查看&#xff1a;如果你是…

Linux内核日志打印时间开关

echo Y > /sys/module/printk/parameters/time //打开内核日志打印时间 echo N > /sys/module/printk/parameters/time //关闭内核日志打印时间 cat /sys/module/printk/parameters/time //查看内核日志打印时间开关状态 static bool printk_time IS_ENABLED(CONFIG…

在 Windows 10 中如何查看系统的激活状态?

查看激活方法 方法一方法二方法三 升级到 Windows 10 或重新安装 Windows 10 后&#xff0c;可能需要检查 Windows 10 安装是否已激活&#xff0c;那么可以通过以下方法来实现&#xff1a; 方法一 开始按钮->设置&#xff08;快捷键 Windows I&#xff09; 点击“更新和…

win 10 系统激活

win10企业版永久激活方法?win10企业版是针对企业用户推出的版本&#xff0c;随着win10系统的不断完善&#xff0c;现在越来越多的人选择升级win10&#xff0c;升级完系统就需要激活它。那么今天就为大家分享一下怎么永久激活win10企业版。 1、右键点击桌面左下角"windows…

激活windows

激活windows 本来一直觉得office不激活也不影响使用&#xff0c;直到最近写报告才发现影响真是很大&#xff0c;搜了好多激活码基本都不可用。直到在某个网站上看到的一个非常简单的一个方式&#xff0c;话不多说了&#xff0c;直接开始。 第一步&#xff1a;下载安装激活工具…

细说Windows系统主流激活的原理与弊端!

Windows系统有必要激活吗&#xff1f; 答案是“有必要”。虽然微软已经放开了系统&#xff0c;不再抓着版权不放&#xff0c;而且可以通过“自建验证服务器”的方式可以自行激活盗版系统&#xff0c;但相较于已经激活的正版系统而言&#xff0c;正版系统提供的功能更齐全&#…

赛效:广告文案自动生成器有哪些

1&#xff1a;在电脑浏览器上打开即时工具&#xff0c;登录自己的账号后&#xff0c;在“智能文本”菜单里点击“广告文案”。 2&#xff1a;在输入框里输入产品类型、产品特性&#xff0c;然后点击下方“生成”。 3&#xff1a;生成广告文案后&#xff0c;点击文案右上角的复制…

JavaSE进阶(day12,复习自用)

网络编程&#xff08;通信&#xff09; 网络通信三要素三要素概述、要素一&#xff1a;IP地址IP地址操作类-InetAddress要素二&#xff1a;端口号要素三&#xff1a;协议 UDP通信-快速入门UDP通信-广播、组播TCP通信-快速入门编写客户端代码编写服务端代码、原理分析 TCP通信-多…

运维小白必学篇之基础篇第十四集:DHCP中继实验

DHCP中继实验 目录 服务器端&#xff1a;&#xff08;vmware5&#xff09; 中继器端&#xff1a;(双网卡ens33、vmware5&#xff1b;ens36、vmware6&#xff09; 客户端&#xff1a;&#xff08;vmware6&#xff09; 实验作业&#xff08;主机名为自己的名字&#xff09;&a…

Bert+FGSM中文文本分类

我上一篇博客已经分别用BertFGSM和BertPGD实现了中文文本分类&#xff0c;这篇文章与我上一篇文章BertFGSM/PGD实现中文文本分类&#xff08;Loss0.5L10.5L2)_Dr.sky_的博客-CSDN博客的不同之处在于主要在对抗训练函数和embedding添加扰动部分、模型定义部分、Loss函数传到部分…

ROS:tf坐标系广播与监听的编程实现

目录 一、创建功能包二、创建代码并编译运行&#xff08;C&#xff09;2.1创建代码2.2编译2.3运行 一、创建功能包 创建的 learning_tf 包来进行代码存放和编译 cd ~/catkin_ws/src catkin_create_pkg learning_tf roscpp rospy tf turtlesim二、创建代码并编译运行&#xff…

视频裁剪

从一段较长的视频中裁剪某一段(时间自己定)&#xff0c;如图 结合api com.github.yangjie10930:EpMedia:v1.0.1 视频裁剪框架 可以实现可视化视频裁剪。 说不多说上源码&#xff1a;https://gitee.com/kbld/video-edit 视频压缩的可以看看https://blog.csdn.net/qq_35198779…

Android 视频裁剪自定义 View

PlaySeekbar - Github Android 视频裁剪自定义 View - 裁减播放的视频&#xff08;本地视频&#xff09; 功能需求与预览 有个视频裁剪功能&#xff0c;需要自定义 View 具体如下 裁剪选择区域模块&#xff0c;可以自定义最少裁剪时间 当选择低于最少裁剪时间时&#xff0c;…

海外网红营销必备:品牌与海外红人合作的谈判技巧指南

随着社交媒体的飞速发展&#xff0c;海外网红已经成为品牌营销的热门选择。与知名红人合作&#xff0c;可以有效地扩大品牌影响力、提升产品认知度&#xff0c;并吸引目标受众。然而&#xff0c;与红人的谈判过程常常充满挑战&#xff0c;需要品牌营销人员具备一定的技巧和策略…

linux裁剪视频教程,适用于Linux桌面的超简单实用的视频裁剪应用

原标题&#xff1a;适用于Linux桌面的超简单实用的视频裁剪应用 来自&#xff1a;Linux迷 https://www.linuxmi.com/video-trimmer-linux.html 您可能已经知道一些适用于Linux 的最佳免费视频编辑器&#xff0c;但并不是每个人都需要那些提供的所有功能。 有时&#xff0c;您只…

Opencv 把视频裁剪成指定帧率的图像集

目的&#xff1a; 视频 FPS30&#xff0c;需要把视频裁剪成 FPS3 的图像集&#xff0c;即两分钟的视频裁剪出360张图像。 FPS&#xff1a; 每秒传输帧数(Frames Per Second)FPS 也可以理解为我们常说的“刷新率&#xff08;单位为Hz&#xff09;”&#xff0c;例如我们常在游戏…

android中slider控件,VideoRangeSlider视频裁剪控件

最近项目中需要用到裁剪视频操作的控件,本着不要重复造轮子的精神,在Github上找了个遍都没有发现有可用的。那就只好自己动手做了。目前已经开源到Github,欢迎Start,issue。 基本用法引入依赖repositories {maven { url "https://jitpack.io"} } dependencies {c…