java之WIFI模块实现文件传输(开源)

news2024/11/16 13:26:23

AndroidManifest这里要获取到权限,所以要导入:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

主界面:

public class MainActivity extends AppCompatActivity {

    private Button startBtton, stopButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //super的意思是继承父类
       super.onCreate(savedInstanceState);
       //初始化xml组件
       setContentView(R.layout.activity_main);
       //初始化按钮组件
       startBtton=findViewById(R.id.bth_start);
       stopButton=findViewById(R.id.bth_stop);

       //当按钮按下去时候的监听器然后进行跳转到别的界面
        startBtton.setOnClickListener(v->startActivity(new Intent(MainActivity.this ,ServerActivity.class)));

        stopButton.setOnClickListener(view ->startActivity(new Intent(MainActivity.this,ClientActivity.class)) );
    }
}

服务器端:

public class ServerActivity extends AppCompatActivity {
    private static final String TAG="ServerActivity";
    //mRegistrationListener: 监听NSD服务注册状态的回调接口。
    private NsdManager mNsdManager=null;
    private  NsdManager.RegistrationListener mRegistrationListener;
    //CHAT_PORT: 定义了用于通信的端口号。
    private  final int CHAT_PORT=6613;
    //udpListenerThread: 用于UDP监听的线程。
    private Thread udpListenerThread;
    //running: 用于控制UDP监听线程是否运行的标志。
    private boolean running = false;
    //packet: 用于接收UDP数据包的对象。
    private DatagramPacket packet;
    //BUFFER_SIZE: 定义了缓冲区的大小。
    private final int BUFFER_SIZE = 1024*6;
    private byte[] buffer = new byte[BUFFER_SIZE];
    //serverTV 和 msgTV: 分别是用于显示服务器状态和接收到的消息的TextView控件。
    private TextView serverTV, msgTV;

    //构造方法: 一个空的构造方法。
    public ServerActivity() {
    }


    @SuppressLint("MissingInflatedId")
    @Override
    //onCreate: 活动创建时调用的方法,用于初始化界面和设置NSD服务。
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_server);
        serverTV = findViewById(R.id.tv_server_state);
        msgTV = findViewById(R.id.tv_msg_receive);

        //设置mRegistrationListener的回调方法。
        mRegistrationListener=new NsdManager.RegistrationListener() {
            @SuppressLint("SetTextI18n")
            @Override
            //获取NSD服务管理器,创建NsdServiceInfo对象并注册服务。
            //当服务注册失败时调用。参数serviceInfo包含有关尝试注册的服务的信息,
            // errorCode提供了失败的原因。这里通过调用Log.i记录信息,并使用runOnUiThread更新UI,显示"nsd服务:注册失败"。
            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
                Log.i(TAG,"onRegistrationFailed ");
                runOnUiThread(() -> serverTV.setText("nsd服务:注册失败"));
            }
                @SuppressLint("SetTextI18n")
                @Override
                // 当服务注销失败时调用。参数含义与上一个方法相同。这里更新UI显示"nsd服务:取消注册失败"。
                public void onUnregistrationFailed (NsdServiceInfo nsdServiceInfo,int i){
                    Log.i(TAG, "onUnregistrationFailed ");
                    runOnUiThread(() -> serverTV.setText("nsd服务:取消注册失败"));
                }
                @SuppressLint("SetTextI18n")
                @Override
                // 当服务成功注册时调用。参数serviceInfo包含已注册服务的详细信息。这里更新UI显示"nsd服务:注册成功"。
                public void onServiceRegistered (NsdServiceInfo nsdServiceInfo){
                    Log.i(TAG, "onServiceRegistered ");
                    runOnUiThread(() -> serverTV.setText("nsd服务:注册成功"));
                }
                @SuppressLint("SetTextI18n")
                @Override
                //当服务成功注销时调用。参数含义与注册成功时相同。这里更新UI显示"nsd服务:取消注册成功"。
                public void onServiceUnregistered (NsdServiceInfo nsdServiceInfo){
                    Log.i(TAG, "onServiceUnregistered ");
                    runOnUiThread(() -> serverTV.setText("nsd服务:取消注册成功"));
                }
            };




        //这行代码通过调用getSystemService方法获取系统服务NSD_SERVICE,即Network Service
        mNsdManager = (NsdManager) getSystemService(NSD_SERVICE);
        //创建了一个NsdServiceInfo对象,这个对象用于存储关于要注册的服务的信息
        NsdServiceInfo serviceInfo = new NsdServiceInfo();
        //设置服务的名称为"test"。这个名称将用于客户端搜索服务时的标识。
        serviceInfo.setServiceName("test");
        //设置服务监听的端口号。CHAT_PORT应该是一个定义好的端口常量,用于聊天服务。
        serviceInfo.setPort(CHAT_PORT);
        //客户端发现服务器是需要对应的这个Type字符串 ;_http._tcp.
        serviceInfo.setServiceType("_saixiang._tcp.");
        //客户端发现服务器是需要对应的这个Type字符串 ;_http._tcp.
        //使用NsdManager的registerService方法注册服务。第一个参数是之前创建的serviceInfo对象,
        // 第二个参数指定使用的协议为DNS-SD,第三个参数是一个监听器mRegistrationListener,用于接收服务注册过程中的状态更新。
        mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
        //这行代码被注释掉了,如果取消注释,它将启动一个UDP监听器。UDP是一种无连接的网络协议,常用于需要快速传输但可以容忍一些数据丢失的场景。
        //startUdpListener();
        //这行代码调用了一个名为startListen的方法,这个方法的具体实现没有给出,但它的目的可能是启动一个监听器来处理网络请求。
        startListen();
    }





    private boolean ifListen=true;
    private ServerSocket serverSocket = null;
    private Socket socket = null;
    boolean ifSocketThreadStart = false;

    /*开始监听
   * */
   //线程定义: socketThread是一个内部线程类,用于处理TCP连接和数据接收。
    private final Thread socketThread = new Thread() {
        //这是线程的run方法,当线程启动时候会执行这个方法
        public void run() {
            //无限循环,表示线程会一直运行直到程序终止
            while (true) {
                try {
                    //这个条件判断如果serverSocket是null并且ifListen为true,则执行大括号里的代码
                    if (serverSocket == null && ifListen) {
                        //定义了一个端口为6613的变量
                        int socket_port = 6613;
                        //创建一个新的serverSocket对象,监听6613端口
                        serverSocket = new ServerSocket(socket_port);
                        //如果serverSocket不是null,则执行大括号里的代码
                    } else if (serverSocket != null) {
                        //调用Accept方法等待客户端连接,并将连接的Socket对象赋值给变量socket
                        socket = serverSocket.accept();
                        if (socket != null) {
                            //创建一个包装了socket输入流的BufferedInputStream,再包装成DataInputStream,用于高效读取数据。
                            DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
                            try {

                                //定义了一个大小为1024的字节数组,用作数据缓冲区
                                byte[] buffer = new byte[1024];
                                int len = 0;
                                //这是一个循环,当从DataInputStream读取到数据(len不为-1)时候,执行大括号里的代码
                                while ((len = in.read(buffer)) != -1) {
                                    //使用读取到的数据和"GB2312"编码创建一个字符串。
                                    String text = new String(buffer, 0, len, "GB2312");
                                    //打印日志,记录接收到的数据。
                                    Log.d("test", "收到的数据为:" + text);
                                }
                               // 捕获并处理DataInputStream读取过程中可能发生的异常。
                            } catch (Exception e) {
                                Log.d("test", "DataService read: " + e);
                                //调用一个自定义的方法来销毁socket,可能是关闭连接。
                                destroySocket();
                            }
                        }
                    }
                    //捕获并处理ServerSocket创建或accept方法调用过程中可能发生的异常。
                } catch (IOException e1) {
                    Log.d("test", "DataService accept: " + e1);
                    destroySocket(); }
            }
        }
    };

    //startListen 用于启动
    public void startListen() {
        ifListen = true;
        if (!ifSocketThreadStart) {
            ifSocketThreadStart = true;
            socketThread.start();
        }
    }
    //停止TCP监听stopListen:
    public void stopListen() {
        ifListen = false;
        destroySocket();
    }
    //用于关闭和重置ServerSocket和Socket。
    private void destroySocket() {
        //开始一个 try 块,用于捕获并处理可能发生的异常。
        try {
            //检查 serverSocket 是否不为 null 且没有被关闭。
            if (serverSocket != null && !serverSocket.isClosed()) {
                //如果条件满足,调用 close 方法关闭 serverSocket。
                serverSocket.close();
            }
            //如果关闭 serverSocket 时发生 IOException,将进入这个 catch 块。
        } catch (IOException e) {
//            AppLog.Log(e.toString());
        }
        //无论是否发生异常,都会执行 finally 块中的代码。
        finally {
          //将 serverSocket 设置为 null,以确保它不再被使用。
            serverSocket = null;
        }
        //开始另一个 try 块,用于关闭另一个套接字 socket。
        try {
            //检查 socket 是否不为 null 且没有被关闭。
            if (socket != null && !socket.isClosed()) {
                //如果条件满足,调用 close 方法关闭 socket。
                socket.close();
            }
        }//如果关闭 socket 时发生 IOException,将进入这个 catch 块。
        catch (IOException e) {
//            AppLog.Log(e.toString());
        }
        //无论是否发生异常,都会执行 finally 块中的代码。
        finally {
            //将 socket 设置为 null,以确保它不再被使用。
            socket = null;
        }
    }


    @Override
    //onDestroy: 活动销毁时调用的方法,用于注销NSD服务和停止监听。
    protected void onDestroy() {
        //这是调用父类(即Activity类)的onDestroy()方法,以确保父类中的资源得到正确释放。
        super.onDestroy();
        //: 这个方法用于停止NSD服务。NSD服务允许应用程序在本地网络中注册和发现服务。
         stopNSDServer();
//       stopUdpListener();
         destroySocket();
         stopListen();
    }
    //NSD服务注册与注销: 通过mNsdManager注册和注销服务,以便其他设备可以通过NSD发现此服务
    public void stopNSDServer() {
        // mRegistrationListener作为参数传递,这样当服务取消注册时,监听器会收到相应的回调。
        mNsdManager.unregisterService(mRegistrationListener);
    }
}

截取了soket应该怎么接收和建立传输数据.

客户端:

//ClientActivity 继承自 AppCompatActivity表明它是一个可以处理配置更改(如屏幕旋转)的活动。
public class ClientActivity extends AppCompatActivity {
    private static final String TAG = "ClientActivity";
    private RecyclerView recyclerView;
    private NsdManager mNsdManager = null;
    //mNsdManager: 用于网络服务发现的 NsdManager 实例。
    private NsdManager.DiscoveryListener mNSDDiscoveryListener = null;    //    搜寻监听器
    private NsdManager.ResolveListener mNSDResolveListener = null;//    解析监听器
    private NSDDeviceAdapter adapter;
    private TextView serverTV;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置了活动的布局
        setContentView(R.layout.activity_client);
        serverTV=findViewById(R.id.tv_server_state_s);
        //获取了布局中RecyclerView组件
        recyclerView = findViewById(R.id.recyclerView);
        //为RecyclerView设置了线性布局管理器
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //创建了一个适配器,用于管理RecyclerView中显示的数据
        adapter = new NSDDeviceAdapter();
        //将适配器设置到recyclerView上
        recyclerView.setAdapter(adapter);
        //服务发现监听器 (mNSDDiscoveryListener):定义了多个回调方法,用于处理服务发现过程中的不同事件。
        mNSDDiscoveryListener = new NsdManager.DiscoveryListener() {
            @Override
            //在开始服务时调用。
            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                Log.i(TAG,"onStartDiscoveryFailed ");
            }
            // 停止服务发现失败时调用
            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                //使用 Log.i(TAG, message) 记录信息,其中 message 是要记录的消息
                Log.i(TAG,"onStopDiscoveryFailed ");

            }
           //分别在服务发现开始时调用。
            @Override
            public void onDiscoveryStarted(String serviceType) {
                Log.i(TAG,"onDiscoveryStarted ");

            }
            //分别在服务发现停止时调用。
            @Override
            public void onDiscoveryStopped(String serviceType) {
                Log.i(TAG,"onDiscoveryStopped ");

            }
           //当发现新服务时调用,并使用 mNSDResolveListener 解析服务信息。
            @Override
            public void onServiceFound(NsdServiceInfo serviceInfo) {
                Log.i(TAG,"onServiceFound "+serviceInfo.toString());
                mNsdManager.resolveService(serviceInfo, mNSDResolveListener);
            }
            //当服务不再可用时调用,并从适配器中移除该服务。
            @Override
            public void onServiceLost(final NsdServiceInfo serviceInfo) {
                Log.i(TAG,"onServiceLost ");
                //使用 runOnUiThread(Runnable) 确保在主线程上更新UI,这是Android中更新UI的标准做法
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        adapter.removeDevice(serviceInfo);
                    }
                });
            }
        };

       //用于监听服务解析的结果。
        mNSDResolveListener = new NsdManager.ResolveListener() {
            @Override
            //onResolveFailed: 在服务解析失败时调用。
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                Log.i(TAG,"onResolveFailed ");

            }

            @Override
            //onServiceResolved: 在服务解析成功时调用,并更新适配器以添加服务信息
            public void onServiceResolved(final NsdServiceInfo serviceInfo) {
                Log.i(TAG,"onServiceResolved ");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        adapter.addDevice(serviceInfo);
                    }
                });
            }
        };
        //使用 mNsdManager方法开始服务发现,指定服务类型 _saixiang._tcp.
        mNsdManager = (NsdManager) getSystemService(NSD_SERVICE);
        //使用discoverServices 方法开始服务发现,使用的协议 NsdManager.PROTOCOL_DNS_SD。
        mNsdManager.discoverServices("_saixiang._tcp.", NsdManager.PROTOCOL_DNS_SD, mNSDDiscoveryListener);

        // 客户端在服务解析成功后,尝试与服务器建立连接
        mNSDResolveListener = new NsdManager.ResolveListener() {
            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                // 处理解析失败的情况
                Log.i(TAG,"onResolveFailed ");
            }

            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo) {
                // 服务解析成功,尝试建立连接
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 创建Socket连接
                            Socket socket = new Socket(serviceInfo.getHost(), serviceInfo.getPort());
                            // 发送数据
                            OutputStream out = socket.getOutputStream();
                            out.write("Hello Server!".getBytes());
                            out.flush();
                            // 接收数据
                            InputStream in = socket.getInputStream();
                            byte[] buffer = new byte[1024];
                            int len = in.read(buffer);
                            String received = new String(buffer, 0, len);
                            Log.i(TAG, "Received: " + received);

                            // 关闭连接
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        };
    }

    @Override
    //在活动销毁时停止服务发现,避免资源泄露。
    protected void onDestroy() {
        super.onDestroy();
        mNsdManager.stopServiceDiscovery(mNSDDiscoveryListener);
    }

}

也是建立了socket来建立数据传输.

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

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

相关文章

22 - grace数据处理 - 补充 - 泄露误差改正 - Slepian局部谱分析法(二) - Slepian谱分析程序包初始化

22 - grace数据处理 - 补充 - 泄露误差改正 - Slepian局部谱分析法 - Slepian谱分析程序包初始化 0 引言1 slepian程序包配置过程1.1 获取环境配置安装包1.2 执行demo测试是否配置成功2 结语0 引言 上篇提到进行slepian谱分析可以使用美国普林斯顿大学Frederik Simons教授提供的…

Google Chrome 应用商店插件离线导出导入方法(亲测有效)

Google Chrome 浏览器插件&#xff08;也称为扩展程序&#xff09;是一种可以增强浏览器功能的小型软件程序。这些插件可以让用户在浏览器中添加新的功能、定制化界面、自动化任务等。以下是一些常见的 Google Chrome 浏览器插件功能&#xff1a; 功能增强&#xff1a;插件可以…

使用 Pytorch 从头开始​​构建 Transformer

目录 一、说明 二、输入嵌入 2.1 __init__()方法目的 2.2 super() 三、PositionalEncoding 类 四、位置编码的工作原理 4.1 总体过程 4.2 数学公式 五、LayerNormalization 类 5.1 过程描述 5.2 例子 六、FeedForwardBlock 类 6.1 总体描述 6.2 数学公式 七、MultiHeadAttentio…

全球清真食品配料市场规划预测:未来六年CAGR为3.4%

随着全球穆斯林人口的增长和消费能力的提升&#xff0c;清真食品配料作为符合伊斯兰教义的食品添加剂和成分&#xff0c;正逐渐受到更多消费者的青睐。本文旨在通过深度分析清真食品配料行业的各个维度&#xff0c;揭示行业发展趋势和潜在机会。 【市场趋势的演变】 1. 市场规…

AI 生成搞笑段子

段子在我们生活中扮演着极为重要的角色&#xff0c;它不仅能够带给我们欢乐和娱乐&#xff0c;还能够促进交流和拉近人与人之间的距离。通过幽默诙谐的段子&#xff0c;我们可以轻松地化解尴尬和紧张的气氛&#xff0c;让沉闷的场合变得活泼有趣。 而段子手生成器&#xff0c;则…

Flink-DataWorks第一部分:DataWorks(第57天)

系列文章目录 1.1 什么是DataWorks 1.2 功能特性 1.2.1 数据集成&#xff1a;全领域数据汇聚 1.2.3 数据建模&#xff1a;智能数据建模 1.2.4 数据分析&#xff1a;即时快速分析 1.2.5 数据质量&#xff1a;全流程的质量监控 1.2.6 数据地图&#xff1a;统一管理&#xff0c;跟…

数据跨境流动需要注意什么?怎么实现安全合规的跨境传输?

2024年3月22日&#xff0c;《促进和规范数据跨境流动规定》&#xff08;以下简称《数据跨境规定》&#xff09;正式公布并施行。数据跨境流通涉及到隐私保护、安全性和法律合规等多个方面的重要考虑因素。 具体来说&#xff0c;需要注意以下几点&#xff1a; 1、隐私保护&…

农场游戏中的时间管理实例

一、准备工作 在Unity中创建承载日期和时间的文本 二、设置游戏的时间戳 using System.Collections; using System.Collections.Generic; using UnityEngine; //标识这个类可以被序列化 [System.Serializable] public class GameTimestamp {// 游戏时间戳的成员变量public in…

【第三版 系统集成项目管理工程师】第10章 启动过程组

持续更新。。。。。。。。。。。。。。。 【第三版】第十章 启动过程组 10.1 制定项目章程10.1.1 主要输入1.立项管理文件-P3562.协议-P35710.1.2 主要输出1.项目章程-P3572.假设日志-P358练习10.2 识别干系人10.2.1 主要输入1.项目管理计划-P3602.项目文件-P36010.2.2 主要工…

49 mysql 子查询 加 group by 产生的奇怪现象

前言 这里要提到的是一个 之前碰到的一个 很令人诧异的查询, 主要是 和 group 查询有关系 查询如下, 按照常规理解, “select id from t_user_02 where name jerry group by age ” 会返回 两条数据, 然后 整个查询 会查询出两条数据 但是 结果很令人差异, 查询出了 四条…

华为云全域Serverless技术创新:全球首创通用Serverless平台被ACM SIGCOMM录用

华为开发者大会2024&#xff08;HDC 2024&#xff09;在东莞松山湖圆满结束&#xff0c;期间华为云主办的“全域Serverless时代&#xff1a;技术创新引领&#xff0c;赋能行业实践”专题论坛&#xff0c;向广大开发者传递了Serverless领域的前沿思考和实践&#xff0c;现场座无…

CVE-2023-33440详解

一.访问url http://eci-2zef9bcht3lq36hkwyoh.cloudeci1.ichunqiu.com/ 二.目录扫描 http://eci-2zef9bcht3lq36hkwyoh.cloudeci1.ichunqiu.com/ 三.拼接访问/login.php 四.抓包构造数据包 发给repeter 复制过去这几个位置都有空格&#xff0c;要删除掉&#xff0c;Referer和…

基于单片机的空调红外遥控器设计

【摘要】 本文基于单片机AT89C51、利用红外遥控发射技术设计了一款空调红外遥控器。对其系统结构框架、硬件部分等内容进行介绍&#xff0c;最后通过系统仿真验证设计的正确性和有效性。 【关键词】 遥控技术&#xff1b;单片机&#xff1b;红外 1.引言 远程控制技术指的是对…

DC系列靶场---DC 5靶场的渗透测试

DC-5渗透测试 信息收集 地址探测 使用arp-scan对目标主机进行地址探测 arp-scan -l -I eth0 目标主机IP地址为172.30.1.132 Nmap扫描 使用Nmap对目标主机进行端口扫描 nmap -sS -sV -T4 -p- -O 172.30.1.132//-sS Nmap默认扫描类型&#xff0c;SYS的秘密扫描//-sV 服务…

可用性测试:提升用户体验的关键

目录 前言1. 可用性测试的概念1.1 可用性测试的特点1.2 可用性测试的类型 2. 可用性测试的主要作用2.1 发现用户需求2.2 识别可用性问题2.3 提高用户满意度 3. 可用性测试在整个测试过程中的地位3.1 可用性测试与功能测试的关系3.2 可用性测试与性能测试的关系3.3 可用性测试与…

Java | Leetcode Java题解之第326题3的幂

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isPowerOfThree(int n) {return n > 0 && 1162261467 % n 0;} }

鸿蒙(API 12 Beta2版)NDK开发【HarmonyOS ABI】硬件兼容性

HarmonyOS系统支持丰富的设备形态&#xff0c;支持多种架构指令集&#xff0c;支持多种操作系统内核&#xff1b;为了应用在各种HarmonyOS设备上的兼容性&#xff0c;本文定义了"OHOS" ABI&#xff08;Application Binary Interface&#xff09;的基础标准&#xff0…

《Milvus Cloud向量数据库指南》——高可用黄金标准:深入解析与业务策略考量

高可用黄金标准:深入解析与业务策略考量 在信息技术飞速发展的今天,高可用性(High Availability, HA)已成为衡量企业IT系统性能与稳定性的关键指标之一。它不仅仅关乎技术层面的优化与配置,更是企业保障业务连续性、提升客户体验、增强市场竞争力的重要基石。尽管高可用性…

基于Java中的SSM框架实现在线音乐网站系统项目【项目源码+论文说明】

基于Java中的SSM框架实现在线音乐网站系统演示 摘要 本文讲述了使用JSP语言及HTML5语言及MySql数据库技术开发的音乐网站的设计与实现。本文所讲的JSP音乐系统是通过所学的知识创办一个类似于QQ音乐或者酷狗音乐性质的网站平台&#xff0c;使所有对国内外音乐欣赏感兴趣的人都…

未授权访问漏洞合集

今天我们来开一个新的坑&#xff0c;未授权访问漏洞&#xff0c;以后我会慢慢更新&#xff0c;大家可以持续跟进一下&#xff0c;谢谢大家&#xff01; 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷&#xff0c;导致其他用户可以直接访问&#xff0c;从…