TCP/IP协议学习

一、TCP/IP协议概述

TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WAN)设计的。它是由ARPANET网的研究机构发展起来的。图1是OSI模型和TCP/IP协议模型的对比。

图1  OSI模型和TCP/IP协议模型

(1)网络接口层

  TCP/IP协议模型的基层,负责数据帧的发送和接收。对应OSI模型中的物理层和数据链路层,是TCP/IP的最底层,不过通常在描述TCP/IP模型时还是会划分具体为物理层(PHY)和数据链路层(MAC)。

(2)网络层

  通过互联协议将数据包封装成互联网数据包,并运行必要的路由算法。这里有4种互联协议。

  (a)网际协议IP:负责在主机和网络之间的路径寻址和数据包路由。

  (b)地址解析协议ARP:获得同一物理网络中的主机硬件地址。

  (c)网际控制消息协议ICMP:发送消息,并报告有关数据包的传送错误。

  (d)互联组管理协议IGMP:用来实现本地多路广播路由器报告。

(3)传输层

  传输协议在主机之间提供通信会话。传输协议的选择根据数据传输方式而定。主要有以下2种传输协议:

  (a)传输控制协议TCP:为应用程序提供可靠的通信连接,适用于要求得到响应的应用程序。

  (b)用户数据包协议UDP:提供无连接通信,且不对传输包进行可靠性确认。

(4)应用层

  应用程序通过这一层访问网络,主要包括常见的FTP、HTTP、DNS和TELNET协议。

 

二、TCP协议(Transmission Control Protocol)

1.概述

应用程序通过打开一个socket来使用TCP服务。

2.连接管理

(1)连接建立——3次握手协议

在TCP中建立连接采用三次握手的方法。为了建立连接,其中一方,如服务器,通过执行LISTEN和ACCEPT原语被动地等待一个到达的连接请求。

另一方,如客户方,执行CONNECT原语,同时要指明它想连接到的IP地址和端口号,设置它能够接受的TCP数据报的最大值,以及一些可选的用户数据。CONNECT原语发送一个SYN=1,ACK=0的数据报到目的端,并等待对方响应。

该数据报到达目的端后,那里的TCP实体将察看是否有进程在侦听目的端口字段指定的端口。如果没有,它将发送一个RST=1的应答,拒绝建立该连接。

如果某个进程正在对该端口进行侦听,于是便将到达的TCP数据报交给该进程,它可以接受或拒绝建立连接。如果接受,便发回一个确认数据报。一般情况下,TCP的连接建立过程如图2所示。

 

图2   TCP 3次握手协议

 

(2)释放连接——2个方向,4个数据报

为了释放连接,每方均可发送一个FIN=1的TCP数据报,表明本方已无数据发送。当FIN数据报被确认后,那个方向的连接即告关闭。当两个方向上的连接均关闭后,该连接就被完全释放了。一般情况下,释放一个连接需要4个TCP数据报:每个方向均有一个FIN数据报和一个ACK数据报

 

3 传输策略——滑动窗口

TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为0时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个1字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。

 

4 拥塞控制——两个窗口

当加载到某个网络上的载荷能力超过其处理能力时,便会出现拥塞现象。对于因特网来说有两个潜在的问题--网络的容量和接收方的容量,应该分别进行处理。发送方始终保持两个窗口:接收方承认的窗口拥塞窗口。取两个窗口的最小值作为可以发送的字节数。

当建立连接时,发送方将拥塞窗口大小初始化为该连接所用的最大数据报的长度值,并随后发送一个最大长度的数据报。如果该数据报在定时器超时之前得到了确认,那么发送方会在原拥塞窗口的基础上再增加一个数据报的字节值,使其为两倍最大数据报的大小,然后发送两个数据报。当这些数据报中的每一个都被确认后,拥塞窗口大小就再增加一个最大数据报的长度。当拥塞窗口是N个数据报的大小时,如果发送的所有N个数据报都被及时确认,那么将拥塞窗口大小增加N个数据报对应的字节数目。拥塞窗口保持指数规律增大,直到数据传输超时或者达到接收方设定的窗口大小。拥塞窗口便设置为恰好不造成超时或达到接收方的窗口大小的字节数。

 

5 定时器管理——重发定时器、持续定时器

TCP使用多个定时器,如重发定时器、持续定时器、"keep alive"定时器等。最重要的是重发定时器。在发送一个数据报的同时,启动一个数据重发定时器。如果在定时器超时前该数据报被确认,则关闭该定时器;相反,如果在确认到达之前定时器超时,则需要重发该数据报。

持续定时器用于防止出现死锁情况。当一个连接长时间闲置时,"keep alive"定时器会超时而使一方去检测另一方是否仍然存在。如果它未得到响应,便终止该连接。

 

6.TCP数据报头

TCP数据包头如下图3所示:

图3   TCP协议数据报头

 

7.报头内容

源端口、目的端口:16位长。标识出远端和本地的端口号。

顺序号:32位长。表明了发送的数据报的顺序。

确认号:32位长。希望收到的下一个数据报的序列号。

TCP头长:4位长。表明TCP头中包含多少个32位字。

接下来的6位未用。

ACK:ACK位置1表明确认号是合法的。如果ACK为0,那么数据报不包含确认信息,确认字段被省略。

PSH:表示是带有PUSH标志的数据。接收方因此请求数据报一到便可送往应用程序而不必等到缓冲区装满时才传送。

RST:用于复位由于主机崩溃或其它原因而出现的错误的连接。还可以用于拒绝非法的数据报或拒绝连接请求。

SYN:用于建立连接。

FIN:用于释放连接。

窗口大小:16位长。窗口大小字段表示在确认了字节之后还可以发送多少个字节。

校验和:16位长。是为了确保高可靠性而设置的。它校验头部、数据和伪TCP头部之和。

可选项:0个或多个32位字。包括最大TCP载荷,窗口比例、选择重发数据报等选项。

最大TCP载荷:允许每台主机设定其能够接受的最大的TCP载荷能力。在建立连接期间,双方均声明其最大载荷能力,并选取其中较小的作为标准。如果一台主机未使用该选项,那么其载荷能力缺省设置为536字节。

窗口比例:允许发送方和接收方商定一个合适的窗口比例因子。这一因子使滑动窗口最大能够达到232字节。

选择重发数据报:这个选项允许接收方请求发送指定的一个或多个数据报。

 

8.包头分析实例——20个字节

TCP包头占有20个字节,即:

0d 28 00 15 37 8d 49 3b 00 46 74 e0 50 18 fe d9 ea f7 00 00

注:每一数字代表一个16进制数,就是4位。2个数字代表8位,即一个字节。

  (1) “0d 28”,表示本地端口号,转换为十进制就是3368。

  (2) “00 15”,表示目标端口号,转换为十进制就是23,因为我是连接TELNET站点,所以,这个就是23。

  (3) “37 8d 49 3b”,是顺序号(Sequence Number),简写为SEQ。

  (4) “00 46 74 e0”,是确认号(Acknowledgment Number),简写为ACKNUM。

  (5) “50 18”,转换为二进制,“0101 0000 0001 1000”。这两个字节,总共16bit,有好多东西。第一个4bit“0101”,是TCP头长,十进制为5,表示(5个32比特,字节数即为5*4)20个字节。接着的6bit现在TCP协议没有用上,都为0。最后的6bit“01 1000”是六个重要的标志。这是两个计算机数据交流的信息标志。接收和发送断根据这些标志来确定信息流的种类。下面是一些介绍: 

  URG:(Urgent Pointer field significant)紧急指针。用到的时候值为1,用来处理避免TCP数据流中断。

  ACK:(Acknowledgment fieldsignificant)置1时表示确认号(AcknowledgmentNumber)为合法,为0的时候表示数据段不包含确认信息,确认号被忽略。

  PSH:(Push Function),PUSH标志的数据,置1时请求的数据段在接收方得到后就可直接送到应用程序,而不必等到缓冲区满时才传送。

  RST:(Reset the connection)用于复位因某种原因引起出现的错误连接,也用来拒绝非法数据和请求。如果接收到RST位时候,通常发生了某些错误。 

  SYN:(Synchronize sequence numbers)用来建立连接,在连接请求中,SYN=1,ACK=0连接响应时,SYN=1,ACK=1。即,SYN和ACK来区分Connection Request和Connection Accepted。 

  FIN:(No more data from sender)用来释放连接,表明发送方已经没有数据发送了。 

  这6个标志位,对号入座。本例中SYN=0,ACK=1,当然就是表示连接请求了。在分析TCP包头时候,要注意这两位的变换。 

  (6) “fe d9”,窗口大小,用来控制实现流量控制。

(7) “ea f7”,校验和,TCP的检验和是强制的。

(8) “00 00”,紧急指针。

按图3,TCP协议数据报头的格式最后还有可选项,这里的报头里不包含。

 

三、UDP协议(user data protocol)

1.概述

因特网协议组也支持无连接的传输协议UDP(user data protocol)。 UDP使用底层的因特网协议来传送报文,提供与IP一样的不可靠的、无连接的数据报传输服务。它不使用确认信息对报文的到达进行确认,不对收到的数据报进行排序,也不提供反馈信息来控制机器之间传输的信息流量。UDP通信的可靠性方面的工作,包括报文的丢失、重复、乱序等现象,由使用UDP的应用程序来承担。

 

2.UDP报头

一个UDP数据报包括一个8字节的头和数据部分。报头的格式如下图4所示,它包括四个长为16字节的字段。

(1)源端口和目的端口:作用与TCP中的相同,是用来标明源端和目的端的端口号。

(2)UDP长度字段:指明包括8个字节的头和数据在内的数据报长度。

(3)UDP校验和字段:可选项,用于纪录 UDP头、UDP伪头、用户数据三者的校验和。

 

图4  UDP数据报头格式

 

四、IP协议

1.概述——屏蔽底层细节

IP协议提供了不可靠的、无连接的数据报传输机制。TCP/IP是为了适应物理网络的多样性而设计的,而这种适应性主要是通过IP层来体现的。由于物理网络的多样性,各种物理网络的数据帧格式、地址格式之间的差异很大。为了将这些底层的细节屏蔽起来,使得采用不同物理网络的网络之间进行通讯, TCP/IP分别采用了IP数据报和IP地址作为物理数据帧与物理地址的统一描述形式。这样IP向上层提供统一的IP数据报和统一的IP地址,使得各种物理帧及物理地址的差异性对上层协议不复存在。

 

2.IP数据报头——20字节固定长度部分+可选任意长度部分

一个IP数据报由一个头部和数据部分构成。头部包括一个20字节的固定长度部分和一个可选任意长度部分。头部格式如图5所示。

 

图5   IP数据报头

版本:4位长。记录了数据报对应的协议版本号。当前的IP协议有两个版本:IPV4 和IPV6。

IHL:4位长。代表头部的总长度,以32位字节为一个单位。

服务类型:8位长。使主机可以告诉子网它想要什么样的服务。如下图所示,服务类型域又分为了5个部分。优先权字段是标志优先级的;三个标志位分别代表延迟、吞吐量、可靠性。

 

图6   服务类型的5个部分

总长:16位。指头部和数据的总长。最大长度是65535个字节。

标识:16位。通过它使目的主机判断新来的分段属于哪个分组,所有属于同一分组的分段包含同样的标识值。

DF:代表不要分段。它命令路由器不要将数据报分段,因为目的端不能重组分段。

MF:代表还有进一步的分段,用它来标志是否所有的分组都已到达。除了最后一个分段的所有分段都设置了这一位。

分段偏移:13位。标明分段在当前数据报的什么位置。

生命期:8位。用来限制分组生命周期的计数器。它在每个节点中都递减,而且当在一个路由器中排队时可以倍数递减。

协议:8位。说明将分组发送给那个传输进程,如TCR、VDP等。

头校验和:16位。仅用来校验头部。

源地址: 32位。产生IP数据报的源主机IP地址。

目的地址:32位。IP数据报的目的主机的IP地址。

可选项:是变长的。每个可选项用一个字节标明内容。有些可选项还跟有一字节的可选项长度字段,其后是一个或多个数据字节。现在已定义了安全性、严格的源路由选择、松的源路由选择、记录路由和时间标记五个可选项。但不是所有的路由器都支持全部5个可选项。

安全性选项说明了信息的安全程度。

严格的源路由选择选项以一系列的IP地址方式,给出了从源到目的地的完整路径。数据报必须严格地从这条路径传送。当路由选择表崩溃,系统管理员发送紧急分组时,或作时间测量时,此字段很有用。

松的源路由选择选项要求分组遍及所列的路由器,但它可以在其间穿过其它的路由器。

记录路由选项让沿途的路由器都将其IP地址加到可选字段之后,这使系统管理者可以跟踪路由选择算法的错误。

时间标记选项像记录路由选项一样,除了记录32位的IP地址外,每个路由器还要记录一个32位的时间标记。同样地,这一选择可用来为路由选择算法查错。

 

3.  IP数据报的分段与重组——当在两个不同MTU(最大传输单元)网络之间传输时

IP数据报是通过封装为物理帧来传输的。由于因特网是通过各种不同物理网络技术互连起来的,在因特网的不同部分,物理帧的大小(最大传输单元MTU)可能各不相同。为了最大程度的利用物理网络的能力,IP模块以所在的物理网络的MTU做为依据,来确定IP数据报的大小。当IP数据报在两个不同MTU的网络之间传输时,就可能出现IP数据报的分段与重组操作。

在IP头中控制分段和重组的IP头域有三个:标识域、标志域、分段偏移域。

◆标识是源主机赋予IP数据报的标识符。目的主机根据标识域来判断收到的IP数据报分段属于哪一个数据报,以进行IP数据报重组。

◆标志域中的DF位标识该IP数据报是否允许分段。当需要对IP数据报进行分段时,如果DF位置1,网关将会抛弃该IP数据报,并向源主机发送出错信息。

◆标志域中的MF位标识该IP数据报分段是否是最后一个分段。

◆分段偏移域记录了该IP数据报分段在原IP数据报中的偏移量。偏移量是8字节的整数倍。分段偏移域被用来确定该IP数据报分段在IP数据报重组时的顺序。

IP数据报在被传输过程中,一旦被分段,各段就作为独立的IP数据报进行传输,在到达目的主机之前有可能会被再次或多次分段。但是IP数据报分段的重组都只在目的主机进行。

 

4.  IP对输入数据报的处理——主机、网关

IP对输入数据报的处理分为两种,一种是主机对数据报的处理,一种是网关对数据报的处理。

◆主机: 当IP数据报到达主机时,如果IP数据报的目的地址与主机地址匹配,IP接收该数据报并将它传给高级协议软件处理;否则抛弃该IP数据报。

◆网关: 网关则不同,当IP数据报到达网关IP层后,网关首先判断本机是否是数据报到达的目的主机。如果是,网关将接收到的IP数据报上传给高级协议软件处理。如果不是,网关将对接收到的IP数据报进行寻径,并随后将其转发出去。

主要区别在于不匹配的时候,对IP数据报的处理。主机是抛弃,网关是转发。

 

5.  IP对输出数据报的处理——主机、网关

IP对输出数据报的处理也分为两种,一种是主机对数据报的处理,一种是网关对数据报的处理。

对于网关来说,IP接收到IP数据报后,经过寻径,找到该IP数据报的传输路径。该路径实际上是全路径中的下一个网关的IP地址。然后,该网关将该IP数据报和寻径到的下一个网关的地址交给网络接口软件。网络接口软件收到IP数据报和下一个网关地址后,首先调用ARP完成下一个网关IP地址到物理地址的映射,然后将IP数据报封装成帧,最后由子网完成数据报的物理传输。

 

6.  ICMP协议——差错信息、控制信息的构造、某些网络信息的获取

ICMP(Internet Control Message Protocol)-因特网控制报文协议。ICMP主要用于差错信息和控制信息的构造及某些网络信息的获取。ICMP与IP 同属IP层,但ICMP报文是经IP封装后,作为IP数据报发送出去的。不把ICMP作为一个独立的协议层次,是因为ICMP不是上层协议的基础,在概念上构不成一个独立的层次。

ICMP消息包括以下类型:目的不可达、超时、参数问题、源端抑制、重定向、回声请求、回声应答、时间标记请求、时间标记应答。

目的不可达消息:报告子网/路由器不能定位目的地,或设置了DF位的分组不能绕过"小分组"网络。

超时消息:报告报文由于计时器为零而被丢弃。

参数问题消息:表明在头部字段中发现了非法值。

源端抑制消息:抑制发送过多分组的主机。当主机收到这个消息,就要减慢发送速度。

重定向消息:在路由器发现可能出现了路由错误时发送。

回声请求和回声应答消息:测试目的是否可达且正常运行。收到回声请求消息,目的端应该往回发一个回声应答消息。时间标记请求和时间标记应答与此类似,只是消息到达时间和应答发出时间应加入应答中,其好处是可以用来测试网络性能。

 

7. IP在Linux上的实现

如图7所示,Linux以分层的软件结构实现了TCP/IP协议。

BSD套接字:由一般性的套接字管理软件INET套接字层支持。

INET套接字:管理基于IP的TCP或UDP协议端。

UDP:在传输UDP数据报时,Linux不必关心数据报是否安全到达目的端。

TCP:对TCP数据报来说,Linux需要对数据报进行编号,数据报的源端和目的端需要协调工作,以便保证数据报不会丢失,或以错误的顺序发送。

IP层:包含的代码需要处理数据报的报头信息,并且必须将传入的数据报发送到TCP或 UDP两者中正确的一层处理。

网络设备层:在IP层之下是Linux的网络设备层,其中包括以太网设备或PPP设备等。和Linux系统中的其它设备不同,网络设备并不总代表实际的物理设备,例如,回环设备就是一个纯软件设备。

ARP协议:提供地址解析功能,因此它处于IP层和网络设备层之间。

各层的在源码中的位置

BSD socket层:这一部分处理BSD socket相关操作,每个socket在内核中以struct socket结构体现。

这一部分的文件主要有:/net/socket.c /net/protocols.c etc

INET socket层:BSD socket是个可以用于各种网络协议的接口,而当用于tcp/ip,即建立了AF_INET形式的socket时,还需要保留些额外的参数,于是就有了struct sock结构。

文件主要有:/net/ipv4/protocol.c /net/ipv4/af_inet.c /net/core/sock.c etc

TCP/UDP层:处理传输层的操作,传输层用struct inet_protocol和struct proto两个结构表示。

文件主要有:/net/ipv4/udp.c /net/ipv4/datagram.c /net/ipv4/tcp.c /net/ipv4/tcp_input.c

        /net/ipv4//tcp_output.c /net/ipv4/tcp_minisocks.c /net/ipv4/tcp_output.c

        /net/ipv4/tcp_timer.c etc 

IP层:处理网络层的操作,网络层用struct packet_type结构表示。

文件主要有:/net/ipv4/ip_forward.c ip_fragment.c ip_input.c ip_output.c etc.

数据链路层和驱动程序:每个网络设备以struct net_device表示,通用的处理在dev.c中,驱动程序都在/driver/net目录下。

 

图7  Linux网络分层结构图

 

7.1 套接字缓冲区——在协议层和网络设备之间传送数据

Linux利用套接字缓冲区在协议层和网络设备之间传送数据。Sk_buff包含了一些指针和长度信息,从而可让协议层以标准的函数或方法对应用程序的数据进行处理。如图8所示,每个sk_buff均包含一个数据块、四个数据指针以及两个长度字段。利用四个数据指针,各协议层可操纵和管理套接字缓冲区的数据,这四个指针的用途如下。

Head:指向内存中数据区的起始地址。Sk_buff和相关数据块在分配之后,该指针的值是固定的。

Data:指向协议数据的当前起始地址。该指针的值随当前拥有Sk_buff的协议层的变化而变化。

Tail:指向协议数据的当前结尾地址。和data指针一样,该指针的值也随当前拥有Sk_buff的协议层的变化而变化。

End:指向内存中数据区的结尾。和head指针一样,Sk_buff被分配之后,该指针的值也固定不变。

(Head和End对应,Data和Tail对应)

Sk_buff的两个长度字段,len和truesize,分别描述当前协议数据报的长度和数据缓冲区的实际长度。

 

图8  sk_buff的结构

 

7.2 接收IP数据报——backlog队列、哈希表

当网络设备从网络上接收到数据报时,它必须将接收到的数据转换为sk_buff数据结构,然后将该结构添加到backlog队列中排队。当backlog队列变得很大时,接收到的sk_buff数据将会被丢弃。当新的sk_buff添加到backlog队列时,网络底层程序将被标志为就绪状态,从而可以让调度程序调度底层程序进行处理。

调度程序最终会运行网络的底层处理程序。这时,网络底层处理程序将处理任何等待传输的数据报,但在这之前,底层处理程序首先会处理sk_buff结构的backlog队列。底层处理程序必须确定将接收到的数据报传递到哪个协议层。

在Linux进行网络层的初始化时,每个协议要在ptype_all链表或ptype_base哈希表中添加packet_type数据结构以进行注册。Packet_type数据结构包含协议类型、指向网络设备的指针、指向协议的接收数据处理例程的指针等。Ptype_base是一个哈希表,其哈希函数以协议标识符为参数,内核通常利用该哈希表判断应当接受传入的网络数据报的协议。通过检查ptype_all链表和ptype_base哈希表,网络底层处理程序会复制新的sk_buff,最终,sk_buff会传递到一个或多个目标协议的处理例程。

 

7.3 发送IP 数据报——路由解析

网络处理代码必须建立sk_buff来包含要传输的数据,并且在协议层之间传递数据时,需要添加不同的协议头和协议尾

首先,IP协议需要决定要使用的网络设备,网络设备的选择依赖于数据报的最佳路由。

对于只利用调制解调器和PPP协议连接的计算机来说,路由的选择比较容易。

对于连接到以太网的计算机来说,路由的选择是比较复杂的。

对每个要传输的IP数据报,IP利用路由表解析目标IP地址的路由。对每个可从路由表中找到路由的目标IP地址,路由表返回一个rtable数据结构描述可使用的路由。这包括要使用的源地址、网络设备的device数据结构的地址以及预先建立的硬件头信息。该硬件头信息和网络设备相关,包含了源和目标的物理地址以及其它的介质信息。

 

7.4 数据报的分段与重组

当传输IP数据报时,IP从IP路由表中找到发送该IP数据报的网络设备,网络设备对应的device数据结构中包含由一个mtu字段,该字段描述最大的传输单元。如果设备的mtu小于等待发送的IP数据报的大小,就需要将该IP数据报划分为小的片断。

每个片断由一个sk_buff代表,其中的IP头标记为数据报片断,以及该片断在IP数据报中的偏移。最后的数据报被标志为最后的IP片断。如果分段过程中IP不能分配sk_buff,则传输失败。

IP片断的接收较片断的发送更加复杂一些,因为IP片断可能以任意的顺序接收到,而在重组之前,必须接受到所有的片断。每次接收到IP数据报时,IP 要检查是否是一个分段数据报。当第一次接收到分段的消息时,IP建立一个新的ipq数据结构,并将它链接到由等待重组的IP片断形成的ipqueue链表中。随着其他IP片断的接收,IP找到正确的ipq数据结构,同时建立新的ipfrag数据结构描述该片断。每个ipq数据结构中包含有其源和目标IP地址、高层协议的标识符以及该IP帧的标识符,从而唯一描述了一个分段的IP接收帧。当所有的片断接收到之后,它们被组合成单一的sk_buff并传递到上一级协议层处理。如果定时器在所有的片断到达之前到期,ipq数据结构和ipfrag被丢弃,并假定消息已经在传输中丢失,这时,高层协议需要请求源主机重新发送丢失的信息。

转载于:https://www.cnblogs.com/xufenghfut/archive/2012/09/06/2673079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值