Mysql 源码阅读(二)登录连接调试

Mysql源代码阅读笔记(一) 代码流程 代码分析基于最新的5.5.21 Mysql服务器的main()在/sql/main.cc,实际的入口点在/sql/mysqld.cc。 我们直接从mysqld_main()开始阅读。 先理解一些比较重要的宏定义: (1)宏HAVE_NPTL:  这个宏如果打开了会去读一个系统变量LD_ASSUME_KERNEL,并把他赋给一个全局变量ld_assume_kernel_i 阅读详情

简介

在上篇中我们将源码在本地顺利的跑了起来,接下来我们需要连接我们的数据库,为后面的工作做一定的准备

使用docker容器尝试连接

我们首先使用docker容器去启动连接我们上篇文章中成功运行起来的MySQL服务器,但没能如愿,没有连接成功

下面的错误,以前我们也是经常见到了

PS C:\Users\lw> docker run -ti mysql mysql -h 192.168.1.4 -P 3306 -u root -p
Enter password:
ERROR 1130 (HY000): Host 'DESKTOP-8U69O9P' is not allowed to connect to this MySQL server

我们使用: is not allowed 去全局搜索下代码,找到下面的代码,通过打上断点,也走到了这步里面

成功的找到了代码入口

bool acl_check_host(const char *host, const char *ip)
{
  mysql_mutex_lock(&acl_cache->lock);
  if (allow_all_hosts)
  {
    
    mysql_mutex_unlock(&acl_cache->lock);
    return 0;
  }

  if ((host && my_hash_search(&acl_check_hosts,(uchar*) host,strlen(host))) ||
      (ip && my_hash_search(&acl_check_hosts,(uchar*) ip, strlen(ip))))
  {
    mysql_mutex_unlock(&acl_cache->lock);
    return 0;                                   // Found host
  }
  for (ACL_HOST_AND_IP *acl= acl_wild_hosts->begin();
       acl != acl_wild_hosts->end(); ++acl)
  {
    if (acl->compare_hostname(host, ip))
    {
      mysql_mutex_unlock(&acl_cache->lock);
      return 0;                                 // Host ok
    }
  }
  mysql_mutex_unlock(&acl_cache->lock);
  if (ip != NULL)
  {
    /* Increment HOST_CACHE.COUNT_HOST_ACL_ERRORS. */
    Host_errors errors;
    errors.m_host_acl= 1;
    inc_host_errors(ip, &errors);
  }
  return 1;                                     // Host is not allowed
}

通过调试,我们发现acl_wild_hosts里面没有值导致的,导致ip==null,从而host没有匹配上,不允许连接

我们在当前文件中没有搜索到acl_wild_hosts,只能在整个解决方案中进行搜索,我们定位到下面一段代码:

static void init_check_host(void)
{
  DBUG_ENTER("init_check_host");
  if (acl_wild_hosts != NULL)
    acl_wild_hosts->clear();
  else
    acl_wild_hosts=
      new Prealloced_array<ACL_HOST_AND_IP, ACL_PREALLOC_SIZE>(key_memory_acl_mem);

  size_t acl_users_size= acl_users ? acl_users->size() : 0;

  (void) my_hash_init(&acl_check_hosts,system_charset_info,
                      acl_users_size, 0, 0,
                      (my_hash_get_key) check_get_key, 0, 0,
                      key_memory_acl_mem);
  if (acl_users_size && !allow_all_hosts)
  {
    for (ACL_USER *acl_user= acl_users->begin();
         acl_user != acl_users->end(); ++acl_user)
    {
      if (acl_user->host.has_wildcard())
      {                                         // Has wildcard
        ACL_HOST_AND_IP *acl= NULL;
        for (acl= acl_wild_hosts->begin(); acl != acl_wild_hosts->end(); ++acl)
        {                                       // Check if host already exists
          if (!my_strcasecmp(system_charset_info,
                             acl_user->host.get_host(), acl->get_host()))
            break;                              // already stored
        }
        if (acl == acl_wild_hosts->end())       // If new
          acl_wild_hosts->push_back(acl_user->host);
      }
      else if (!my_hash_search(&acl_check_hosts,(uchar*)
                               acl_user->host.get_host(),
                               acl_user->host.get_host_len()))
      {
        if (my_hash_insert(&acl_check_hosts,(uchar*) acl_user))
        {                                       // End of memory
          allow_all_hosts=1;                    // Should never happen
          DBUG_VOID_RETURN;
        }
      }
    }
  }
  acl_wild_hosts->shrink_to_fit();
  freeze_size(&acl_check_hosts.array);
  DBUG_VOID_RETURN;
}

从名称和功能上看出,这个就是acl_check_hosts的初始化相关代码

其中acl_users通过断点调试,有三个用户:

  • root:我们的经常用到的初始用户
  • mysql.session: 这个还真没见过
  • mysql.sys: 这个也没有见过

这个函数看下来,大致有两个地方会导致acl_check_hosts的增加:

(void) my_hash_init(&acl_check_hosts,system_charset_info,
                      acl_users_size, 0, 0,
                      (my_hash_get_key) check_get_key, 0, 0,
                      key_memory_acl_mem);

上面这个是初始化,从里面的参数没有找到什么新增的

下面一段代码是明显新增的,但调试中,代码一直走不进去这段逻辑

if (acl == acl_wild_hosts->end())       // If new
          acl_wild_hosts->push_back(acl_user->host);

而走不下去的第一步就是

if (acl_user->host.has_wildcard())

bool has_wildcard()
  {
    return (strchr(hostname,wild_many) ||
            strchr(hostname,wild_one)  || ip_mask );
  }

strchr是一个字符串搜索函数:该函数返回在字符串 str 中第一次出现字符 c 的位置,如果未找到该字符则返回 NULL。

其中的wild_many是我们熟悉的%,而wild_one是"_",而hostname是localhost,所以没有匹配上

都走不下去,那我们只能看看acl_user的相关代码了

很幸运,在当前文件中,我们找到了acl_users的初始化函数:

static my_bool acl_load(THD *thd, TABLE_LIST *tables)

// 函数代码太长了,先粘贴一个关键的
acl_users->push_back(user);

而host的初始化在这步:

user.host.update_hostname(get_field(&global_acl_memory,
                                      table->field[table_schema->host_idx()]));

看着是从表中读取一些数据,有点头大,搞不动了,看不懂(超过认知负载了,我们继续挖下去也挖不动了,只能先往上跳一跳)

使用mysql workbench进行连接

为了避免一直卡住不动了,我们还是直接本地安装一个mysql workbench,然后使用localhost的域名和root用户进行连接

如果忘记了初始密码,想要再初始化一次,可能会遇到下面的错误:

2022-06-25T00:28:59.791538Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.

我们把源码根目录下的: release/sql/data 文件夹删除即可

初次链接的使用需要重置密码,重置完成后,就链接上了

然后我们执行下面的脚本,赋予root其他ip的连接权限

SET SQL_SAFE_UPDATES = 0;
use mysql;
update user set host='%' where user='root';
flush privileges;

在我们运行上面的SQL的时候,用户的初始化和host检测的初始化,都重新执行一遍

再次使用mysql容器进行连接

然后我们再次运行命令进行连接

docker run -ti mysql mysql -h 192.168.1.4 -P 3306 -u root -p

通过调试,我们发现现在是直接:allow_all_hosts 直接允许访问了

bool acl_check_host(const char *host, const char *ip)
{
  mysql_mutex_lock(&acl_cache->lock);
  if (allow_all_hosts)
  {
    
    mysql_mutex_unlock(&acl_cache->lock);
    return 0;
  }
  ......
}

通过查看代码是在这里设置的,但也看不是太懂,留待日后,今天看的也有点晕了

static void init_check_host(void)
{
......
  if (acl_users_size && !allow_all_hosts)
  {
      {
        if (my_hash_insert(&acl_check_hosts,(uchar*) acl_user))
        {                                       // End of memory
          // 这里直接设置了
          allow_all_hosts=1;                    // Should never happen
          DBUG_VOID_RETURN;
        }
      }
    }
  }
......
}

然后我们就成功访问了

总结

今天吧登录认证的代码走了一遍,对MySQL的连接认证有了一个初步的认知,但还是有很多的细节不清楚

使用docker容器连接成功后,我们一直debug下去,发现了tcp连接的监听处理函数:

extern "C" void *handle_connection(void *arg)
{
    // 连接准备,今天的host检测和用户认证都是在这个函数里面进行的
    if (thd_prepare_connection(thd))
      handler_manager->inc_aborted_connects();
    else
    {
      while (thd_connection_alive(thd))
      {
	// 看名字就知道是具体命令的处理函数,嘿嘿,找到了下篇文章的函数入口
        if (do_command(thd))
          break;
      }
      end_connection(thd);
    }
    close_connection(thd, 0, false, false);
    ······
}

参考链接

基于Spring Boot的小说阅读平台(源码+LW+调试+讲解) 👑本项目是一个基于Spring Boot✅✅的小说阅读平台✅✅系统,旨在为用户提供便捷的阅读体验。平台支持章节更新提醒、离线缓存阅读等功能,同时具备个性化推荐系统,根据用户的阅读历史推送相似小说。作者可以通过平台发布自己的小说作品并获得粉丝与反馈。整体系统通过简洁的界面设计和高效的后台管理,提供了一个舒适的阅读环境,提升了小说爱好者的阅读体验。 阅读详情

相关推荐

mysql-5.7.23-source-read:mysql-5.7.23原始代码阅读分析-mysql

mysql-5.7.23-源代码阅读 mysql-5.7.23原始代码阅读分析

如何阅读MySQL源码

目录1.下载MySQL源码2.IDE的使用2.1 安装 C/C++ 插件。2.2 打开代码 为了更加准确的理解MySQL原理,很多时间需要查看文档和阅读源码。如果文档中,描述模糊,就需要查看代码进行确认。 本文简单介绍下,在Mac OS 环境下,如何高效的阅读MySQL源码。 1.下载MySQL源码 在github上找到release列表,选择需要下载的版本。 本文这里下载的是5.7.26。 下载后,解压缩。 2.IDE的使用 IDE的使用,可以极大提高阅读效率。 网上,有的也推荐用vim等等,需要繁琐的配

翔云 3714

火星遥感数据的获取与处理工具安装详解

有关火星遥感影像数据的那些事...

FengYingLuo的博客 5570

Mysql源码阅读 -- Windows10编译运行MySQL源码

看了一些MySQL相关的书籍和文章,但感觉知识还不是自己的,打算看一看源码,本篇文章就从Windows10下编译运行MySQL源码开始

github_35735591的博客 926

STM32移植LVGL(LittleVGL)

**STM32移植LVGL(LittleVGL)**

qq_53000374的博客 1万+

国内网络环境下Leaflet加载OpenStreetMap地图的5种替代方案(附可用瓦片地址)

本文针对国内网络环境下Leaflet加载OpenStreetMap地图的常见问题,提供了5种可用的瓦片替代方案,包括OpenStreetMap.fr HOT、OpenStreetMap.de、CartoDB、Stamen和Thunderforest,并附上详细的代码示例和选择建议,帮助开发者解决地图加载问题。

qsc901234的博客 1678

【MySQL】MVCC原理分析 + 源码解读 -- 必须说透

如何控制并发是数据库领域中非常重要的问题之一,MySQL为了解决并发带来的问题,设计了事务隔离机制、锁机制、MVCC机制等等,用一整套机制来解决并发问题,本文主要介绍MySQL5.7版本的MVCC机制。MVCC, 全称 Multi-Version Concurrency Control(多版本并发控制)利用多版本解决的是读写并发冲突, 做到读写冲突时, 避免加锁, 实现非阻塞的读操作, 也就是无锁并发控制.

天罡gg的专栏 6332

BitLocker恢复密钥丢失?从原理到实战的完整解锁与系统重生指南

磁盘加密技术是数据安全的核心防线,它通过对存储设备上的数据进行编码,确保未经授权的用户无法访问。其原理主要基于加密算法(如AES)与密钥管理机制,在操作系统启动前或数据读写时进行实时加解密。这项技术的核心价值在于防止设备丢失或被盗后的数据泄露,尤其对于笔记本电脑和移动设备至关重要。典型的应用场景包括企业办公电脑、存有敏感信息的个人设备以及符合合规性要求的行业。当使用Windows系统自带的BitLocker加密功能时,若因硬件改动、系统更新等触发保护机制,用户可能会面临需要输入恢复密钥才能启动的困境。本文聚

weixin_34006965的博客 487

科普文:软件架构数据库系列之【MySQL源码阅读小技巧】

开源软件已经广泛的被互联网公司所应用,不仅仅是因为其能给企业节省一大笔成本,而且最重要的是拥有更多的自主可控性,能从源头上对软件质量进行把控。另一方面,由于开源软件背后往往没有大型的商业公司,所以文档相对来说不是非常完善(或者说文档和代码不一定相互对应),因此,作为一名合格程序员,尤其是基础软件开发的程序员,阅读源码的能力是必备的素质。

为无为,事无事,味无味。 1542

fast-lio运行步骤(使用velodyne数据)

使用fast-lio运行velodyne数据

ericdowney 4768

QT应用编程: 编写低功耗BLE蓝牙调试助手(Android系统APP)

一、环境介绍 QT版本: 5.12.6 编译环境: win10 64位 目标系统: Android 完整工程源码下载地址(包含APK文件):https://download.youkuaiyun.com/download/xiaolong1126626497/19051696 二、功能介绍 本软件是一款BLE蓝牙串口调试助手,支持常规的发送和接收调试,BLE是低功耗类型蓝牙,在智能家居、物联网领域使用较多。BLE低功耗蓝牙一般不能直接使用手机进行连接,手机蓝牙默认都是工作在传统蓝牙模式,无法直接连接BL..

7656

idea调试mysql源码_IDEA阅读spring源码并调试

目标:搭建起Spring源码阅读和代码调试跟踪的环境,顺便建立一个简单的Demo,能够调试Spring的源代码本节,主要介绍一下Spring源码阅读和调试的相关环境搭建,并使用MVN创建一个非常简单的Demo,以便可以跟踪和调试Spring的内核。1、源码的下载2、Spring源码的编译Spring源码下载下来后,我这里比较习惯,先编译出来,而不是直接导入到相关的 IDE。大型的开源项目都是借助于...

weixin_35411480的博客 478

105、LLC谐振变换器的LTspice仿真建模

文章摘要:本文分享了LLC谐振变换器在LTspice中的仿真建模经验。作者从实际调试中炸管的教训出发,指出数学计算无法捕捉瞬态问题,必须通过仿真验证。详细介绍了半桥LLC主电路搭建、理想元件选择、开环增益扫频、闭环控制实现等关键步骤,重点讲解了启动过程、ZVS验证和短路保护等高风险工况的仿真技巧。文章提供了实用参数设置建议和LTspice代码片段,强调先开环后闭环的调试顺序,并提醒仿真结果需保留20%设计裕量。最后总结了谐振电流波形观察、死区时间优化等经验性建议。

Jack010169的博客 223

php基于Vue在线小说阅读平台(源码+文档+调试+讲解)

在线小说阅读平台汇聚海量作品,满足读者多元需求,提供便捷阅读体验。智能推荐系统助力发现佳作,互动性强,促进读者交流。多种阅读模式,舒适体验。平台成文学传播新渠道,注入活力。系统利用PHP语言,结合目前流行的 B/S架构,数据库使用免费的高性能MySQL数据库作为后端数据库,系统选择Windows操作系统。实现用户、作者、小说分类、热门小说、我的书架、小说听书、系统管理、我的信息等功能。面向用户群体,分为管理员、作者和用户三个角色,针对不同的用户划分不同的管理权限。期望该系统能够成为汉服销售与租赁的主要系统。

qq_1262330535的博客 1751

ABAP ALV 导出总被锁死为固定格式?把 Always Use Selected Format 一键重置到可选状态

摘要:SAP ALV报表导出时勾选"Always Use Selected Format"会导致导出格式被锁定,无法切换格式。文章分析该问题原因(系统持久化配置),提供用户自助解法(ALV list使用&RESET_EXCEL命令码,ALV grid通过右键菜单恢复弹窗),管理员治理方案(使用SALV_BS_ADMIN_MAINTAIN报表批量处理),并指出SAP_BASIS 7.02版本的特殊处理方式(需参考SAP Note 1716802和1590484)。最后给出排障清单,

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 217

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

基于Spring Boot的名著阅读网站(源码+LW+调试+讲解)

👑本项目是一个基于Spring Boot✅✅的名著阅读✅✅网站,汇集经典文学作品,方便读者在线阅读和下载。网站提供书籍的详细信息,包括作者、出版年份和简介,同时支持用户评论和评分功能,促进阅读交流。用户可以根据分类、标签和热门推荐等方式快速查找感兴趣的书籍。此外,系统还允许用户创建个人书单,记录阅读进度,提升阅读体验。网站的目标是让更多人接触和欣赏经典文学,培养阅读习惯。

leealan的博客 906

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

基于SpringBoot+Vue的小说阅读器系统(源码+LW+调试文档+讲解)

基于 Spring Boot + Vue 的小说阅读器系统是一款为小说爱好者打造的功能丰富、体验优良的阅读平台。 系统在用户管理方面具备完善的功能。用户可以通过多种方式注册账号,如手机号注册、邮箱注册等,注册过程中需设置密码。登录后可完善个人信息,包括昵称、头像、性别、年龄等。同时,系统支持用户修改密码,若用户忘记密码,可通过验证手机号或邮箱来重置。此外,用户可根据自己的阅读偏好设置个性化信息,如字体大小、字体类型、背景颜色、阅读模式(白天模式、夜间模式、护眼模式等),让阅读更加舒适。 小说资源管理是系统的

专注于大学生项目实战开发,讲解,毕业答疑辅导,高校老师/讲师/同行合作。以及产品测评宣传、工具推广等合作。全网粉丝30万+,优快云特邀博主,Java新星计划多届导师,掘金/知乎/华为云/阿里云/51CTO等平台优质创作者。 853

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

基于springboot的小说阅读器系统网站(源码+文档)

基于 Spring Boot 的小说阅读器系统网站(源码 + 文档)是一个为小说爱好者打造的在线阅读平台。系统通过用户注册登录功能将用户划分为普通读者、作者和管理员。普通读者可通过邮箱或手机号注册登录,能够搜索、浏览各类小说,将喜欢的小说添加到书架,阅读小说并进行评论、打分,同时可以设置阅读偏好,系统会根据偏好推荐小说。作者可以上传自己创作的小说,更新章节内容,查看读者反馈和作品的统计数据,如阅读量、收藏量等。管理员负责用户信息管理和系统的整体维护,包括审核小说内容,确保其符合法律法规和平台规定。

专注于大学生项目实战开发,讲解,毕业答疑辅导,java就业辅导,高校老师/讲师/同行合作。以及产品测评宣传、工具推广等合作。全网粉丝10w+,平台优质java、小程序创作者。 1255

java源码案例-基于springboot的网络文章阅读与写作,基于springboot的网络小说阅读与写作平台的设计(源码+文档+远程调试等)

java源码案例-基于springboot的网络文章阅读与写作,基于springboot的网络小说阅读与写作平台的设计(源码+文档+远程调试等)

项目帮 746

基于Java+SpringBoot+SSM,Flask在线英语阅读分级平台(源码+LW+调试文档+讲解等)/在线英语阅读/英语阅读分级/分级阅读平台/英语阅读平台/在线阅读分级/英语分级阅读

前端:Spring+SpringMVC+Mybatis,Flask、Python Web框架,后端语言Python后端:SpringBoot+Mybatis数据库:MySQL、SQLServer开发工具:IDEA、Eclipse、Navicat等✌关于毕设项目技术实现问题讲解也可以给我留言咨询!!!SSM 框架的整合使用,为程序设计带来了诸多优势。在开发过程中,Spring 负责整体的架构管理和资源整合,SpringMVC 处理用户请求和业务逻辑,MyBatis 进行数据的持久化操作。

2401_88036107的博客 634

Jsp web小说在线阅读网站的设计与实现(附源码 调试 文档)

本文设计并实现了一个基于JSP和MySQL的小说在线阅读网站管理系统。系统包括两种用户角色:系统管理员和前台会员。系统管理员具有会员管理、通知公告管理、小说类别管理、小说管理和留言管理的功能;前台会员具有小说阅读、小说搜索、公告查看和个人中心管理的功能。本文详细介绍了系统的设计思路、实现方法和具体功能,并通过实际应用案例证明了系统的可行性和实用性。本系统的设计和实现对于提高小说在线阅读网站的管理效率和用户体验具有重要的意义,可以为小说在线阅读网站提供有力的支持和帮助。

1659

基于PHP+MySql的小说阅读网站的设计与实现(附论文 源码 讲解 调试)

随着计算机网络技术的快速发展和普及,网络已经成为人们生活中不可缺少的元素,人们对网络的使用不单单再停留在简单的网页浏览上面,更多的是录找精神上的满足,也就是精神文化方面的需求大大搞升,在这种情况下,人们阅读小说的方式也逐渐的发生着变化,小说网上由此应运而生。一个系统化的小说网站,不升能大大提高用户阅读小说的便利性,同时又能给网站带来稳定的流量,在这个流量就是金钱的时代,开发一款基于PHP技术的小说阅读网站,是相当切实可行的。

1425

基于PHP+ThinkPHP+Vue在线小说阅读平台(源码+LW+调试文档+讲解等)/网络小说阅读/在线阅读网站/电子书阅读/小说在线看/在线看书/免费小说阅读/小说阅读网站/手机小说阅读

前端:Vue、Vue.js、ElementUI后端:ThinkPHP,后端语言php数据库:MySQL、SQLServer开发工具:IDEA、Eclipse、Navicat等✌关于毕设项目技术实现问题讲解也可以给我留言咨询!!!Vue 在程序设计中具有诸多优势。它的简洁语法、组件化开发、强大的指令系统和有效的状态管理,使得程序设计者能够快速构建出高性能、交互性强的应用程序。无论是小型项目还是大型企业级应用,Vue 都能为程序设计提供强大的支持。ThinkPHP 的路由功能在程序设计中非常出色。

擅长Java、Python、小程序、Web网站开发和计算机毕设项目实战✌ 1045

基于PHP+ThinkPHP+Vue小说阅读系统(源码+LW+调试文档+讲解等)/在线小说阅读/电子书阅读器/网络小说系统/免费小说阅读/阅读软件/小说阅读器/小说在线看/小说阅读网站/小说阅读工具

前端:Vue、Vue.js、ElementUI后端:ThinkPHP,后端语言php数据库:MySQL、SQLServer开发工具:IDEA、Eclipse、Navicat等✌关于毕设项目技术实现问题讲解也可以给我留言咨询!!!Vue 在程序设计中具有诸多优势。它的简洁语法、组件化开发、强大的指令系统和有效的状态管理,使得程序设计者能够快速构建出高性能、交互性强的应用程序。无论是小型项目还是大型企业级应用,Vue 都能为程序设计提供强大的支持。ThinkPHP 在程序设计中展现出强大的实用性。

2401_88036107的博客 921

【源码+文档+调试讲解】小说阅读平台97

小说阅读平台是一个汇聚海量文学作品的数字世界。在这里,读者可以尽情探索各种类型的小说,从经典名著到网络热门作品,应有尽有。平台提供舒适的阅读环境,支持多种设备访问,让读者随时随地沉浸在精彩的故事中。小说阅读平台不仅满足读者的阅读需求,更成为文学爱好者交流互动的乐园。系统采用基于Java语言网站开发技术设计的,结合Mysql数据库管理系统对小说阅读相关信息进行管理。按照软件工程学理论完成各阶段设计,经过调试测试达到了管理小说阅读信息的能力。满足了管理员和用户的需要。

2401_84408400的博客 742
上一篇: Mysql源码阅读 -- Windows10编译运行MySQL源码
下一篇: K8S V1.23 安装--Kubeadm+contained+公网 IP 多节点部署
_萧_
博客等级 码龄10年 55粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值