NS-3例程注解与拓展

准备

运行准备

要运行自己的脚本,只需把脚本放到scratch目录下,通过waf脚本就会被编译。

cp examples/tutorial/first.cc scratch/myfirst.cc

使用waf命令来编译自己的第一个实例脚本:

sudo ./waf

运行这个例子

sudo ./waf --run scratch/myfirst

本文均在代码中加入输出XMl文件相应的语句,从而利用NetAnim生成可视化的动画。

在这里插入代码片

概览

NS-3给出的例程在 XXX 目录中,其中first-third.cc均是关于构建网络拓扑结构的。
其中:

  • first 是 :点到点的网络模型(P + P)
  • second 是 :点到以太网的网络模型 (P + LAN )
  • third:是 :WIFI到以太网的网络模型 (WIFI + LAN)

最后我自己给出的网络则是:

  • myfourth.cc:是 :以太网到以太网的网络模型 ( LAN + LAN)

分析

first.cc

网络拓扑如下:
// Default Network Topology
//
//       10.1.1.0
// n0 -------------- n1  
//    point-to-point  
//                    
// 
源码分析:
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/netanim-module.h"


using namespace ns3;

// 定义一个日志组件
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

int
main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);
  
  //设置时间精度,只能设置一次,因为动态设置对内存需求大,
  //因此一旦设置,就会释放内存,如果不设置,使用默认值ns(纳秒)
  Time::SetResolution (Time::NS);
  
  // 使两个日志组件生效,内置在EchoClient和EchoServer应用中
  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

  // 创建节点对象,并且在内部存储Node对象指针
  NodeContainer nodes;
  nodes.Create (2);

  // 设置网络设备和信道属性
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));


  NetDeviceContainer devices; 
  // install方法将设备安装到节点中
  //在NodeContainer中的每一个Node创建一个PointToPointNetDevice,
  devices = pointToPoint.Install (nodes);
   

  // ***为计算机每个node中安装协议栈
  InternetStackHelper stack;
  stack.Install (nodes);

  Ipv4AddressHelper address; // 声明了一个地址助手对象
  address.SetBase ("10.1.1.0", "255.255.255.0"); //从10.1.1.0 开始 以子网掩码为 255.255.255.0 分配地址

  //ns-3中使用interface来在device及IP地址间建立关联
  Ipv4InterfaceContainer interfaces = address.Assign (devices); // 完成了真正的地址配置
  

  // ***下面安装应用层
  UdpEchoServerHelper echoServer (9); // 服务器端

  ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
  serverApps.Start (Seconds (1.0)); // echoServer 在 1s 时开始 
  serverApps.Stop (Seconds (10.0)); //echoServer 在 10s时结束,可选可不选

  UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);//使用Node1的地址及端口号(9)初始化辅助对象
  echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); // 能发送的最大数据分组个数
  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); // 两个数据分组之间要等的时间
  echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); // 每个数据分组的大小

  ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
  clientApps.Start (Seconds (2.0));//同上,开始时间
  clientApps.Stop (Seconds (10.0));


  // 以下三行用于生成可视化文件
  AnimationInterface anim("first.xml"); //
  anim.SetConstantPosition(nodes.Get(0), 1.0, 2.0);
  anim.SetConstantPosition(nodes.Get(1), 2.0, 3.0);
  
  Simulator::Run (); // 启动模拟器
  Simulator::Destroy (); // 销毁任务
  return 0;
}

second.cc

网络拓扑如下:
> // Default Network Topology
//
//       10.1.1.0
// n0 -------------- n1   n2   n3   n4
//    point-to-point  |    |    |    |
//                    ================
//                      LAN 10.1.2.0
源码分析:
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"

using namespace ns3;

// 定义一个日志组件
NS_LOG_COMPONENT_DEFINE("SecondScriptExample");

int main(int argc, char* argv[])
{
	bool verbose = true; // 用来决定是否开启日志组件
	uint32_t nCsma = 3; // 定义csma网络中有多少个节点

	CommandLine cmd;
	cmd.AddValue("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
	cmd.AddValue("verbose", "Tell echo applications to log if true", verbose);

	cmd.Parse(argc, argv);

	if (verbose) // 开启日志的情况下
	{
		LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
		LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
	}

	nCsma = nCsma == 0 ? 1 : nCsma; //csma中最少一个节点

	//创建p2p的两个节点
	NodeContainer p2pNodes;
	p2pNodes.Create(2);

	//创建csma的网络节点
	NodeContainer csmaNodes;
	csmaNodes.Add(p2pNodes.Get(1)); // p2p的一号节点加入csma作为接入点
	csmaNodes.Create(nCsma);

	// 设置p2p的传输速率及延迟
	PointToPointHelper pointToPoint;
	pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
	pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));

	// p2p节点安装网卡
	NetDeviceContainer p2pDevices;
	p2pDevices = pointToPoint.Install(p2pNodes);

	// 设置csma的传输速率及延迟
	// 注意传输速率有channel指定,而非device属性。(CSMA不允许同一信道上有多个不同数据率的设备)
	CsmaHelper csma;
	csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
	csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560)));

	// csma节点安装网卡
	NetDeviceContainer csmaDevices;
	csmaDevices = csma.Install(csmaNodes);

	// 安装协议栈
	InternetStackHelper stack;
	stack.Install(p2pNodes.Get(0)); // p2p的0号节点安装
	stack.Install(csmaNodes); //p2p的1号节点包含在csma中一起安装

	Ipv4AddressHelper address;// 声明了一个地址助手对象
	address.SetBase("10.1.1.0", "255.255.255.0");//从10.1.1.0 开始 以子网掩码为 255.255.255.0 分配地址
	Ipv4InterfaceContainer p2pInterfaces;
	p2pInterfaces = address.Assign(p2pDevices);// 完成了p2p真正的地址配置

	address.SetBase("10.1.2.0", "255.255.255.0");//从10.1.2.0 开始 以子网掩码为 255.255.255.0 分配地址
	Ipv4InterfaceContainer csmaInterfaces;
	csmaInterfaces = address.Assign(csmaDevices);// 完成了csma真正的地址配置

	 // ***下面安装应用层
	UdpEchoServerHelper echoServer(9);// 服务器端 port为9
	// 将server服务器安装在CSMA的最后一个节点上即n4
	ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma));
	serverApps.Start(Seconds(1.0));// echoServer 在 1s 时开始 
	serverApps.Stop(Seconds(10.0));//echoServer 在 10s时结束

	UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9);//设定远程服务器的IP地址和Port
	echoClient.SetAttribute("MaxPackets", UintegerValue(1));// 能发送的最大数据分组个数
	echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0))); // 两个数据分组之间要等的时间
	echoClient.SetAttribute("PacketSize", UintegerValue(1024)); // 每个数据分组的大小

	// 将client服务器安装在p2p的第一个节点上即n0
	ApplicationContainer clientApps = echoClient.Install(p2pNodes.Get(0));
	clientApps.Start(Seconds(2.0));
	clientApps.Stop(Seconds(10.0));

	// 建立网络路由
	Ipv4GlobalRoutingHelper::PopulateRoutingTables();

	//开启p2pHelper,csmaHelper类对象的pcap追踪
	pointToPoint.EnablePcapAll("second"); //
	csma.EnablePcap("second", csmaDevices.Get(1), true);

	Simulator::Run(); // 启动模拟器
	Simulator::Destroy();
	return 0;
}

third.cc

网络拓扑如下:
// Default Network Topology
//
//   Wifi 10.1.3.0
//                 AP
//  *    *    *    *
//  |    |    |    |    10.1.1.0
// n5   n6   n7   n0 -------------- n1   n2   n3   n4
//                   point-to-point  |    |    |    |
//                                   ================
//                                     LAN 10.1.2.0
源码分析:
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/ssid.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE("ThirdScriptExample");

int main(int argc, char* argv[])
{
	bool verbose = true; // 用来决定是否开启日志组件
	uint32_t nCsma = 3; // 定义csma网络中有多少个节点
	uint32_t nWifi = 3; // 定义WIFI网络中有多少个节点
	bool tracing = false;

	CommandLine cmd;
	cmd.AddValue("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
	cmd.AddValue("nWifi", "Number of wifi STA devices", nWifi);
	cmd.AddValue("verbose", "Tell echo applications to log if true", verbose);
	cmd.AddValue("tracing", "Enable pcap tracing", tracing);

	cmd.Parse(argc, argv);

	// The underlying restriction of 18 is due to the grid position
	// allocator's configuration; the grid layout will exceed the
	// bounding box if more than 18 nodes are provided.
	if (nWifi > 18)
	{
		std::cout << "nWifi should be 18 or less; otherwise grid layout exceeds the bounding box" << std::endl;
		return 1;
	}

	if (verbose)
	{
		LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
		LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
	}

	//创建p2p链路2个节点
	NodeContainer p2pNodes;
	p2pNodes.Create(2);

	// 设置p2p的传输速率及延迟
	PointToPointHelper pointToPoint;
	pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
	pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));

	// p2p节点安装网卡
	NetDeviceContainer p2pDevices;
	p2pDevices = pointToPoint.Install(p2pNodes);

	//创建csma的网络节点
	NodeContainer csmaNodes;
	csmaNodes.Add(p2pNodes.Get(1));// p2p的一号节点加入csma作为接入点
	csmaNodes.Create(nCsma);

	// 设置csma的传输速率及延迟
	CsmaHelper csma;
	csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
	csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560)));

	// csma节点安装网卡
	NetDeviceContainer csmaDevices;
	csmaDevices = csma.Install(csmaNodes);

	//创建WIFI的网络节点
	NodeContainer wifiStaNodes;
	wifiStaNodes.Create(nWifi);
	NodeContainer wifiApNode = p2pNodes.Get(0);//设置wifi的AP(无线接入点)为p2p的第一个节点


	//配置PHY和Channel通道助手
	YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
	YansWifiPhyHelper phy = YansWifiPhyHelper::Default();
	phy.SetChannel(channel.Create());//Channel对象与PHY对象关联

	//MAC层配置
	WifiHelper wifi;
	wifi.SetRemoteStationManager("ns3::AarfWifiManager");//使用AARF速率控制算法

	WifiMacHelper mac;
	Ssid ssid = Ssid("ns-3-ssid");
	mac.SetType("ns3::StaWifiMac",
		"Ssid", SsidValue(ssid),
		"ActiveProbing", BooleanValue(false));

	NetDeviceContainer staDevices;//STA 网络设备
	staDevices = wifi.Install(phy, mac, wifiStaNodes);//wifi的STA安装PHY层和MAC层

	//配置wifi网络AP网络设备的MAC类型和基础设施网络的SSID
	mac.SetType("ns3::ApWifiMac",
		"Ssid", SsidValue(ssid));

	NetDeviceContainer apDevices;
	apDevices = wifi.Install(phy, mac, wifiApNode);//与STA共同的PHY特性

	MobilityHelper mobility;//移动模型

	 //网格位置分配器
	mobility.SetPositionAllocator("ns3::GridPositionAllocator",
		"MinX", DoubleValue(0.0),
		"MinY", DoubleValue(0.0),
		"DeltaX", DoubleValue(5.0),
		"DeltaY", DoubleValue(10.0),
		"GridWidth", UintegerValue(3),
		"LayoutType", StringValue("RowFirst"));

	mobility.SetMobilityModel("ns3::RandomWalk2dMobilityModel",//以随机游走的方式移动
		"Bounds", RectangleValue(Rectangle(-50, 50, -50, 50)));
	mobility.Install(wifiStaNodes);//安装到wifi网络的STA

	mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
	mobility.Install(wifiApNode);//安装到wifi网络的AP

	 //安装协议栈
	InternetStackHelper stack;
	stack.Install(csmaNodes);
	stack.Install(wifiApNode);
	stack.Install(wifiStaNodes);

	Ipv4AddressHelper address;

	address.SetBase("10.1.1.0", "255.255.255.0");
	Ipv4InterfaceContainer p2pInterfaces;
	p2pInterfaces = address.Assign(p2pDevices);

	address.SetBase("10.1.2.0", "255.255.255.0");
	Ipv4InterfaceContainer csmaInterfaces;
	csmaInterfaces = address.Assign(csmaDevices);

	address.SetBase("10.1.3.0", "255.255.255.0");
	address.Assign(staDevices);
	address.Assign(apDevices);

	//安装应用
	UdpEchoServerHelper echoServer(9);

	ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma));
	serverApps.Start(Seconds(1.0));
	serverApps.Stop(Seconds(10.0));

	UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9);
	echoClient.SetAttribute("MaxPackets", UintegerValue(1));
	echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0)));
	echoClient.SetAttribute("PacketSize", UintegerValue(1024));

	ApplicationContainer clientApps =
		echoClient.Install(wifiStaNodes.Get(nWifi - 1));//在随后建立的wifi STA上安装客户机
	clientApps.Start(Seconds(2.0));
	clientApps.Stop(Seconds(10.0));

	//建立网络路由
	Ipv4GlobalRoutingHelper::PopulateRoutingTables();

	Simulator::Stop(Seconds(10.0));//无线接入点会一直产生信标,模拟器时间列表一直非空,仿真无法结束

	if (tracing == true)
	{
		pointToPoint.EnablePcapAll("third");
		phy.EnablePcap("third", apDevices.Get(0));
		csma.EnablePcap("third", csmaDevices.Get(0), true);
	}

	Simulator::Run();
	Simulator::Destroy();
	return 0;
}

总结:

通过分析以上三个源码,不难发现:

拓展

仿照上述程序,编写一个由两个LAN互联形成的网络。

myfourth.cc

网络拓扑如下:
// Default Network Topology
//
//       
//    n3   n2   n1   n0  -------------- n4   n5   n6   n7
//    |    |    |    |   point-to-point  |    |    |    |
//    ================                   ================
//     LAN 10.1.1.0                        LAN 10.1.2.0
源码分析:

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/netanim-module.h"


using namespace ns3;

// 定义一个日志组件
NS_LOG_COMPONENT_DEFINE("MyfourthScriptExample");

int main(int argc, char* argv[])
{
	bool verbose = true; // 用来决定是否开启日志组件
	uint32_t nCsma_1 = 3; // 定义csma1网络中有多少个节点
	uint32_t nCsma_2 = 3; // 定义csma2网络中有多少个节点

	CommandLine cmd;
	cmd.AddValue("nCsma_1", "Number of \"extra\" CSMA nodes/devices", nCsma_1);
	cmd.AddValue("nCsma_2", "Number of \"extra\" CSMA nodes/devices", nCsma_2);
	cmd.AddValue("verbose", "Tell echo applications to log if true", verbose);

	cmd.Parse(argc, argv);

	if (verbose) // 开启日志的情况下
	{
		LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
		LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
	}

	nCsma_1 = nCsma_1 == 0 ? 1 : nCsma_1; //csma中最少一个节点
	nCsma_2 = nCsma_2 == 0 ? 1 : nCsma_2;

	//创建p2p的两个节点
	NodeContainer p2pNodes;
	p2pNodes.Create(2);

	//创建csma_1的网络节点
	NodeContainer csmaNodes_1;
	csmaNodes_1.Add(p2pNodes.Get(0)); // p2p的0号节点加入csma1作为接入点
	csmaNodes_1.Create(nCsma_1);

	//创建csma_2的网络节点
	NodeContainer csmaNodes_2;
	csmaNodes_2.Add(p2pNodes.Get(1)); // p2p的1号节点加入csma2作为接入点
	csmaNodes_2.Create(nCsma_2);

	// 设置p2p的传输速率及延迟
	PointToPointHelper pointToPoint;
	pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
	pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));

	// p2p节点安装网卡
	NetDeviceContainer p2pDevices;
	p2pDevices = pointToPoint.Install(p2pNodes);

	// 设置csma的传输速率及延迟
	// 注意传输速率有channel指定,而非device属性。(CSMA不允许同一信道上有多个不同数据率的设备)
	CsmaHelper csma;
	csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
	csma.SetChannelAttribute("Delay", TimeValue(NanoSeconds(6560)));

	// csma节点安装网卡
	NetDeviceContainer csmaDevices_1;
	csmaDevices_1 = csma.Install(csmaNodes_1);
	NetDeviceContainer csmaDevices_2;
	csmaDevices_2 = csma.Install(csmaNodes_2);

	// 安装协议栈
	InternetStackHelper stack;
	//stack.Install(p2pNodes); // p2p不需要独立安装
	stack.Install(csmaNodes_1); //p2p的0号节点包含在csma1中一起安装
	stack.Install(csmaNodes_2); //p2p的1号节点包含在csma2中一起安装

	// 下面是ip的分配
	Ipv4AddressHelper address;// 声明了一个地址助手对象
	
	address.SetBase("10.1.1.0", "255.255.255.0");
	Ipv4InterfaceContainer p2pInterfaces;
	p2pInterfaces = address.Assign(p2pDevices);

	address.SetBase("10.1.3.0", "255.255.255.0");//从10.1.1.0 开始 以子网掩码为 255.255.255.0 分配地址
	Ipv4InterfaceContainer csmaInterfaces_1;
	csmaInterfaces_1 = address.Assign(csmaDevices_1);// 完成了csma1真正的地址配置

	address.SetBase("10.1.2.0", "255.255.255.0");//从10.1.2.0 开始 以子网掩码为 255.255.255.0 分配地址
	Ipv4InterfaceContainer csmaInterfaces_2;
	csmaInterfaces_2 = address.Assign(csmaDevices_2);// 完成了csma2真正的地址配置

	 // ***下面安装应用层
	UdpEchoServerHelper echoServer(9);// 服务器端 port为9
	// 将server服务器安装在CSMA2的最后一个节点上即n7
	ApplicationContainer serverApps = echoServer.Install(csmaNodes_2.Get(nCsma_2));
	serverApps.Start(Seconds(1.0));// echoServer 在 1s 时开始 
	serverApps.Stop(Seconds(10.0));//echoServer 在 10s时结束

	UdpEchoClientHelper echoClient(csmaInterfaces_2.GetAddress(nCsma_2), 9);//设定远程服务器的IP地址和Port
	echoClient.SetAttribute("MaxPackets", UintegerValue(1));// 能发送的最大数据分组个数
	echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0))); // 两个数据分组之间要等的时间
	echoClient.SetAttribute("PacketSize", UintegerValue(1024)); // 每个数据分组的大小

	// 将client服务器安装在csma1的最后一个节点上即n3
	ApplicationContainer clientApps = echoClient.Install(csmaNodes_1.Get(nCsma_1));
	clientApps.Start(Seconds(2.0));
	clientApps.Stop(Seconds(10.0));

	// 建立网络路由
	Ipv4GlobalRoutingHelper::PopulateRoutingTables();

	//开启p2pHelper,csmaHelper类对象的pcap追踪
	pointToPoint.EnablePcapAll("Myfourth"); //
	csma.EnablePcap("Myfourth", csmaDevices_1.Get(nCsma_1), true);
	csma.EnablePcap("Myfourth", csmaDevices_2.Get(nCsma_2), true);

	AnimationInterface anim("myfourth.xml");
	anim.SetConstantPosition(csmaNodes_1.Get(0), 5.0, 4.0);
	anim.SetConstantPosition(csmaNodes_1.Get(1), 3.0, 2.0);
	anim.SetConstantPosition(csmaNodes_1.Get(2), 5.0, 2.0);
	anim.SetConstantPosition(csmaNodes_1.Get(3), 7.0, 2.0);

	anim.SetConstantPosition(csmaNodes_2.Get(0), 5.0, 6.0);
	anim.SetConstantPosition(csmaNodes_2.Get(1), 3.0, 8.0);
	anim.SetConstantPosition(csmaNodes_2.Get(2), 5.0, 8.0);
	anim.SetConstantPosition(csmaNodes_2.Get(3), 7.0, 8.0);


	Simulator::Run(); // 启动模拟器
	Simulator::Destroy();
	return 0;
}
注意:

p2p的两个节点分别是两个CSMA的接入点,编程时:

  • 安装网卡时要分别独立安装
  • 协议栈p2p不需要重复安装
  • IP分配需要重复分配
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cheney822

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值