logo资料库

omnet++教程.doc

第1页 / 共259页
第2页 / 共259页
第3页 / 共259页
第4页 / 共259页
第5页 / 共259页
第6页 / 共259页
第7页 / 共259页
第8页 / 共259页
资料共259页,剩余部分请下载后查看
3 NED语言
3.1 NED 概述
3.1.1 一个NED描述组件
3.1.2 保留字
3.1.3 标识符
3.1.4 大小写敏感
3.1.5 注释
3.2 导入命令
3.3 信道定义
3.4 简单模块定义
3.4.1 简单模块参数
3.4.2 简单模块门
3.5 复合模块定义
3.5.1 复合模块和门
3.5.2 子模块
3.5.3 作为参数的子模块类型
3.5.4 指定子模块参数的值
3.5.5 定义子模块门向量的大小
3.5.6 条件参数和gatesizes域
3.5.7 连接
3.6 定义网络
3.7 表达式
3.7.1 常量
3.7.2 引用参数
3.7.3 操作符
3.7.4 sizeof() 和index 运算符
3.7.5 xmldoc()运算符
3.7.6 支持XML文档和XPath子集
3.7.7 函数
3.7.8 随机值
3.7.9 自定义函数
3.8 参数化复合模块
3.8.1 例子
3.8.2 复合模块的设计模式
3.8.3 拓扑模板
3.9 大型网络
3.9.1 产生NED文件
3.9.2 从C++代码来构建网络
3.10 XML绑定NED 文件
4 简单模块
4.1 仿真概念
4.1.1 离散事件仿真
4.1.2 事件循环
4.1.3 OMNeT++中的简单模块
4.1.4 OMNeT++中的事件
4.1.5 FES 实现
4.2 包传输模型
4.2.1 延迟,比特错误率,数据速率
4.2.2 多传输链接
4.3 定义简单模块类型
4.3.1 Overview
4.3.2 构造器
4.3.3 构造器和析构器 VS initialize()和finish()
4.3.4 与早期版本的兼容性
4.3.5 "垃圾收集"和兼容性
4.3.6 例子
4.3.7 使用全局变量
4.4 添加函数至
4.4.1 handleMessage()
4.4.2 activity()
4.4.3 initialize() and finish()
4.4.4 handleParameterChange()[New!]
4.4.5 通过子类复用模块代码
4.5 OMNeT++中的有限状态机制
4.6 发送和接收消息
4.6.1 发送messages
4.6.2 广播和中继
4.6.3 延迟发送
4.6.4 直接发送消息
4.6.5 接收消息
4.6.6 wait() 函数
4.6.7 使用自身消息模型化事件
4.6.8 终止仿真
4.7 访问模块参数
4.7.1 仿真参数数组
4.8 访问门和链接
4.8.1门对象
4.8.2 链接参数
4.8.3 传输状态
4.8.4 连通性
4.9 遍历模块层次
4.10 模块之间的直接调用方法
4.11 动态模块创建
4.11.1 什么时候需要动态创建模块
4.11.2 概述
4.11.3 创建模块
4.11.4 删除模块
4.11.5 模块删除和finish()
4.11.6 创建链接
4.11.7 删除链接
5 消息
5.1 消息和包
5.1.1
5.1.2 自消息
5.1.3模拟包
5.1.4 封装
5.1.5 附加参数和对象
5.2 消息定义
5.2.1 介绍
5.2.2 枚举声明
5.2.3 消息声明
5.2.4 继承,合成
5.2.5 使用现有的C++类型
5.2.6 定制生成的类
5.2.7 在消息类中使用STL
5.2.8 概述
5.2.9 还有什么可以生成代码?
6 仿真库
6.1 类库公约
6.1.1基类
6.1.2 Setting 和 getting 属性
6.1.3 className()
6.1.4 Name 属性
6.1.5 fullName()和fullPath()
6.1.6 拷贝和复制对象
6.1.7 Iterators
6.1.8 错误处理
6.2 模块日志
6.3 仿真时间转换
6.4 产生随机数
6.4.1 随机数产生器
6.4.2 随机数流,RNG映射
6.4.3 访问RNG
6.4.4 随机变量
6.4.5 直方图得到的随机数
6.5 容器类
6.5.1 队列类:
6.5.2 扩展的数组:
6.6 参数类:
6.6.1读取值
6.6.2 值改变
6.6.3
6.7 路由支持:
6.7.1 概述
6.7.2 基本用途
6.7.3 最短路径
6.8 统计和分布估计
6.8.1
6.8.2 分布估计
6.8.3 k分裂算法
6.8.4 瞬时检测和结果精确性
6.9 记录仿真结果
6.9.1输出向量:
6.9.2 输出标量
6.9.3 精度[New!]
6.10 查看和快照
6.10.1 基本查看
6.10.2 读写查看[New!]
6.10.3 结构体查看[New!]
6.10.4 STL查看New!]
6.10.5 快照
6.10.6 断点
6.10.7 获得协同程序栈的用途
6.11 派生新类
6.11.1
6.11.2
6.11.3 类注册
6.11.4 详细信息
6.12 对象所有权管理
6.12.1所有权树
6.12.2 管理所有权
7 构建仿真程序
7.1 概述
7.2使用Unix和gcc
7.2.1 安装
7.2.2 构建仿真模型
7.2.3 多目录模型
7.2.4 静态与共享OMNet++系统库
7.3 使用Windows和 Microsoft Visual C++
7.3.1 安装
7.3.2 在命令行构建仿真模块
7.3.3从MSVC IDE构建仿真模型
8配置运行仿真
8.1 用户界面
8.2 配置文件: omnetpp.ini
8.2.1 举例
8.2.2仿真运行的概念
8.2.3文件语法
8.2.4文件包含的内容
8.2.5 部件
8.2.6 [General] 部件
8.3 动态加载NED
8.4 在omnetpp.ini中设置模块参数
8.4.1 指定的Run和general 部件
8.4.2使用通配符模式
8.4.3 缺省应用
8.5 配置输出向量
8.6 配置随机数生成器
8.6.1 RNG数量
8.6.2 RNG 选择
8.6.3 RNG 映射
8.6.4自动种子选择
8.6.5 手动种子配置
8.6.6 选择好的种子值: 利用seedtool
8.7 Cmdenv: 命令行接口
8.7.1命令行参数
8.7.2 Cmdenv ini 文件选项
8.7.3 解释 Cmdenv 输出
8.8 Tkenv:图形化用户接口
8.8.1 命令行参数
8.8.2 Tkenv ini 文件设置
8.8.3使用图形化环境
8.8.4 In Memoriam...
8.9反复或循环仿真run
8.9.1 执行多个run
8.9.2 参数值的变化
8.9.3种子值的变化(多个独立的run)
8.10 支持Akaroa: 在并行中的多复制
8.10.1 介绍
8.10.2什么是Akaroa
8.10.3 OMNeT++使用Akaroa
8.11 典型问题
8.11.1 堆栈问题
8.11.2 内存泄漏和破坏
8.11.3 仿真迟缓执行
9 网络图形和动画
9.1 显示字符串
9.1.1 显示字符串语法
9.1.2 子模块显示字符串
9.1.3 显示字符串的背景
9.1.4 链接显示字符串
9.1.5 消息显示字符串
9.2 颜色
9.2.1 颜色名
9.2.2 彩色图标
9.3 图标
9.3.1 位图路径
9.3.2 分类图标
9.3.3 图标大小
9.4 布局
9.5 GNED – 图形化 NED 编辑器
9.5.1 绑定键盘和鼠标
9.6 增强动画
9.6.1 在运行时改变显示字符串
9.6.2 Bubbles
10分析仿真结果
10.1 输出向量
10.1.1 使用Plove绘制输出向量
10.1.2 输出向量文件的格式
10.1.3 无Plove的工作
10.2 标量统计数据
10.2.1 输出标量文件的格式
10.2.2 标量工具
10.3 分析和可视化工具
10.3.1 Grace
10.3.2 ROOT
10.3.3 Gnuplot
11 NED 文档和消息
11.1 概述
11.2 授权文档
11.2.1 文档注释
11.2.2 文本布局与格式化
11.2.3 特殊标签
11.2.4 使用HTML添加文本格式
11.2.5 回避 HTML 标签
11.2.6 哪里输出注释
11.2.7 定制标题页面
11.2.8 添加额外的页面
11.2.9 合并外部创建的页面
11.3 调用 opp_neddoc
11.3.1 多工程
11.4 opp_neddoc 如何工作?
12 并行分布式仿真
12.1介绍并行离散事件仿真
12.2 访问仿真模型中可用的平行关系
12.3 OMNeT++支持的并行分布仿真
12.3.1 概述
12.3.2 并行仿真例子
12.3.3 占位符模块和代理网关
12.3.4 配置
12.3.5 OMNeT++支持的PDES设计
13 定制和嵌套
13.1 结构
13.2 OMNeT++嵌套
13.3 Sim: 仿真内核和类库
13.3.1全局仿真对象
13.3.2 协同程序包
13.4 模型组件库
13.5 Envir, Tkenv 和 Cmdenv
13.5.1 main() 函数
13.5.2
13.5.3 定制 Envir
13.5.4 用户界面的实现: 仿真应用程序
14 NED语言文法
15 References
OMNet++仿真基础
Linux下安装OMNeT++
1.1 OMNeT++为何物? OMNeT++是一款面向对象的离散事件网络模拟器,可以实现的功能如下: .无线电通信网络信道模拟 • 协议模拟 • 模拟队列网络 • 模拟多处理器和其他分布式硬件系统 • 确认硬件结构 • 测定复杂软件系统多方面的性能 • 模拟其他的任何一种合适的离散事件系统 一款 OMNeT++模拟器包括一些分层次的嵌入式模型,嵌入式模型的深度是无限的, 即允许用户在模拟环境中绘制实际系统的逻辑结构.各模块通过信息的传输进 行通信,其信息可以包括任意复杂的数据结构,各模块均可以通过门或者线路直 接发送信息给目标点或者也可以通过预先的路径进行传输. 各个模块可以有自己的参数集,参数集可以被用于定制模块行为,或者可以用于 确定模拟拓扑图的参数. 模拟网络最底层的模块可以嵌入行为,这些模块被称为基本模块,它可以利用模 拟器的库函数在 C++进行编程. OMNeT ++模拟器可以在根据不同的目的来改变用户接口: 调试、实例和批量执 行。高级用户的接口可以把模块透明的交给用户,即允许控制模拟器执行以及可 以通过改变模块中的变量/对象来干涉模拟器的执行,这在开发 /调试模拟器工 程师非常有用的,用户接口也促进了模块工作的实现。 模拟器的接口和工具都非常轻便:目前得知它可以在 Windows 和各种 UNIX 操作 系统下利用 c++进行编译。 OMNeT ++还支持分布式并行仿真,OMNeT++可以利用多种机制来进行用于几个并 联的分布式模拟器之间的通信仿真,比如 MPI 和指定的通道。这种并行仿真算法 可以很容易的进行扩展,也很容易加入新的模块。各个模块不必须要特定的结构 来并行运行,这只是一个配置的问题。OMNeT++甚至还可以被用于并行模拟仿 真 算法的多层次描述,因为模拟器可以在 GUI 下并行运行,这种 GUI 为运行过程提 供了详细的反馈。 OMNEST 是 OMNeT++的一个商业版本,OMNeT++只在学术和非盈利性活动免费,在 进行商业性研究时需要从 Global 公司获得 OMNEST 许可证。 1.2 本手册的组织结构 本手册的组织结构如下: 第[1],[2]章包括介绍性的资料 第二组章节,[3],[4],和[6]是编程向导.他们提出了 NED 语言,仿真的概念和他 们在 OMNet++中的执行,解释了如何写一个简单的模块并描述了类库.
第[9],[11]进一步阐述了主题,通过解释如何定制网络图,从产生的方件中,如何 写 NED 源代码注释. [7],[8],[10]处理了实际的问题,比如建立,运行仿真器,分析结果,提出了 OMNet++工具提供的所支持的任务. [12]章支持分布式执行 最后[13]解释了 OMNet++内部结构 附录[14]提供了参考的 NED 语言 第二章 概述 2.1 建模的概念 OMNeT++为用户提供了有效的用于描述实际系统结构的工具。一些主要的特征表 现如下: (1) 分层次嵌入式模块 (2) 各模块以模块类型分类 (3) 模块之间通过信号在通道上 的传输进行通信 (4) 灵活的模块参数 (5)拓扑描述语言 2.1.1 分层次的各模块 OMNeT ++模块包括分层次的嵌入式模块,这些模块通过彼此之间传输消息来进行 通信。OMNeT++经常被描述成网络结构,最顶层的模块称为系统模块,系统模块 包括子模块,其子模块还可以包括本身的子模块,模块嵌入的深度是没有限制的, 它允许用户在模块结构中根据实际系统来绘制逻辑结构图。 模块结构利用 OMNeT++ 的 NED 语言进行描述。 包含子模块的模块称为混合模块,与在层次模块最底层的简单模块相反.在模型 中简单模块包括算法.使用 OMNet++的仿真类库, 用户通过 C++执行简单模块. 2.1.2 模块类型 基本模块和复合模块都是模块类型的实例。在描述模块时,用户定义了模块类型; 这些模块类型的实例用于组成更复杂的模块类型.最终,用户创建系统模块为前
面所定义的模块类型的实例;所有的网络模块都被实例为系统模块的子模块和子 子模块. 当一种模块类型被用作一个建立块,则不管是基本模块和复合模块都没有区别。, 这使用户在不影响现有的模块类型用户的条件下,可以将一个基本模块分割成多 个基本模块嵌入至一个复合模块,或者相反,集成一个复合模块的功能为单个基 本模块. 模块类型可以存储于文件中,并且可以保证与它实际的用法分别开来,这就意味 着用户可以通过存在的模块类型进行分组,也可以创造组成库,这一特征在后面 第[8]章将会给出详细的介绍。 2.1.3 消息、门、链路 模块之间通过交换消息进行通信,在一个实际的模拟器中,可以使用计算机网络 中的帧和包来替代消息,在队列网络中可以用作业或消费者来替代消息,或者其 他的移动实体类型。消息可以包括任意复杂的数据结构.基本模块可以通过门或 连接,直接发消息至目的地,也可以通过预先确定的路径发送消息. 当模块接收一个消息时,模块的”本地仿真时间”前进.消息能够从其他的模块或 从相同的模块抵达(自身的消息用于执行定时器). 门是模块的输入/输出接口,消息通过输出门发送出去,通过输入门进行接收。 每个连接(也称之为链接)被创建成一个单一层次的模块层次:在一个复合模块中, 可以连接相应的两个子模块的门,或一个子模块的门和一个复合模块的门. 子模块彼此连接 子模块连接父模块 由于模块的层次结构,典型的消息传输是通过一系列的连接,开始和到达都在简 单模块中.这些连接系列从简单模块到简单模块,被称之为路由.在模块中的复合 模块可以看成”纸盒”,在其内部和外部世界之间透明地转播消息. 2.1.4 包输出的建模 连接被分配三个参数,用于方便通信网络的建模,但是在其他的建模中也是有用 的:传播延迟,比特错误率和数据率,所有三个都是可选的.对每个连接都可以分 别指定链接参数,或者定义链接类型,在整个网络中使用. 传播延迟是指由于通过通道传输,消息抵达的延迟的时间数. 位错误率指一比特数据被错误传输的概率,允许简单的噪音通过建模. 数据率 bit/second,用于计算传输一个包的时间. 当数据率在使用的时候,模块中发送的消息对应于传输的第一个比特,消息接收 对应于接收的最后一个比特.这个模块不是总是可用的,例如,类似于 Token 环和
FDDI 协议,不等待结构到达其实体,而是开始重复它的第一个比特,然后他们到 达—换句话说,”流量通过”结构,仅存在很少的延迟.如果你想模块化这些网 络,OMNet++的数据率建模特征将不能使用. 2.1.5 参数表 模块可以有参数表,参数表可以在 NED 文件中指定,也可以在 omnetpp.ini 中进 行配置。 参数可以用于定制简单模块行为,也可以参数化模型拓扑. 参数可以是 string, numeric 或 boolean 值,或者也可以包括 XML 数据等.numeric 值包含使用其他参数的表达式以及调用 C 函数,不同分类的随机变量,和由用户 交互输入的值. Numeric 值的参数可以以灵活的方式构成拓扑结构.在一个复合模块中,其参数 定义子模块数,门数,和形成内部连接的方法. 2.1.6 拓扑描述方法 用户使用 NED 描述语言定义了模型的结构.NED 语言将在第[3]章讨论. 2.2 设计算法 一个模型的简单模块包括像 C++函数的算法.使用设计语言的灵活性和能力,支 持 OMNet++的仿真类库.仿真程序员可以选择事件驱动或进程式的描述,可以自 由使用面向对象概念(继承,多态等)和设计模式来扩展仿真功能. 仿真对象(消息,模块,队列等)由 C++类表示.他们被设计成有效地共同工作,创 建一个有力的仿真设计结构.以下的类是仿真类库中的一部分: modules, gates, connections etc. parameters messages container classes (e.g. queue, array) data collection classes statistic and distribution estimation classes (histograms, P2 algorithm for calculating quantiles etc.) transient detection and result accuracy detection classes . 这些类是一个特殊的工具,允许运行的仿真对象的移动,显示他们的信息如,名称, 类名,状态变量或内容.这个特点使他可能创建一个仿真 GUI,其中所有的仿真内 在都是可见的. 2.3 使用 OMNeT++ 2.3.1 新建运行模拟器
这节提供了在实践中观察 OMNet++的工作:比如讨论了模型文件,编译,运行仿真 器等问题. 一个 OMNet++模型包括以下几部分: NED 语言拓扑描述(.ned 文件),其使用参数,门等描述了模块结构.NED 文件可以 使用任何文本编辑器或 GNED 图形化编辑器来编写. 消息定义(.msg 文件).可以定义变量消息类型,以及在其上添加数据文 件.OMNet++将消息定义转化成完全的 C++类. 简单模块源.他们是 C++文件,.h 或.cc 后缀. 仿真系统提供了以下的组件: 仿真内核.这包含用 C++编写的管理仿真和仿真类库的代码,编译使其形成一个 库文件(扩展名为.a 或.lib). 用户接口.OMNet++用户接口在仿真执行的时候使用,用于方便调试,演示或者批 处理仿真的执行.有许多用 C++编写的用户接口, 编译使其形成一个库文件(扩 展名为.a 或.lib). 从以上的组件中创建仿真程序.首先,使用 opp_msgc.程序将.msg 文件转化成 C++ 代码.然后编译所有的 C++源文件,链接仿真内核和用户的接口库,形成一个仿真 可执行文件.NED 文件可以转化成 C++文件(使用 nedtool)进行链接,当仿真程序 开始执行时,也可在他们原始的文本里动态加载. 仿真器的运行和结果分析 仿真执行文件是一个单独的程序,因此它可以运行在没有 OMNet++,或正在显示 模型文件的其他机器上.当程序开始执行,它读一个配置文件(通常为 omnetpp.ini)这个文件包括设置,它控制了仿真如何被执行,模型参数的值,等. 配置文件也指定了许多仿真运行;在最简单的情况下,他们将被仿真程序接连地 执行. 仿真的输出写入一个数据文件:输出向量文件,输出标量文件,以及用户自己的输 出文件.OMNet++提供一个 GUI 工具 Plove 来查看,制作输出向量文件的内容图. 它不希望仅仅使用 OMNet++来处理结果文件:输出文件的格式是一个文本文件, 可以读进数学包像 Matlab 或 Octave,或导入电子数据表像 OpenOffice Calc, Gnumeric 或 MS Excel(许多预处理将需要 sed,awk,perl,这将在后面讨论).所有 这些外部的程序提供了丰富的功能用于统计分析和可视化,OMNet++范围之外的 程序使他们的成就加倍.本手册简单描述了许多数据测绘程序,以及如何使用 OMNet++. 输出标量文件使用标量工具可视化.它可以画出柱形统计图表,x-y 图表(比如吞 吐量 VS 提供的负载),或导出数据通过剪贴板至电子数据表和其他的程序进行更 详细的分析. 用户接口
用户接口的基本目的是使模型的内部对用户可视,控制仿真执行,通过改变模型 内部的变量/对象允许用户干涉.这在项目仿真的开发/调试阶段非常重要的.一 个传递下去的经验允许用户得到一个模型行为的”感觉”也同样重要.图形用户 接口可以用于证明一个模型的操作. 相同的仿真模型在模型文件本身不做任何改变的情况下被不同的用户执行.用户 可以使用一个有力的图形化用户接口进行测试调试仿真,最终使用一个简单快速 的支持批处理执行的用户接口运行. 组件库 存储在文件的模块类型从他们实际使用的地方分离出来.这个使用用户组合现有 的模块类型,创建组件库. 通用的单独仿真程序 仿真执行文件可以存储许多独立的模型,使用相同的简单模块集.用户可以在配 置文件中指定运行哪个模型.允许创建一个包括许多仿真模型的大的可执行文件, 发布为一个单独的传感器工具.拓扑描述语言的灵活性也支持这种方法. 2.3.2 各分类的内容 如果安装了发布的源程序,你系统上的 omnetpp 目录将包括以下的子目录.(如果 你安装了一个预处理发布,将缺少一些目录,或者会有额外的目录,比如 包括 OMNet++绑定的软件). 仿真系统本身: omnetpp/ OMNeT++ 根目录 bin/ OMNeT++ 可执行文件目录(GNED, nedtool 等) include/ lib/ bitmaps/ doc/ 仿真模块的头文件 库文件 图形网络中会使用的图标 手册(PDF),readme, license 等 manual/ HTML 帮助文件 tictoc-tutorial/ 介绍使用 OMNeT++ api/ 参考的 HTML API nedxml-api/ API 参考 NEDXML 库 src/ 文件源 src/ OMNeT++ 源 nedc/ nedtool,消息编译器
sim/ 仿真内核 parsim/ 发布执行的文件 netbuilder/ 动态读取 NED 文件的文件 envir/ cmdenv/ tkenv/ gned/ plove/ scalars nedxml/ utils/ 用户接口的公共代码 用户接口命令行 基于 Tcl/Tk 的用户接口 图形化 NED 编辑器 输出向量分析器和制图工具 输出标量分析器和制图工具 NEDXML 库 makefile 创建器,文档工具等 test/ 回归测试 core/ distrib/ ... 在 samples 目录中的是仿真例子 samples/ aloha/ cqn/ ... 仿真库的回归测试 创建发布的回归测试 仿真例子的目录 Aloha 协议模型 关闭的队列网络 contrib 目录包括 OMNeT++的贡献内容. contrib/ 贡献内容目录 octave/ emacs/ 用于结果处理的 Octave 脚本 Emacs 高亮显示 NED 语法 你也会发现一些附加的目录,像 msvc/, 其包括 VC++的综合组件等. 3 NED 语言 3.1 NED 概述 模型的拓扑结构可以使用 NED 语言详细描述.NED 语言方便了一个网络的模块描 述.这意味着一个网络描述包括许多组件描述(通道,简单/复合模块类型).网络 描述的通道,简单模块和复合模块可以在另一个网络描述中重复使用.
包含网络拓扑模型描述的文件通常以.ned 为后缀名,它可以动态地载入仿真程 序或由 NED 编译器翻译为 C++代码,并链接到可执行文件中. EBNF 语言描述见附录[14]. 3.1.1 一个 NED 描述组件 一个 NED 描述包括以下组件,以任意数据或顺序: 导入命令 定义信道 简单和复合模块定义 网络定义 3.1.2 保留字 网络描述必须注意不能使用保留字命名.NED 语言的保留字有: Import, channel, endchannel, simple, endsimple, module, endmodule, error, delay, datarate, const, parameters, gates, submodules, connections, gatesizes, if, for, do, endfor, network, endnetwork, nocheck, ref, ancestor, true, false, like, input, numeric, string, bool, char, xml, xmldoc. 3.1.3 标识符 标识符是模块名,信道,网络,子模块,参数,网关,信道属性和函数. 标识符必须由英文字母表(a-z,A-Z),数字(0-9)和下划线”_”.可以由字母或下 划线开始.如果你想以数据开头的话,在前面加个下划线,例如_3Com. 如果标识符由几个单词组成时,按惯例大写每个单词的首字母,建议大写模块,信 道,网络等标识符的首字母,小写参数,门,子模块等标识符的首字母.下划线很少 使用. 3.1.4 大小写敏感 网络描述和所有的标识符是大小写敏感的.例如,TCP 和 Tcp 是两个不同的命名. 3.1.5 注释 注释可以放在 NED 文件的任何地方,跟 C++语法类似:由双斜线开始”//”,一直 延续到这行的结尾,注释被 NED 编译器忽略. NED 注释可以用于产生文档,像 JavaDoc 和 Doxygen.此特性在第[11]章描述. 3.2 导入命令 导入命令是用于从其他网络描述文件中导入描述.在导入一个网络描述后,可以 使用组件(信道,简单/复合模块类型定义.
分享到:
收藏