下载工具漫谈

第1章 下载协议

常用的下载协议有HTTP、FTP、P2P。

下载一个文件可以使用HTTP或FTP,这两种都是集中下载的方式,而 P2P则换了一种思路,采取非中心化下载的方式。P2P也是有两种,一种是依赖于tracker的,也即元数据集中,文件数据分散;另一种是基于分布式的哈希算法,元数据和文件数据全部分散。

首先简述HTTP下载和FTP下载的区别。Web浏览器对这两种协议都有支持,在使用Web浏览器进行请求下载时,这两个协议之间的差异几乎不会对使用的方便性及下载时间产生影响。不过,两者却拥有各自不同的结构。

1.1 HTTP下载

HTTP是一种为了将位于全球各个地方的Web服务器中的内容发送给不特定多数用户而制订的协议。也就是说,可以把HTTP看作是旨在向不特定多数的用户“发放”文件的协议。

HTTP使用于从服务器读取Web页面内容。Web浏览器下载Web服务器中的HTML文件及图像文件等,并临时保存在个人电脑硬盘及内存中以供显示。

使用HTTP下载软件等内容时的不同之处只是在于是否以Web浏览器显示的方式保存,还是以不显示的方式保存而已。结构则完全相同。因此,只要指定文件,任何人都可以进行下载。

1.2 FTP下载

FTP即文件传输协议,是专门设计用来做文件传输的应用层协议。
FTP采用两个TCP连接来传输一个文件。

1.2.1 控制连接

服务器以被动的方式,打开众所周知用于FTP的端口21,客户端则主动发起连接。该连接将命令从客户端传给服务器,并传回服务器的应答。常用的命令有:
list——获取文件目录;
reter——取一个文件;
store——存一个文件。

1.2.2 数据连接

每当一个文件在客户端与服务器之间传输时,就创建一个数据连接。

另一方面,FTP是为了在特定主机之间“传输”文件而开发的协议。因此,在FTP通信的起始阶段,必须运行通过用户ID和密码确认通信对方的认证程序,

1.2.3 FTP的两种工作模式

每传输一个文件,都要建立一个全新的数据连接。FTP 有两种工作模式,分别是主动模式(PORT)和被动模式(PASV),这些都是站在 FTP 服务器的角度来说的。

1.3 P2P

无论是 HTTP 的方式,还是 FTP 的方式,都有一个比较大的缺点,就是难以解决单一服务器的带宽压力,因为它们使用的都是传统的客户端服务器的方式。

P2P就是peer-to-peer。资源开始并不集中地存储在某些设备上,而是分散地存储在多台设备上。这些设备我们姑且称为peer。

1.3.1 概念定义
P2P定义

Peer-to-peer网络是一个运行于个人电脑上的应用,通过网络在用户间分享文件,而不再通过中央服务器。

P2P是一种分布式网络,网络的参与者共享他们所拥有的一部分硬件资源(处理能力、存储能力、网络连接能力、打印机等),这些共享资源需要由网络提供服务和内容,能被其它对等节点(peer)直接访问而无需经过中间实体。在此网络中的参与者既是资源(服务和内容)提供者(server),又是资源(服务和内容)获取者(client)。

P2P特点

无中央服务器,打破了C/S模式,用户之间互联并分享文件。

P2P应用分类

在P2P技术出现时,出现了P2P技术解决一切问题的风潮,类似与区块链对接一切。因此在市场上出现了很多基于P2P网络的应用。

1、提供文件和其他内容共享的P2P网络,即不同的文件下载器。如Napster、Gnutella、eDonkey、emule、BitTorrent等;
2、挖掘P2P对等计算能力和存储共享能力,如SETI@home、Avaki、Popular Power等;
3、基于P2P方式的协同处理与服务共享平台,如JXTA、Magi、Groove、.NET My Service等;
4、即时通讯交流,包括ICQ、QICQ、Yahoo Messenger等;
5、安全的P2P通讯与信息共享,如Skype、Crowds、Onion Routing等。

1.3.2 BitTorrent协议

满足上述的P2P下载原理,就需要设计相关的协议。具有代表性的就是BitTorrent协议。

协议功能描述

想要下载一个文件的时候,你只要得到那些已经存在了文件的 peer,并和这些 peer 之间,建立点对点的连接,而不需要到中心服务器上,就可以就近下载文件。

一旦下载了文件,你也就成为 peer 中的一员,你旁边的那些机器,也可能会选择从你这里下载文件,所以当你使用 P2P 软件的时候,例如 BitTorrent,往往能够看到,既有下载流量,也有上传的流量,也即你自己也加入了这个 P2P 的网络,自己从别人那里下载,同时也提供给其他人下载。

可以想象,这种方式,参与的人越多,下载速度越快,一切完美。

.torrent种子文件

当你想下载一个文件的时候,怎么知道哪些 peer 有这个文件呢?这就用到种子啦,也即咱们比较熟悉的.torrent 文件。.torrent 文件由两部分组成,分别是:announce(tracker URL)和文件信息。

文件信息里面有这些内容:

info 区:这里指定的是该种子有几个文件、文件有多长、目录结构,以及目录和文件的名字
Name 字段:指定顶层目录名字
每个段的大小:BitTorrent(简称 BT)协议把一个文件分成很多个小段,然后分段下载
段哈希值:将整个种子中,每个段的 SHA-1 哈希值拼在一起
工作过程

下载时,BT客户端首先解析.torrent 文件,得到 tracker 地址,然后连接 tracker 服务器。

tracker 服务器回应下载者的请求,将其他下载者(包括发布者)的 IP 提供给下载者。

下载者再连接其他下载者,根据.torrent 文件,两者分别对方告知自己已经有的块,然后交换对方没有的数据。
此时不需要其他服务器参与,并分散了单个线路上的数据流量,因此减轻了服务器的负担。

这个过程也可以看出,这种方式特别依赖 tracker。tracker 需要收集下载者信息的服务器,并将此信息提供给其他下载者,使下载者们相互连接起来,传输数据。

虽然下载的过程是非中心化的,但是加入这个 P2P 网络的时候,都需要借助 tracker 中心服务器,这个服务器是用来登记有哪些用户在请求哪些资源。所以,这种工作方式有一个弊端,一旦 tracker 服务器出现故障或者线路遭到屏蔽,BT 工具就无法正常工作了。

1.3.3 去中心化网络(DHT)

为了向彻底去中心化迈步前进,后来就有了一种叫作DHT(Distributed Hash Table)的去中心化网络。

每个加入这个DHT网络的节点,都要负责存储这个网络里的资源信息和其他成员的联系信息,相当于所有节点一起构成了一个庞大的分布式存储数据库。

有一种著名的 DHT 协议,叫Kademlia协议。这个和区块链的概念一样,很抽象。

任何一个 BitTorrent 启动之后,它都有两个角色。一个是peer,监听一个 TCP 端口,用来上传和下载文件,这个角色表明,我这里有某个文件。另一个角色DHT node,监听一个 UDP 的端口,通过这个角色,这个节点加入了一个 DHT 的网络。

在DHT网络里面,每一个DHT node 都有一个 ID。这个ID是一个很长的串。每个DHT node都有责任掌握一些知识,也就是文件索引,也即它应该知道某些文件是保存在哪些节点上。

它只需要有这些知识就可以了,而它自己本身不一定就是保存这个文件的节点。

1.4 磁力链接

1.4.1 BT下载流程及存在问题

通过前面章节,已经了解用户通过BT下载的基本过程:

一、找到.torrent文件
二、使用BT客户端软件打开这个文件
三、客户端软件会根据.torrent文件中的网址自动连接Tracker服务器,从它那里接收到其他正在下载该文件的人的网址名单。下一步,软件就一一与名单上的网址取得联系,从它们那里获取文件的片段,直到整个下载完成。从整个过程不难看出,BT Tracker服务器是一个中央节点,任何客户端都可以在其上找到“同伴”——只要其他人也在下载或分享同一个文件。

因此,BT并非一个去中心化的应用,必须依靠中央节点(BT Tracker服务器)才能正常工作。存在该中心化节点,就存在不稳定性。

1.4.2 Magnet下载文件原理

Magnet不需要Tracker服务器,也不需要.torrent文件,仅需要一串字符就可以进行文件下载。
其所用到的关键技术点如下。

DHT

2002年,纽约大学的两个教授Petar Maymounkov和David Mazières发表了一篇论文,提出了一种真正去中心化的“点对点”下载模型,他们将其称为Kademlia方法。2005年,BT软件开始引入这种技术,在BT中被称为DHT协议(Distributed Hash Table,分布式哈希表)。

DHT是一种分布式存储方法。DHT的作用是找到那些与本机正在下载(上传)相同文件的对端主机(Peer),当然,实现这一过程并不依赖Tracker服务器。在DHT网络中的每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。这种信息获取方式保证了整个网络没有单个的中心,即使一个节点下线,依然可以通过其他节点来获取文件,因此也就不需要Tracker服务器来告诉你,其他节点在什么地方。

PEX

PEX是Peer Exchange的简写,我们可以将其理解为“节点信息交换”。虽然DHT解决了去中心化的问题,但要在没有“中心协调员”(Tracker)的情况下实现高效寻址,就要借助PEX。PEX所提供的功能有点类似于以前的Tracker服务器,但工作方式却非常不同,我们可以打个比方来说明。
小赵在A班,她不认识B班的小何,也不认识C班的小温,但小赵认识同班的小王,而小王认识B班的小何,也可能还认识C班的小温,或者小王仅认识B班的小何,但小何认识C班的小温,而小温又认识同班的所有同学,结果就是小赵可以“无限”地延伸自己的关系网,不管怎样,总有一条沟通途径可以将这些同学联系在一起,待小赵“认识”了小温后,他们就可以直接沟通了,在P2P世界里,就是进行上传与下载。
Magnet links
有网友将其称为磁链。DHT+PEX解决了BT“寻址”的问题,但是如何告诉BT客户端找(寻)什么又是另外一个问题。在.torrent文件中包含的内容就是用户真正要下载的文件的特征信息,或称为“电子指纹”,BT客户端知道了要找什么,也知道如何去找,于是P2P方式的下载、上传就实现了。以前BT客户端通过.torrent文件得知“要找什么”,现在,文件的“电子指纹”不再存放于.torrent中,而被放在了Magnet links中
例如:

magnet:?xt=urn:btih:36684b463ca2aa2f9347b18e9f6b1a9090bdb073&dn=Microsoft+iSCSI+Initiator

分解一下这个地址:

magnet:协议名。
xt:exact topic的缩写,表示资源定位点。BTIH(BitTorrent Info Hash)表示哈希方法名,这里还可以使用SHA1和MD5。这个值是文件的标识符,是不可缺少的。
dn:display name的缩写,表示向用户显示的文件名。这是一个可选项。
tr:tracker的缩写,表示tracker服务器的地址。这是一个可选项,本例中并未出现。

其实magnet:?xt=urn:btih:36684b463ca2aa2f9347b18e9f6b1a9090bdb073就够用了,附加dn(display name),在使用上会更加方便一些。

Magnet Link的好处至少包括两点:网络的可靠性得到了极大的增强;不存在“被拔线”的风险。由于不存在所谓的中央节点,审查将变得更加困难,“单点失效”的问题也就不存在了。此外,Magnet URI只是一个字符串,非常容易传播,根本无法禁止。因此,Magnet URI取代Tracker模式将是大势所趋,迟早会成为主流BT下载方式。

DHT+PEX+Magnet Link模式中的一个问题——BT客户端的“第一步是如何迈出的”,套用在介绍PEX时使用的例子,那就是小赵是怎么“加入”A班的呢?这确实是个问题。解决这个问题依然需要一台服务器(bootstrap node),不过这台服务器所起的作用与Tracker不同,它仅负责接纳小赵进入A班,当小赵与A班中的同学“搭上了话”,之后这台服务器就没有什么用处了。bootstrap node可以是不同BT客户端厂商独立运营的,也可以是几家联合共用,总之,它是分散的,只要在客户端软件中内置一张表单,那客户端就将有非常多的入口可供选择。

第2章 工程实现

2.1 迅雷离线下载

如果用户要下载一些电影或者游戏资源,往往要长时间挂机,不仅浪费时间而且消耗大量的带宽。 离线下载其实就是下载工具的服务器代替用户先行下载,多用于冷门资源。
比如,用户的正常下载最大速度能达到200KB/S,但是某个资源是冷门资源,下载速度只能达到10KB/S,用户就得下很久,如果用户使用离线下载技术,就可以让服务商的服务器代替用户下载,用户就可以关掉下载工具或者机器,节约时间和电费。等到离线下好了,用户再从下载工具的服务器上以200KB/S的速度下到自己的电脑上。

操作过程:

(1)用户通过客户端或Web界面提交一个下载请求。
(2)迅雷公司服务器端接受请求,服务器首先查询用户提交的下载链接是否被下载过;如果没有,开启多线程实施下载(或用迅雷自己特有的P2P方式);如果有,直接把已下载的数据文件(或只是文件的链接)放入用户服务器端的在线空间。
(3)下载完成后,用户在线登录到在线空间,取回下载的文件。其间也可以采用迅雷自己的P2P方式,从已下载或正在下载相同文件的用户那里取得数据。

简单来说,就是如果要下载的资源已经存在于迅雷的服务器中,那么直接用P2P的方式从迅雷的服务器中取回。如果下载的资源尚未下载,那么可以将下载任务交由服务器代为完成。
下载文件的协议:HTTP、FTP、P2P

2.2 断点续传

断点续传的原理 其实断点续传的原理很简单

断点续传是一种结合本地存储和网络存储的技术,主要用来解决网络失效时的数据丢失问题。对于大文件传输,断点续传支持从文件上次中断的地方开始传送数据,而并非是从文件开头传送,这样可以保证数据传输的成功率及完整性。这就是断点续传的定义。

其实断点续传的原理很简单,就是在 Http 的请求上和一般的下载有所不同而已。

2.2.1 解决思路

打个比方,浏览器请求服务器上的一个文时,所发出的请求如下:
假设服务器域名为w,文件名为down.zip。

GET /down.zip HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, 
image/pjpeg, application/vnd.ms-excel, 
application/msword, application/vnd.ms-powerpoint, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
Connection: Keep-Alive

服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下:

200
Content-Length=106786028
Accept-Ranges=bytes
Date=Mon, 30 Apr 2001 12:56:11 
GMT ETag=W/“02ca57e173c11:95b”
Content-Type=application/octet-stream
Server=Microsoft-IIS/5.0
Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT

所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给Web服务器的时候要多加一条信息,从哪里开始。
下面是用自己编的一个“浏览器”来传递请求信息给 Web 服务器,要求从 2000070 字节开始。

GET /down.zip HTTP/1.0
User-Agent: NetFox
RANGE: bytes=2000070-
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

仔细看一下就会发现多了一行 RANGE: bytes=2000070-
这一行的意思就是告诉服务器 down.zip 这个文件从 2000070 字节开始传,前面的字节不用传了。
服务器收到这个请求以后,返回的信息如下:

206
Content-Length=106786028
Content-Range=bytes 2000070-106786027/106786028
Date=Mon, 30 Apr 2001 12:55:20 GMT
ETag=W/“02ca57e173c11:95b”
Content-Type=application/octet-stream
Server=Microsoft-IIS/5.0
Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT

和前面服务器返回的信息比较一下,就会发现增加了一行:

Content-Range=bytes 2000070-106786027/106786028

返回的代码也改为 206 了,而不再是 200 了。
知道了以上原理,就可以进行断点续传的编程了。

2.2.2 Java实现断点续传

(1) 用什么方法实现提交 RANGE: bytes=2000070-。
当然用最原始的 Socket 是肯定能完成的,不过那样太费事了,其实 Java 的 net 包中提供了这种功能。代码如下:

URL url = new URL(“”);
HttpURLConnection httpConnection
 = (HttpURLConnection)url.openConnection();
// 设置 User-Agent
httpConnection.setRequestProperty(“User-Agent”,“NetFox”);
// 设置断点续传的开始位置
httpConnection.setRequestProperty(“RANGE”,“bytes=2000070);
// 获得输入流
InputStream input = httpConnection.getInputStream();

从输入流中取出的字节流就是 down.zip 文件从 2000070 开始的字节流。 大家看,其实断点续传用 Java 实现起来还是很简单的吧。 接下来要做的事就是怎么保存获得的流到文件中去了。
保存文件采用的方法。
采用的是 IO 包中的 RandAccessFile 类。
操作相当简单,假设从 2000070 处开始保存文件,代码如下:

RandomAccess oSavedFile = new RandomAccessFile(“down.zip”,“rw”);
long nPos = 2000070;
// 定位文件指针到 nPos 位置
oSavedFile.seek(nPos);
byte[] b = new byte[1024];
int nRead;
// 从输入流中读入字节流,然后写到文件中
while((nRead=input.read(b,01024))0)
  {
  oSavedFile.write(b,0,nRead);
  }

第3章 下载软件

3.1 cURL

URL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。

本质上其可以支持各种http协议的操作方式,作为简单的http交互工具使用,由于多数时候已经集成在各种操作系统中,因此其作为下载器也是非常方便。

参考:curl

3.2 多线程下载器

3.2.1 Aria2

Aria2是一款免费开源跨平台且不限速的多线程下载软件,Aria2的优点是速度快、体积小、资源占用少;支持 HTTP / FTP / BT / Magnet磁力链接等类型的文件下载;支持 Win、Mac、Linux系统,甚至在树莓派、NAS、路由器等设备上都能安装它。
Aria2简介
Aria2是一个多平台轻量级,支持 HTTP、FTP、BitTorrent 等多协议、多来源的命令行下载工具。Aria2 可以从多个来源、多个协议下载资源,最大的程度上利用了你的带宽。Aria2 有着非常小的资源占用,在关闭磁盘缓存的情况下,物理内存占用通常为 4M(正常 HTTP/FTP 下载的情况下),BitTorrent 下载每秒2.8M/S的情况下,CPU 占有率约为 6%。Aria2 支持 JSON-RPC 和 XML-RPC 接口远程调用。
很多人在Windows可能用过 Internet Download Manager,是很好用的多线程下载工具。Aria2 跟 IDM 类似,不仅可以多线程下载,还可以通过多来源进行下载,简单的说就是从多个镜像服务器同时下载一个文件,Aria2 还支持 BT 协议,弥补了IDM只支持HTTP和FTP 的痛点。

3.2.2 下载 Aria2

Aria2 是一个命令行下载工具,所以使用的时候要敲命令,可是每下载一个文件敲一条命令。另外Aria2 支持远程接口调用,只需要配置一个 Web 管理面板就可以在浏览器管理 Aira2 了。

1 下载并解压Aria2主程序

可以直接去开源托管平台github上下载最新的程序。
网址:https://github.com/persepolisdm/persepolis/releases
这里有不同平台的压缩包,Windows下载 [win-32bit] 或者 [win-64bit],下载后解压,解压到剩余空间比较大的地方,不要解压在桌面。(建议自己新建一个文件夹进行解压)。

2 下载Aria2 配置文件

默认已经配置好了,如果需要更改配置,用记事本等文本编辑器,打开 aria2.conf ,根据aria2配置文件说明的文档进行修改。
dir=Download # 文件保存目录 ,默认下载到 Aria2 目录的 Download 文件夹。
disk-cache=32M # 硬盘缓存,默认 32M,作用是将数据缓存到内存中。
file-allocation=none # 文件预分配方式,配置文件有速度比较,具体看你的硬盘,机械硬盘用默认的none不进行预分配就好,固态硬盘可以选择falloc。
enable-rpc=true # 是否启用 RPC,RPC 是远程调用接口,开启:true,关闭:false。
#rpc-secret=mivm.cn # RPC 授权令牌,如果启用授权令牌,远程管理会要求输入令牌,去掉 # 即可启用,默认授权令牌:mivm.cn.
剩下的参数配置文件有注释,更多参数可以查阅官方文档。
修改完记得重启 Aria2

3 下载 Aria2 控制文件

Start.bat 带命令行窗口输出启动Aria2
Start.vbs 不带命令行窗口启动 Aria2
Stop.bat 停止 Aria2
Status.bat 查看 Aria2 进程状态
Restart.bat 重启 Aria2
Boot.bat 开启或取消Aria2开机启动
一般使用 Start.vbs 就可以了,第一次运行会出现防火墙警告,允许即可。
注:当你运行完“Start.vbs”,你就可以不管它了。

4 Web管理面板进行管理下载

aria2 WebUI管理网站。
http://aria2c.com/
可以通过配置,连接到本地到服务进行控制。

3.2.3 Aria2封装PDM

Persepolis Download Manager (简称 PDM) 是一款封装了 Aria2 作为内核,并为其套上图形界面的开源免费下载软件。它能让你享受 Aria2 一切的特性,同时又帮助你完全跳过安装和配置 Aria2 那些繁琐的过程,并且有一个图形化的直观界面供你用鼠标进行操作,你就像用迅雷、Folx 等下载工具一样的简单明了,而不必再对着命令行发愁。

3.2.4 Aria2封装Motrix

Motrix除了支持一般的http,https,ftp协议外,还支持BT与磁链,所以Motrix称得上是一个全能下载器[[[] Motrix-全能下载软件
https://zhuanlan.zhihu.com/p/437353580]]。
Motrix使用aria2作为内核,下载速度非常快。

3.2.5 多线程下载器 IDM

收费
它的全称是 Internet Download Manager(简称 IDM),向来被誉为是最强的下载神器。
而实际情况也的确如此,IDM 能够多线程下载文件从而提升下载速度,还可以自动嗅探下载网页视频,配合脚本还可以实现百度网盘不限速下载,超级实用。

3.2.6 多线程下载器

NDM
开源免费
Neat Download Manager(简称 NDM),它同样是一款多线程下载加速工具,能够用动态分段算法下载文件。它具有浏览器扩展,可以直接获取浏览器的下载链接和网站上下载视频、音频。

3.2.7 多线程下载器XDown

xdown torrent
免费无广告的idm / torrent 合成体。
专业的文件下载与分享工具(BitTorrent/HTTP/FTP)

Java安全漫谈是一本关于Java安全的书籍,深入探讨了Java应用程序在网络环境中的安全性和相关的安全漏洞。该书内容涵盖了Java安全基础、Java虚拟机的安全机制、Java安全管理、Java安全开发等方面的知识。 首先,Java安全基础部分介绍了Java安全模型的原理和特点,包括Java类库的安全特性、权限管理和访问控制、安全策略配置等。这部分内容可帮助开发人员了解Java应用程序的安全需求,并提供相应的解决方案。 其次,Java虚拟机的安全机制是Java应用程序的基石。该书介绍了Java虚拟机的安全沙箱和类加载机制,并讨论了如何利用这些安全机制避免恶意代码的执行和隐患的防范。 此外,Java安全管理部分从用户角度出发,介绍了Java应用程序的安全管理工具和技术,如Java安全策略文件、权限管理和安全认证等。开发人员可以通过合理配置和使用这些工具来提高Java应用程序的安全性。 最后,该书还涉及了Java安全开发过程中的一些最佳实践和常见安全漏洞,如输入验证、跨站脚本攻击(XSS)、SQL注入、跨站请求伪造(CSRF)等。通过学习和掌握这些知识,开发人员可以编写出更加安全的Java应用程序。 总而言之,Java安全漫谈是一本全面讨论Java安全的书籍,内容涵盖了Java安全基础、Java虚拟机的安全机制、Java安全管理和Java安全开发等方面的知识。它对于开发人员和安全从业人员来说,都是一本重要的参考书,有助于提高Java应用程序的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值