Qt/C++ 调用迅雷开放下载引擎(ThunderOpenSDK)下载数据资源

目录导读

    • 前言
    • ThunderOpenSDK 简介
      • 参考 xiaomi_Thunder_Cloud 示例
      • ThunderOpenSDK 下载问题

前言

在对以前老版本的exe执行程序进行研究学习的时候,发现以前的软件是使用的ThunderOpenSDK这个迅雷开放下载引擎进行的项目数据下载,于是在网上搜索一番找到了相关内容,但是不知道为什么了相关资料相当少,不过用是真的好用,于是仔细的研究了一下。


ThunderOpenSDK 简介

ThunderOpenSDK 是一个迅雷开放下载引擎的 SDK,允许开发者在自己的应用程序中集成迅雷的下载功能。该 SDK 提供了丰富的接口,支持多种下载任务的管理,包括任务的创建、启动、停止、删除等操作。此外,SDK 还支持设置下载速度限制、代理、用户代理等功能,以满足不同应用场景的需求。
出自:ThunderOpenSDK 使用教程
相关内容参考:

  1. 迅雷开放下载引擎(ThunderOpenSDK)使用指南

  2. ThunderOpenSDK 使用教程

  3. 配置云平台ip和端口 云平台接口

  4. GitHub: ThunderOpenSDK

ThunderOpenSDK 不需要再进行编译,直接附加到项目中就能直接使用,甚至示例程序都写好了,只管调用。
GitHub示例中有0.CurUseCommonLib360Jisu_Thunder_Cloudliebao_Thunder_Cloudxiaomi_Thunder_CloudXunleiDownload_Old 5个版本的示例,
可以根据需求任选一个
在这里插入图片描述
通过查看xldl.dll文件的属性信息和Github上的声明,
我都毫不怀疑这些库文件是不是是从某个软件上扒下来的。

参考 xiaomi_Thunder_Cloud 示例

xiaomi_Thunder_Cloud 迅雷云加速开发平台版本示例;
在这里插入图片描述
打开xldl.h文件可以发现xldl.dll的接口和数据结构都已经声明好还有注释,只管调用:

  • xldl.h:
#pragma once

// 所有结构体定义按1字节对齐
#pragma pack(push, 1)
struct DownTaskParam
{
	DownTaskParam()
	{
		memset(this, 0, sizeof(DownTaskParam));
		nReserved1		 = 5;
		bReserved			 = FALSE;
		DisableAutoRename	 = FALSE;
		IsOnlyOriginal		 = FALSE;
		IsResume			 = TRUE;
	}
    int nReserved;
	wchar_t szTaskUrl[2084];          // 任务URL
	wchar_t szRefUrl[2084];           // 引用页
	wchar_t szCookies[4096];          // 浏览器cookie
	wchar_t szFilename[MAX_PATH];     // 下载保存文件名.
	wchar_t szReserved0[MAX_PATH];
	wchar_t szSavePath[MAX_PATH];     // 文件保存目录
	HWND  hReserved;
	BOOL bReserved; 
	wchar_t szReserved1[64];
	wchar_t szReserved2[64];
	BOOL IsOnlyOriginal;            // 是否只从原始地址下载
	UINT nReserved1;
	BOOL DisableAutoRename;         // 禁止智能命名
	BOOL IsResume;                  // 是否用续传
	DWORD reserved[2048];
};
enum  DOWN_TASK_STATUS
{
	NOITEM = 0,
	TSC_ERROR,
	TSC_PAUSE,
	TSC_DOWNLOAD,
	TSC_COMPLETE,
	TSC_STARTPENDING,
	TSC_STOPPENDING
};
enum TASK_ERROR_TYPE
{
	TASK_ERROR_UNKNOWN	   =			0x00,   // 未知错误
	TASK_ERROR_DISK_CREATE =			0x01,   // 创建文件失败
	TASK_ERROR_DISK_WRITE =				0x02,   // 写文件失败
	TASK_ERROR_DISK_READ =				0x03,   // 读文件失败
	TASK_ERROR_DISK_RENAME =			0x04,   // 重命名失败
	TASK_ERROR_DISK_PIECEHASH =			0x05,   // 文件片校验失败
	TASK_ERROR_DISK_FILEHASH =			0x06,   // 文件全文校验失败
	TASK_ERROR_DISK_DELETE =			0x07,   // 删除文件失败失败
	TASK_ERROR_DOWN_INVALID =			0x10,   // 无效的DOWN地址
	TASK_ERROR_PROXY_AUTH_TYPE_UNKOWN = 0x20,   // 代理类型未知
	TASK_ERROR_PROXY_AUTH_TYPE_FAILED = 0x21,   // 代理认证失败
	TASK_ERROR_HTTPMGR_NOT_IP =			0x30,   // http下载中无ip可用
	TASK_ERROR_TIMEOUT =				0x40,   // 任务超时
	TASK_ERROR_CANCEL =					0x41,   // 任务取消
    TASK_ERROR_TP_CRASHED=              0x42,   // MINITP崩溃
    TASK_ERROR_ID_INVALID =             0x43,   // TaskId 非法
};
struct DownTaskInfo
{
	DownTaskInfo()
	{
		memset(this, 0, sizeof(DownTaskInfo));
		stat		= TSC_PAUSE;
		fail_code	= TASK_ERROR_UNKNOWN;
		fPercent = 0;
		bIsOriginUsable = false;
		fHashPercent = 0;
	}
	DOWN_TASK_STATUS	stat;
	TASK_ERROR_TYPE		fail_code;
	wchar_t		szFilename[MAX_PATH];
	wchar_t		szReserved0[MAX_PATH];
	__int64     nTotalSize;         // 该任务总大小(字节)
	__int64     nTotalDownload;     // 下载有效字节数(可能存在回退的情况)
	float		fPercent;           // 下载进度
	int			nReserved0;
	int			nSrcTotal;          // 总资源数
	int			nSrcUsing;          // 可用资源数
	int			nReserved1;
	int			nReserved2;
	int			nReserved3;
	int			nReserved4;
	__int64     nReserved5;
	__int64		nDonationP2P;       // p2p贡献字节数
	__int64		nReserved6;
	__int64		nDonationOrgin;		// 原始资源共享字节数
	__int64		nDonationP2S;		// 镜像资源共享字节数
	__int64		nReserved7;
	__int64     nReserved8;
	int			nSpeed;             // 即时速度(字节/秒)
	int			nSpeedP2S;          // 即时速度(字节/秒)
	int			nSpeedP2P;          // 即时速度(字节/秒)
	bool		bIsOriginUsable;    // 原始资源是否有效
	float		fHashPercent;       // 现不提供该值
	int			IsCreatingFile;     // 是否正在创建文件
	DWORD		reserved[64];
};
enum DOWN_PROXY_TYPE
{
	PROXY_TYPE_IE	 = 0,
	PROXY_TYPE_HTTP  = 1,
	PROXY_TYPE_SOCK4 = 2,
	PROXY_TYPE_SOCK5 = 3,
	PROXY_TYPE_FTP   = 4,
	PROXY_TYPE_UNKOWN  = 255,
};
enum DOWN_PROXY_AUTH_TYPE
{
	PROXY_AUTH_NONE =0,
	PROXY_AUTH_AUTO,
	PROXY_AUTH_BASE64,
	PROXY_AUTH_NTLM,
	PROXY_AUTH_DEGEST,
	PROXY_AUTH_UNKOWN,
};
struct DOWN_PROXY_INFO
{
	BOOL		bIEProxy;
	BOOL		bProxy;
	DOWN_PROXY_TYPE	stPType;
	DOWN_PROXY_AUTH_TYPE	stAType;
	wchar_t		szHost[2048];
	INT32		nPort;
	wchar_t		szUser[50];
	wchar_t		szPwd[50];
	wchar_t		szDomain[2048];
};
struct WSAPROTOCOL_INFOW;

#pragma pack(pop)

namespace DownEngine
{
    extern "C" __declspec(dllimport) BOOL   XL_Init(void);
    extern "C" __declspec(dllimport) BOOL   XL_UnInit(void);
	extern "C" __declspec(dllimport) HANDLE XL_CreateTask(DownTaskParam &stParam);
	extern "C" __declspec(dllimport) BOOL   XL_DeleteTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_StartTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_StopTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_ForceStopTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_QueryTaskInfo(HANDLE hTask, DownTaskInfo & stTaskInfo); //旧版接口,使用Ex接口替换
	extern "C" __declspec(dllimport) BOOL   XL_QueryTaskInfoEx(HANDLE hTask, DownTaskInfo & stTaskInfo);
	extern "C" __declspec(dllimport) BOOL	XL_DelTempFile(DownTaskParam &stParam);
	extern "C" __declspec(dllimport) void	XL_SetSpeedLimit(INT32 nKBps);
	extern "C" __declspec(dllimport) void	XL_SetUploadSpeedLimit(INT32 nTcpKBps,INT32 nOtherKBps);
	extern "C" __declspec(dllimport) BOOL	XL_SetProxy(DOWN_PROXY_INFO &stProxyInfo);
	extern "C" __declspec(dllimport) void   XL_SetUserAgent(const wchar_t *pszUserAgent);
	extern "C" __declspec(dllimport) BOOL   XL_ParseThunderPrivateUrl(const wchar_t *pszThunderUrl, wchar_t *normalUrlBuffer, INT32 bufferLen);
	extern "C" __declspec(dllimport) BOOL   XL_GetFileSizeWithUrl(const wchar_t * lpURL, INT64& iFileSize);
    extern "C" __declspec(dllimport) BOOL   XL_SetFileIdAndSize(HANDLE hTask, char szFileId[40], unsigned __int64 nFileSize);
	extern "C" __declspec(dllimport) BOOL   XL_SetAdditionInfo( HANDLE task_id, WSAPROTOCOL_INFOW *sock_info, CHAR *http_resp_buf, LONG buf_len );
	extern "C" __declspec(dllimport) HANDLE XL_CreateTaskByURL(const wchar_t *url, const wchar_t *path, const wchar_t *fileName, BOOL IsResume);
	extern "C" __declspec(dllimport) LONG   XL_CreateTaskByThunder(wchar_t *pszUrl, wchar_t *pszFileName, wchar_t *pszReferUrl, wchar_t *pszCharSet, wchar_t *pszCookie);
	extern "C" __declspec(dllimport) LONG   XL_CreateBTTaskByThunder(const wchar_t *pszPath);
};

相关函数的具体说明,可以参考Github上的文档
这一版本没有调用的示例,但是没关系,liebao_Thunder_Cloud这一版本有调用示例;
在这里插入图片描述
参考thunderWrapper.h文件中的thunderWrapper类通过
LoadLibraryGetProcAddress函数调用,使用MSCV2017编译器
并添加<Windows.h>引用,建议添加:

#include <Windows.h>
#include <stdio.h>
#include <Shlwapi.h>
#pragma comment(lib,"Shlwapi")
  • 初始化函数示例:

只需要简单修改init方法,修改xldl.dll的加载路径,其他基本不变;

bool init(PCWSTR pDllPath = L"xldl.dll")
{
    assert(!m_hModule);
    WCHAR szModulePath[MAX_PATH] = { 0 };
     GetModuleFileNameW(NULL, szModulePath, MAX_PATH);
     PathRemoveFileSpecW(szModulePath);  // 拆分路径        新版使用PathCchRemoveFileSpec
    qDebug()<<"[szModulePath] "<<QString::fromWCharArray(szModulePath);
     WCHAR szDllpath[MAX_PATH] = { 0 };
     PathCombineW(szDllpath, szModulePath, L"xldl.dll");  // 连接路径, 新版建议使用 PathCchCombine
     qDebug()<<"[szDllpath] "<<QString::fromWCharArray(szDllpath);
    m_hModule = LoadLibraryW(szDllpath);
    assert(m_hModule);
    if (m_hModule == NULL)
    {
        qDebug()<<"can not load xldl.dll -->";
        throw L"can not load xldl.dll";
    }
    _Init					= (fn_Init)						GetProcAddress(m_hModule, "XL_Init");
    _UnInit					= (fn_UnInit)					GetProcAddress(m_hModule, "XL_UnInit");
    _TaskCreate				= (fn_TaskCreate)				GetProcAddress(m_hModule, "XL_CreateTask");
    _TaskDelete				= (fn_TaskDelete)				GetProcAddress(m_hModule, "XL_DeleteTask");
    _TaskStart				= (fn_TaskStart)				GetProcAddress(m_hModule, "XL_StartTask");
    _TaskPause				= (fn_StopTask)				    GetProcAddress(m_hModule, "XL_StopTask");
    _TaskForcePause         = (fn_StopTask)				    GetProcAddress(m_hModule, "XL_ForceStopTask");
    _TaskQuery				= (fn_TaskQuery)				GetProcAddress(m_hModule, "XL_QueryTaskInfo");
    _TaskQueryEx			= (fn_TaskQueryEx)				GetProcAddress(m_hModule, "XL_QueryTaskInfoEx");
    _LimitSpeed				= (fn_LimitSpeed)				GetProcAddress(m_hModule, "XL_SetSpeedLimit");
    _LimitUploadSpeed		= (fn_LimitUploadSpeed)			GetProcAddress(m_hModule, "XL_SetUploadSpeedLimit");
    _DelTempFile			= (fn_DelTempFile)				GetProcAddress(m_hModule, "XL_DelTempFile");
    _SetProxy				= (fn_SetProxy)                 GetProcAddress(m_hModule, "XL_SetProxy");
    _SetUserAgent			= (fn_SetUserAgent)				GetProcAddress(m_hModule, "XL_SetUserAgent");
    _GetFileSizeWithUrl		= (fn_GetFileSizeWithUrl)		GetProcAddress(m_hModule, "XL_GetFileSizeWithUrl");
    _ParseThunderPrivateUrl = (fn_ParseThunderPrivateUrl)	GetProcAddress(m_hModule, "XL_ParseThunderPrivateUrl");
    _SetAdditionInfo		= (fn_SetAdditionInfo)			GetProcAddress(m_hModule, "XL_SetAdditionInfo");
    _SetFileIdAndSize		= (fn_SetFileIdAndSize)			GetProcAddress(m_hModule, "XL_SetFileIdAndSize");
    _CreateTaskByURL        = (fn_CreateTaskByURL)			GetProcAddress(m_hModule, "XL_CreateTaskByURL");
    _CreateTaskByThunder    = (fn_CreateTaskByThunder)		GetProcAddress(m_hModule, "XL_CreateTaskByThunder");
    _CreateBTTaskByThunder  = (fn_CreateBTTaskByThunder)	GetProcAddress(m_hModule, "XL_CreateBTTaskByThunder");

    CHECKFUNC(_Init, false);
    return _Init() == TRUE;
}

需要注意的是在不同版本中,所包含的方法函数也不一样,例如liebao_Thunder_Cloud 版就没有XL_CreateTaskByURL函数方法,

  • 实际线程调用:

继承QThread类,重写void run() override;方法,获取文件总大小,下载进度,下载有效字节数,即时速度,倒计时等信息,并通过信号槽控制下载的中断和退出。

void QThread_ThunderWrapper::run()
{
 emit IsStart(true);
    bool ISuccessed=false;
    IsQuit=false;
    QString Error="";
    try {
        qDebug()<<"QThread_ThunderWrapper Start!";
        thunderWrapper=new Lib_ThunderWrapper();
        bool ISuccessed=thunderWrapper->init();
        if(!ISuccessed)
            throw QString("Lib_ThunderWrapper 初始化失败!");
        else
            qDebug()<<"thunderWrapper->init : Successed!";

        wchar_t * url=utf8_to_wchar(Urlpath.toStdString().c_str());
        wchar_t * path=utf8_to_wchar(Filepath.toStdString().c_str());
        wchar_t * fileName=utf8_to_wchar(Filename.toStdString().c_str());


        if(!thunderWrapper->CreateTaskByURL(url,path,fileName,TRUE))
        {
            thunderWrapper->unInit();
            throw QString("taskCreate 失败!");
        }
        else
            qDebug()<<"thunderWrapper->taskCreate : Successed!";

        if(!thunderWrapper->taskStart())
        {
            thunderWrapper->taskDelete();
            thunderWrapper->unInit();
            throw QString("taskStart 失败!");
        }
        else
            qDebug()<<"thunderWrapper->taskStart : Successed!";

        //! 1秒查询一次
        msleep(1000);
        DownTaskInfo stTaskInfo;
        while (!IsQuit) {
            if(thunderWrapper->taskQueryEx(stTaskInfo))
            {
                if(stTaskInfo.stat==TSC_ERROR)
                {
                    emit Current_status("下载失败!",TSC_ERROR);
                    throw QString("TSC_ERROR: fail_code:%1").arg(stTaskInfo.fail_code);
                }
                else if(stTaskInfo.stat==TSC_PAUSE)
                {
                    emit Current_status("下载暂停!",TSC_PAUSE);
                }
                else if(stTaskInfo.stat==TSC_DOWNLOAD)
                {
                    emit Current_status("正在下载...",TSC_PAUSE);
                    emit Down_Speed(stTaskInfo.nSpeed);
                    emit ProgressBar((int)stTaskInfo.fPercent*100);
                    emit SendDownsize(stTaskInfo.nTotalDownload,stTaskInfo.nTotalSize);
                    if(stTaskInfo.nSpeed>0)
                        emit Time_Remaining((stTaskInfo.nTotalSize-stTaskInfo.nTotalDownload)/stTaskInfo.nSpeed);
                }
                else if(stTaskInfo.stat==TSC_COMPLETE)
                {
                    ISuccessed=true;
                    IsQuit=true;
                    emit Current_status("下载完成",TSC_COMPLETE);
                    emit Down_Speed(stTaskInfo.nSpeed);
                    emit ProgressBar((int)stTaskInfo.fPercent*100);
                    emit SendDownsize(stTaskInfo.nTotalDownload,stTaskInfo.nTotalSize);
                    emit Time_Remaining(0);
                    break;
                }
                else if(stTaskInfo.stat==TSC_STARTPENDING)
                {
                    emit Current_status("等待下载!",TSC_STARTPENDING);
                }
                else if(stTaskInfo.stat==TSC_STOPPENDING)
                {
                    emit Current_status("停止等待!",TSC_STARTPENDING);
                }
//                qDebug().noquote()<<QString("\n state              : %1 "
//                                            "\n fail_code          : %2"
//                                            "\n nTotalSize         : %3"
//                                            "\n nTotalDownload     : %4"
//                                            "\n fPercent           : %5"
//                                            "\n nSrcTotal          : %6"
//                                            "\n nSrcUsing          : %7"
//                                            "\n nSpeed             : %8"
//                                            "\n szFilename         : %9"
//                                            "\n szSavePath         : %10"
//                                            "\n IsCreatingFile     : %11"
//                                            "\n bIsOriginUsable    : %12 \n\n")
//                                     .arg(stateStr)
//                                     .arg(stTaskInfo.fail_code)
//                                     .arg(QString::number(stTaskInfo.nTotalSize,10))
//                                     .arg(QString::number(stTaskInfo.nTotalDownload,10))
//                                     .arg(QString::number(stTaskInfo.fPercent))
//                                     .arg(stTaskInfo.nSrcTotal)
//                                     .arg(stTaskInfo.nSrcUsing)
//                                     .arg(stTaskInfo.nSpeed)
//                                     .arg(QString::fromWCharArray(stTaskInfo.szFilename))
//                                     .arg(QString::fromWCharArray(stTaskInfo.szReserved0))
//                                     .arg(stTaskInfo.IsCreatingFile?"TRUE":"FALSE")
//                                     .arg(stTaskInfo.bIsOriginUsable?"TRUE":"FALSE")
//                                    ;
                //! 1秒查询一次
                }
            msleep(1000);
        }

    }
    catch (QString error) {
        ISuccessed=false;
        Error="异常信息 :"+error;
    }
    catch (...) {}
    qDebug()<<"thunderWrapper unInit-->";
    thunderWrapper->unInit();
    //! 清除连接
    delete thunderWrapper;
    thunderWrapper=nullptr;
    emit IsStart(true);
}

如图所示:
下载在网上找到系统镜像文件时,ThunderOpenSDK下载速度更快, 能稳定到9mb/s左右,而通过原生的QNetworkReply下载最高在5Mb/s左右。
请添加图片描述


ThunderOpenSDK 下载问题

ThunderOpenSDK 无法下载包含重定向跳转的下载链接,
正当我打算整体改用ThunderOpenSDK下载时,我突然发现ThunderOpenSDK 无法下载项目中的资源文件,换成其他网上找的资源文件又能正常下载,
测试多次发现ThunderOpenSDK只能下载直接指向下载资源的链接,
包含重定向跳转的下载链接下载不了!
无解,果断放弃,还是改用调用Aria2下载!
不过一般的下载ThunderOpenSDK库也完全够用了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ML2021Spring-hw1(COVID-19 Cases Prediction)

文章目录 前言代码一代码二对比 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本篇博客内容来自&#xff1a;Machine Learning 2022 Spring &#x1f4ab;更多和本篇博客相关内容详见专栏&#xff1a;Machine Learning(李…

STM32主从定时器输出个数、频率可调的脉冲

STM32中发出脉冲一般有两种方式&#xff1a; 1&#xff09;利用定时中断输出脉冲&#xff0c;但是间隔的延时会影响其他主程序的进程&#xff0c;当控制多个电机的时候就非常不可取&#xff1b; 2&#xff09;利用PWM脉宽调制&#xff0c;并通过主从定时器进行设定&#xff0…

研发效能度量核心三问:看什么、怎么看、怎么说服团队

问题 1&#xff1a;研发效能度量指标应该看什么&#xff1f; 在探讨研发效能度量时&#xff0c;首要步骤是广泛了解并学习业界认可的成熟指标及其指向性。明确指标的指向性后&#xff0c;面对众多度量项&#xff0c;应采用 GQM&#xff08;Goal-Question-Metric&#xff09;方…

java多线程父子参数传递失败问题

java在一个父线程中启动了一个子线程 但是运行过程中父线程的参数没有传递到子线程 原因&#xff1a;threadLocal不支持父子线程传递 解决&#xff1a;使用TransmittableThreadLocal --有问题的代码 private static final ThreadLocal<EventRuntimeContext> FLOW_CO…

TIFS-2024 细粒度表示和重组在换衣行人重识别中的应用

总体结论 本文提出了一种新的细粒度表示与重构&#xff08;FIRe2&#xff09;框架&#xff0c;用于解决布变人重识别问题。通过细粒度特征挖掘和属性重构&#xff0c;FIRe2在不依赖任何辅助信息的情况下&#xff0c;实现了最先进的性能。该方法在多个基准数据集上取得了显著的…

PostgreSQL的前世今生

PostgreSQL的起源可以追溯到1977年的加州大学伯克利分校&#xff08;UC Berkeley&#xff09;的Ingres项目。该项目由著名的数据库科学家Michael Stonebraker领导&#xff0c;他是2015年图灵奖的获得者。以下是PostgreSQL起源的详细概述&#xff1a; 一、早期发展 Ingres项目…

DAY43 ||322.零钱兑换 |279.完全平方数 |139.单词拆分

322.零钱兑换 题目&#xff1a;322. 零钱兑换 - 力扣&#xff08;LeetCode&#xff09; 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 你可以认为每种硬…

WebGL进阶(五)-可视域

理论基础&#xff1a; 顶点着色器 Vertex Shader 主要是负责处理顶点位置、顶点颜色、顶点向量等顶点的数据&#xff1b;处理一些顶点的变换&#xff1a;例如在进行视图变换和投影变换时MVP矩阵会改变顶点的位置信息。 输入&#xff1a; 顶点着色器输入部分主要是声明&…

gin入门教程(10):实现jwt认证

使用 github.com/golang-jwt/jwt 实现 JWT&#xff08;JSON Web Token&#xff09;可以有效地进行用户身份验证,这个功能往往在接口前后端分离的应用中经常用到。以下是一个基本的示例&#xff0c;演示如何在 Gin 框架中实现 JWT 认证。 目录结构 /hello-gin │ ├── cmd/ …

三星瞄准2026年推出400层垂直NAND技术,2030年前剑指1000层NAND闪存

据报道&#xff0c;三星计划在2026年前推出400层的垂直NAND闪存&#xff0c;并且目标是在2030年前实现1000层的NAND技术。随着人工智能&#xff08;AI&#xff09;浪潮的到来&#xff0c;高带宽内存&#xff08;HBM&#xff09;已经成为存储巨头之间的关键战场&#xff0c;而同…

端口号和ip地址一样吗?区别是什么

在网络通信的世界里&#xff0c;端口号和IP地址是两个不可或缺的概念&#xff0c;它们各自扮演着独特的角色&#xff0c;共同维系着数据在网络中的有序传输。然而&#xff0c;对于许多初学者而言&#xff0c;这两者往往容易被混淆&#xff0c;认为它们是同一事物的不同表述。那…

前端自学资料(笔记八股)分享—CSS(4)

更多详情&#xff1a;爱米的前端小笔记&#xff08;csdn~xitujuejin~zhiHu~Baidu~小红shu&#xff09;同步更新&#xff0c;等你来看&#xff01;都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们…

JavaScript字符串不可变性与ES6 新增字符串方法详解

非 VIP 用户可前往公众号“前端基地”进行免费阅读,文章链接如下: JavaScript字符串不可变性与ES6 新增字符串方法详解本文介绍了 JavaScript 中字符串的不可变性以及 ES6 新增的字符串方法。包括判断是否包含、以指定字符串开头或结尾,还有重复指定次数等方法,并结合案例…

鸿蒙开发:arkTS FolderStack容器组件

ArkTS(也称为Ark TypeScript)是鸿蒙生态的应用开发语言&#xff0c;它在TypeScript(简称TS)的基础上进行了优化和定制&#xff0c;以满足鸿蒙系统的开发需求。今天给大家分享arkTS FolderStack容器组件技术知识&#xff0c;如果有所帮助&#xff0c;大家点点关注支持一下&#…

SSL/TLS 密码套件漏洞分析以及修复方法

1. 前言 在当今数字化时代&#xff0c;网络安全至关重要。SSL/TLS 协议作为保障网络通信安全的重要手段&#xff0c;广泛应用于各类网络应用中。然而&#xff0c;如同任何技术一样&#xff0c;SSL/TLS 也并非绝对安全&#xff0c;存在着一些可能被攻击者利用的漏洞。本文将深入…

如何加密电脑磁盘?电脑本地磁盘加密方法介绍

随着信息技术的不断发展&#xff0c;电脑磁盘加密已经成为保护个人隐私和数据安全的重要手段。本文将介绍几种常见的电脑本地磁盘加密方法&#xff0c;帮助用户保护自己的数据安全。 文件夹只读加密专家 文件夹只读加密专家不仅可以加密电脑中的文件夹&#xff0c;还可以加密保…

已解决Navicat 选择Mysql表 报错unkonow internal error: Access violation - no RTTI data

已解决Navicat 选择Mysql表 报错unkonow internal error&#xff1a; Access violation - no RTTI data 报错信息截图&#xff1a; 使用Navicat Premium15 选择sql server表时 出现大量弹窗报错&#xff0c;导致sql文件执行不了&#xff0c;右键数据库执行外部文件也失败了。弹…

【机器学习】揭秘XGboost:高效梯度提升算法的实践与应用

目录 &#x1f354; XGBoost 原理 1.1 目标函数确定和树的复杂度介绍 1.2 XGBoost目标函数的推导 1.3 泰勒公式展开 1.4 化简目标函数 1.5 问题再次转换 1.6 对叶子结点求导 1.7 XGBoost的回归树构建方法 &#x1f354; XGBoost API 2.1 通用参数 2.2 Booster 参数 …

基于vue框架的的高校学习资源共享系统5ym3y(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;学生,学校信息,课程分类,班课信息,班课申请,学习资源,班课评价,班课投诉,投诉学生,教师,班级 开题报告内容 基于Vue框架的高校学习资源共享系统开题报告 一、项目背景与意义 随着信息技术的飞速发展和教育改革的深入推进&#xff0c;…

Hadoop生态圈框架部署(二)- 配置IP地址映射为主机名及免密登录

文章目录 前言一、配置IP地址映射为主机名1. 虚拟机hadoop1配置主机名与 IP 地址的映射关系2. 虚拟机hadoop2配置主机名与 IP 地址的映射关系3. 虚拟机hadoop3配置主机名与 IP 地址的映射关系 二、配置免密登录1. 配置虚拟机hadoop1免密登录到hadoop1、hadoop2和hadoop32. 配置…