CN1722681A - 便携分布式应用框架 - Google Patents
便携分布式应用框架 Download PDFInfo
- Publication number
- CN1722681A CN1722681A CN200510077480.2A CN200510077480A CN1722681A CN 1722681 A CN1722681 A CN 1722681A CN 200510077480 A CN200510077480 A CN 200510077480A CN 1722681 A CN1722681 A CN 1722681A
- Authority
- CN
- China
- Prior art keywords
- message
- protocol
- emulation
- data
- application
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 230000004044 response Effects 0.000 claims abstract description 22
- 230000003139 buffering effect Effects 0.000 claims description 80
- 238000004088 simulation Methods 0.000 claims description 76
- 238000000034 method Methods 0.000 claims description 42
- 230000005540 biological transmission Effects 0.000 claims description 25
- 230000006854 communication Effects 0.000 claims description 18
- 238000004891 communication Methods 0.000 claims description 17
- 238000013461 design Methods 0.000 claims description 6
- 238000005538 encapsulation Methods 0.000 claims description 5
- 238000013507 mapping Methods 0.000 claims description 2
- 230000001360 synchronised effect Effects 0.000 claims description 2
- 230000006870 function Effects 0.000 description 25
- 238000012360 testing method Methods 0.000 description 25
- 239000011800 void material Substances 0.000 description 20
- 238000010586 diagram Methods 0.000 description 14
- 230000009471 action Effects 0.000 description 13
- 230000008859 change Effects 0.000 description 9
- 238000007726 management method Methods 0.000 description 9
- 230000008569 process Effects 0.000 description 9
- 238000005516 engineering process Methods 0.000 description 7
- 238000012423 maintenance Methods 0.000 description 7
- 230000006978 adaptation Effects 0.000 description 6
- 230000000712 assembly Effects 0.000 description 5
- 238000000429 assembly Methods 0.000 description 5
- 239000003795 chemical substances by application Substances 0.000 description 5
- 241001269238 Data Species 0.000 description 3
- 239000012141 concentrate Substances 0.000 description 3
- 230000003068 static effect Effects 0.000 description 3
- 241000568443 Aname Species 0.000 description 2
- 241000764238 Isis Species 0.000 description 2
- 238000004458 analytical method Methods 0.000 description 2
- 230000000295 complement effect Effects 0.000 description 2
- 238000012217 deletion Methods 0.000 description 2
- 230000037430 deletion Effects 0.000 description 2
- 238000011161 development Methods 0.000 description 2
- 230000000694 effects Effects 0.000 description 2
- 239000000284 extract Substances 0.000 description 2
- 230000007246 mechanism Effects 0.000 description 2
- 239000003607 modifier Substances 0.000 description 2
- 230000008520 organization Effects 0.000 description 2
- 239000002245 particle Substances 0.000 description 2
- ABEXEQSGABRUHS-UHFFFAOYSA-N 16-methylheptadecyl 16-methylheptadecanoate Chemical compound CC(C)CCCCCCCCCCCCCCCOC(=O)CCCCCCCCCCCCCCC(C)C ABEXEQSGABRUHS-UHFFFAOYSA-N 0.000 description 1
- 238000013459 approach Methods 0.000 description 1
- 230000006399 behavior Effects 0.000 description 1
- 230000008901 benefit Effects 0.000 description 1
- 229910002056 binary alloy Inorganic materials 0.000 description 1
- 230000015572 biosynthetic process Effects 0.000 description 1
- 238000010276 construction Methods 0.000 description 1
- 238000007796 conventional method Methods 0.000 description 1
- 230000008878 coupling Effects 0.000 description 1
- 238000010168 coupling process Methods 0.000 description 1
- 238000005859 coupling reaction Methods 0.000 description 1
- 125000004122 cyclic group Chemical group 0.000 description 1
- 238000013499 data model Methods 0.000 description 1
- 239000000835 fiber Substances 0.000 description 1
- 239000012634 fragment Substances 0.000 description 1
- 238000005417 image-selected in vivo spectroscopy Methods 0.000 description 1
- 238000007689 inspection Methods 0.000 description 1
- 238000012739 integrated shape imaging system Methods 0.000 description 1
- 230000010354 integration Effects 0.000 description 1
- 230000003993 interaction Effects 0.000 description 1
- 230000002452 interceptive effect Effects 0.000 description 1
- 230000035772 mutation Effects 0.000 description 1
- 238000004806 packaging method and process Methods 0.000 description 1
- 238000004321 preservation Methods 0.000 description 1
- 238000012545 processing Methods 0.000 description 1
- 238000011084 recovery Methods 0.000 description 1
- GOLXNESZZPUPJE-UHFFFAOYSA-N spiromesifen Chemical compound CC1=CC(C)=CC(C)=C1C(C(O1)=O)=C(OC(=O)CC(C)(C)C)C11CCCC1 GOLXNESZZPUPJE-UHFFFAOYSA-N 0.000 description 1
- 230000009897 systematic effect Effects 0.000 description 1
- 238000012546 transfer Methods 0.000 description 1
- 230000001052 transient effect Effects 0.000 description 1
Images
Classifications
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L43/00—Arrangements for monitoring or testing data switching networks
- H04L43/50—Testing arrangements
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L41/00—Arrangements for maintenance, administration or management of data switching networks, e.g. of packet switching networks
- H04L41/14—Network analysis or design
- H04L41/145—Network analysis or design involving simulating, designing, planning or modelling of a network
Landscapes
- Engineering & Computer Science (AREA)
- Computer Networks & Wireless Communication (AREA)
- Signal Processing (AREA)
- Computer And Data Communications (AREA)
- Stored Programmes (AREA)
- Data Exchanges In Wide-Area Networks (AREA)
Abstract
本发明公开了一种便携分布式应用框架,其使用下述定义文件,该定义文件描述了由所述框架用来与应用相接口的数据结构和命令。响应于定义文件的代理基于所述定义文件来创建和接收消息。所创建的消息包含用来控制应用的数据和命令,而所接收的消息包含来自应用的数据。响应于定义文件的控制在代理和应用之间中继消息。响应于定义文件和来自代理的消息的容器向应用提供配置信息,并从应用接收数据。
Description
技术领域
本发明涉及便携分布式应用框架。
背景技术
对诸如路由器的网络设备进行大量测试,以确保使错误的传输和致命的错误最小化。市面上可获得多种测试设备,包括来自安捷伦科技有限公司(本申请的受让人)的路由器测试仪(ROUTER TESTER)。这种测试设备一般监控路由器对多种模拟输入的响应。
可以将路由过程简单地概括为节点寻找到每个可能目的地的路径。在第1层(物理层)以上,路由无所不在。但是,大多数人所熟悉的路由发生在第3层(网络层)处,因此,这里将只讨论第3层(并且更具体地)的因特网协议(IP)路由。路由器使用表来确定向何处转发分组。更新这些表是由路由协议执行的功能。每个路由器响应于一种或多种协议。
用于交换路由信息的协议将遍布全球的多个路由器连接起来,以通过它们的异构路由表(虽然大体上是一致的)向它们提供网络的公共视图。路由表存储路由器到达网络上的每个目的地所必需的所有信息,而不管网络有多大。存在很多种路由协议被用来构造跨越网络的路由表。诸如BGP、OSPF、RIP和ISIS之类的协议有助于向网络上的所有路由器传送对该网络正确并且一致的描述。
已知的路由器测试仪利用专门创建的数据“测试分组”来模拟网络流量,其中所述数据“测试分组”是网络上出现的典型的真实数据。将这些测试分组通过被测网络传输到网络设备。由流量模拟器系统(包括“路由器测试仪”)测试的参数包括路由验证、负载情况下服务质量(QoS)等级的实现以及与其他设备之间的正确配合(inter-working)。这些所谓的“分组播发器(packet blaster)”中的很多也通过根据协议来配制并传输数据,从而测试网络设备与协议保持一致的能力。
图1是流量模拟器测试系统100的方框图。更具体地说,该流量模拟器测试系统100是由安捷伦科技有限公司提供的路由器测试仪的一般代表。路由器测试仪只是路由器测试系统的一个示例,具体地说,其被广告为多端口流量生成、协议仿真和分析测试系统,用于对企业、都市/边缘、核心路由和光纤网络的设备的性能进行验证。该系统一般包括连接到被测系统的多个协议仿真卡102n,在这种情形中所述被测系统是路由器104。每个协议仿真卡102n一般包括具有相关的存储器和I/O的处理器。由例如运行视窗环境的PC之类的计算机106控制协议仿真卡102n。计算机106对例如图形用户界面之类的接口108作出响应。
根据通信协议的规则和解释(例如那些由工业界的许多标准团体所定义的),构建由协议仿真卡102n产生的测试分组。有许多通信协议在使用中,并且在继续开发多种新的协议。一般来说,新协议最初是由装备制造商开发的,并且本质上是专用的。标准团体随后常常会采纳这些协议,以在工业界广泛地实现。协议仿真卡102n使用协议状态机来根据被测协议(subject protocol)创建用于传输的数据。所述状态机在运行上与在路由器自身中所使用的状态机相似。
当前与流量模拟器测试系统相关联的软件体系结构要求对协议仿真方案的所有部分进行硬编码,其中协议仿真方案包括图形用户界面、脚本API、配置和控制组件,以及协议状态机自身。要求为每种协议硬编码导致使用大量人力来创建大的代码体。这种代码的很大部分专门用于将计算机106接口到每种新的协议仿真卡102n。
将计算机106接口到每种新协议仿真卡102n的传统方法要求在用接口描述语言(IDL)硬编码及写接口的时候就知道方法和相关联的参数。在这种范例中,每次写新的协议仿真时或者将旧的协议扩展时,就要不断地创建新的方法和参数。这导致了包含有数以百计的方法和参数的巨大的API(应用编程接口),并且导致维护代价高昂的代码体。此外,已知的方法导致在多个不同的层复制API,从而使问题更复杂。因此,API的每次改变(不管多小)都要求对系统内的大量代码和不同的层进行更新。这种方法的一种副作用是必须为每种协议和它的每次更新生成唯一的GUI(图形用户界面)。对于API来说,随着协议数目的增多,所需的GUI实现方式也增多。
现在正在努力设计减轻某些前述问题的通用系统。在这里结合作为参考的,名为“构建数据分组”的待审查美国专利申请序列号No.10/266,507、公开号No.US20040068681 A1的专利申请中描述了一种示例,其使用外部协议仿真描述来驱动通用协议数据单元(PDU)编码/解码引擎。接下来的步骤是:为每个新的仿真器或者仿真器的改变建立到下述协议仿真器的通用接口,所述协议仿真器不要求新代码或者硬编码接口改变。
对这种情形的解决方法是为控制协议而开发专用的编译语言。在主机上写语言语句,并将其编译,然后将作为结果的目标文件分发到嵌入的软件模块以执行。在这种方法中,需要为每种协议开发新的语言语句。这要求不断地改写编译器,而这本质上是复杂、高技巧的任务。此外,为每种协议开发GUI也是正在进行的庞大任务。
另一种方法是开发传统的、非通用的应用框架。这种方法要求在固定的、预定义的API和数据结构内,或者在对于每种协议是高度定制的框架内进行协议仿真。使用真实协议的经历表明高度定制是必须的,这使得这种方法不能令人满意。
因此,本发明的发明者已经认识到需要一种通用框架,其基于框架外的定义文件与应用接口。为不同的应用修改该框架将只要求创建新的定义文件,而不要求重写框架自身。在协议状态机的上下文中,这种框架将使得能够使用:包括通用GUI在内的多种能够支持所有协议仿真的用户接口;通用控制和命令主机组件;以及嵌入设备上的通用协议容器。
发明内容
本发明公开了一种协议仿真系统,其包括:至少一个由协议仿真定义来配置的仿真容器,用于根据包含在所述协议仿真定义文件内的数据启动协议仿真会话;由所述协议仿真定义配置的接口,其显示与由所述仿真容器创建的所述会话相关的数据,并且帮助来自用户的命令和配置数据的进入,所述命令和配置数据被传输到所述仿真容器,并且修改仿真容器的行为;以及仿真控制器,其分发协议仿真定义,并且充当所述仿真容器与所述接口之间的数据和命令的管道。
根据本发明,提供了一种便携分布式应用框架,包括:定义文件,其描述由所述框架用来与应用接口的命令和数据的结构;代理,响应于定义文件,用于基于所述定义文件创建和接收消息,所创建的消息包含用来控制应用的数据和命令,所接收的消息包含来自所述应用的数据;控制,响应于所述定义文件,用于在所述代理和所述应用之间中继消息;以及容器,响应于所述定义文件和来自所述代理的消息,向所述应用提供配置信息,并从所述应用接收数据。
根据本发明,提供了一种控制应用的方法,包括:创建定义,所述定义描述用于与所述应用相接口的数据和命令;使用所述定义来配置通用接口,所述接口创建基于所述定义而构建的消息;以及使用所述定义来配置通用容器,所述容器从所述接口接收消息,从所述定义中抽取数据和命令,并将所述数据和命令提供给所述应用,所述容器基于所述定义,将从所述应用接收到的数据封装到消息中,所述消息被传输到所述接口。
根据本发明,提供了一种与远程应用通信的方法,所述方法包括:定义将被用来与所述远程应用通信的消息的结构;将所定义的结构提供给中央控制和至少两个接口;创建一串位于所述远程应用本地的缓冲区来保存来自所述接口的消息,其中针对每种类型的消息来定义缓冲区;创建一串位于所述接口本地的缓冲区以保存来自所述远程应用的消息,其中针对每种类型的消息来定义缓冲区;基于所定义的消息结构,在所述用户接口本地为所述远程应用创建第一消息;基于所定义的消息结构,在所述远程应用本地为所述接口创建第二消息;将所述第一消息传输到中央控制;将所述第二消息传输到所述中央控制;基于所述消息的类型,缓冲在所述中央控制中所接收到的消息;将所述中央控制中的缓冲区镜像映射到位于所述接口本地的缓冲区,使得每个接口中的缓冲区的内容与所述中央控制中的缓冲区同步;以及将由所述中央控制接收到的第一消息传输到所述远程应用。
附图说明
结合附图,从下面对本发明的某些实施方式的详细描述可以理解本发明,其中:
图1是流量模拟器测试系统的方框图。
图2a是用于解释已知协议仿真软件体系结构的方框图。
图2b是用于解释适于根据本发明实施方式控制协议仿真软件的体系结构的方框图。
图3是根据本发明实施方式部署在目标平台中的通用协议框架的方框图。
图4是用于解释根据本发明至少一种实施方式的仿真控制运行的方框图。
图5是根据本发明实施方式的通用协议会话模型的方框图。
图6是根据本发明实施方式的协议基础设施的方框图。
图7是根据本发明实施方式,用于在通用协议框架中使用的XML标签层次的图。
在下文中包含的描述中,紧邻元素标识符使用小写字母“n”表示一组元素中的非特定元素实例,而不象在附图和说明书中一样,用紧邻元素号的非斜体字母来表示一个特定元素。在一组元素共享公共的元素标识符的情形中,使用这种没有相邻字母的元素标识符是指这组元素的全部。
具体实施方式
现在将参考本发明的实施方式,在附图中图示了这些实施方式的实施例,其中在所有的附图中相同的标号是指相同的元件。遵循本方法的详细描述可以由计算机可读介质、关联处理器、数据生成和获取卡等之内的对数据位的操作的符号表示和例程来实现。这里,例程通常被认为是导致期望的结果的步骤或者动作的序列,同样地,其包含例如“程序”、“对象”、“函数”、“子例程”和“过程”等专门术语。这些描述和表示是本领域的技术人员用来向本领域的其他技术人员有效地传达其工作的实质的手段。为了方便,在下面的说明和权利要求中,词语“网络”用来指下述任何一个或多个:通信网络、网络设备、任何其他通信设备和可以用测试数据分组来测试的通信系统的一个或多个方面。
虽然描述的实施方式包括在下述路由器测试仪上实现的方法,所述路由器测试仪具有与安捷伦路由器测试仪相似的配置。但是,这里叙述的方法可以在多种路由器测试仪中的任何一种上运行。更为重要的是,这里提出的方法并不内在地与任何具体的设备相关;相反,可以与根据这里的教导的例程一起使用各种设备。具体地说,尽管这里描述路由器测试仪功能,但是这里描述的用于将数据从一个设备传送到另一个设备的方法一般可以适用于数据通信领域。可以执行这里描述的功能的机器包括由下述公司制造的机器:例如,安捷伦科技有限公司、惠普和泰克电子有限公司,以及其他通信设备制造商。
至于这里描述的软件,本领域的普通技术人员将认识到存在多种平台和语言,用于创建软件来执行这里概述的过程。可以用包括C++在内的C的多种变种中的任何一种实现本发明的实施方式。然而,本领域的普通技术人员也认识到,确切的平台和语言的选择常常由所构建的实际系统的特性规定,所以可以在一类系统上工作的在另一类系统上可能无效。也应当理解,这里所描述的例程和计算并不限于作为计算机上的软件执行,而是也可以在硬件处理器中实现。例如,可以利用多种设计工具,在ASIC或者FPGA中用HDL(硬件设计语言)实现例程和计算。
概述
本发明集中描述便携分布式应用框架,其可以被容易地调适来与多种应用相接口,并且控制多种应用。一般来说,该框架包括与应用接口的容器(housing)、与一个或者多个客户接口机制(例如GUI)相接口的代理、以及协助代理与容器之间通信的控制。用相同的描述文件(或者可能是它的拷贝)配置容器、代理和控制中的每一个。描述文件包含数据结构和命令的描述,框架用这些数据结构和命令与应用相接口并且控制应用。下面的描述将集中于将本发明描述为下述实现,所述实现用于在与协议仿真软件的会话相接口以及对协议仿真软件的会话进行控制中使用。然而,本发明不限于在协议仿真软件中使用,而是可以适于在多种环境中使用,尤其是在想要使用远程应用管理的环境中。
图2a是用于解释已知协议仿真软件体系结构200a的方框图。协议仿真软件一般与三个不同的功能区互动:提供控制机制的图形用户界面(GUI)202;提供命令组件的操作系统(OS)204;以及(例如)在卡102上形成协议容器的嵌入软件206。在已知系统中,协议仿真软件208n包含为具体协议专门写的复杂的一套代码,所述协议例如是OSPF(208a)、BGP4(208b)、RIP(208c)和IS-IS(208d)。换句话说,对于每种仿真208n,必须创建并集成到GUI 202、OS 204和嵌入软件206的定制接口。
图2b是用于解释根据本发明实施方式的协议仿真软件的体系结构200b的方框图。本发明实施方式一般包括一套软件例程210,这里称作通用协议框架210(或者GPF 210)。GPF 210与GUI 202、OS 204和嵌入软件206相接口。GPF 210实现能够支持所有协议仿真的通用GUI、通用控制和命令主机组件以及在嵌入设备上的通用协议容器。依赖于具体的实现,可以证明,对诸如协议状态机之类的某些协议元素定制编码是有益的,这些协议元素被描绘为图2b中的元件212n。在这种实现中,框架210将支持协议仿真器的服务和驻留在协议状态机之上的控制层进行归纳。但是,如下文所述,也可以只利用框架210来创建完整的协议仿真,而不需要诸如元件212n之类的嵌入的定制编码组件。
象在这里使用的那样,使用术语“通用”意思是:在没有关于具体协议仿真的知识的情况下写每个通用组件。实现这一目标的一种方法是定义在协议仿真定义文件214中的组件外部的命令和数据结构。在可能的优选实施方式中,协议仿真定义文件214描述:需要从入数据流选择仿真分组的硬件模式匹配器;由该仿真所使用的TCP/IP套接字的细节,包括套接字参数和套接字选项;用来描述由仿真所使用的命令、配置和结果数据的一组通用数据结构;以及由GUI所需要的,用来向用户呈现仿真数据的格式化信息。可以使用协议定义文件214来创建数据结构,这些数据结构在运行时期间被用来配置GPF 210与具体的协议互动。
在一种实施方式中,协议仿真定义文件214使用XML标签来组织服务和控制数据。例如,可以用XML标签<filter>描述硬件模式匹配过滤器的配置。类似地,可以用<socket>标签描述仿真所需要的TCP/IP套接字规范。可以用<parcel>标签描述向仿真和从仿真传输的命令和数据结构。最后,可以用<emulation>标签来装配这些标签所引用的数据。在运行时期间,用装配的数据来创建可由GPF 210的各种组件访问的数据结构。该数据结构在这里被称作参考模型。可以将静态值存储在协议仿真定义文件214中,并且被加载到该参考模型中。可以从外部提供动态值或者需要用户输入的值,并且基于在<parcels>部分中描述的数据结构,利用通信进程将其传输到GPF 210的合适的组件。通常,在系统上运行的每个协议仿真实例(术语称作“会话”)都将访问一个或者多个参考模型,以获得配置和控制数据。可以证明,为将在系统上激活的每类协议仿真都创建参考模型(或者参考模型的集合)是有益的。
在名为“分布式数据模型”的待审查美国专利申请No.10/851,303中随同适当的XML语法一起给出了参考模型的一般结构。′303申请集中于XML语法的具体子集的特点,其包含有<parcels>标签(用来描述命令和通信数据结构)。′303申请于2004年5月21日提交,被转让给本申请的受让者,并且被结合于此作为参考。本发明将在′303申请中描述的某些概念扩展到整套协议仿真软件。一旦查看本发明的详细描述和所附权利要求,本发明的其他方面将变清楚。
在一种实施方式中,GPF 210还包括通用的、自文档化(self-documenting)的API。可以在协议仿真定义文件214以及任何帮助文本中描述与这种API相关联的命令和参数。这使得在不写任何框架代码的情况下就能创建新的命令。通过使用诸如工具控制语言(“Tcl”)之类的工具,可以用XML和Tcl定义整个协议仿真来在框架之内运行。这使用户和技术支持工程师能够立即对新协议进行测试,而不用等待供应商提供定制协议模块(例如模块212n)。诸如常规仿真之类的通用仿真看起来与API和GUI相同。尽管对于这种完全通用解决方案可能存在性能限制,但是很大地改进了上市时间窗口。如果需要更高的性能,则可以提供定制的模块。
图3是根据本发明实施方式部署在目标平台中的通用协议框架300的方框图。通用协议框架300(GPF 300)一般包括三个组件:仿真控制304;仿真容器308n;以及代理控制314n。仿真控制304管理协议会话(没有示出,但是在下文中作了描述),并驻留在主机302上。一般来说,仿真控制304创建并移除会话。主机302一般包括诸如运行视窗操作系统的PC之类的计算机,但不是必须的。仿真容器308n容纳提供被配置的资源和会话数据的协议会话。仿真容器308n为每个协议会话向仿真控制304提供双向数据管道。仿真容器一般驻留在端口306n上。每个端口306n一般驻留在协议仿真卡(没有示出,参见图1的元件102n)上。代理控制314n通过提供对仿真控制命令和数据的访问,帮助实现对仿真控制304的远程控制。可以将代理控制314n提供给多种功能组件,包括所示的GUI 310和Tcl API 312。
每个组件具有协议仿真定义214n。通常来说,对于任何给定的协议,协议仿真定义214n都是相同的。可能变化的是任何具体的组件是否具有一组相同的协议仿真定义。例如,仿真容器308n不需要与不会在具体端口306n上执行的协议有关的协议仿真定义214n。
如下文所详细讨论的那样,组件从定义生成参考模型316n。参考模型316n存储下述数据,所述数据允许每个组件配置、执行并与其他组件通信。这种数据包括数据结构、配置数据、数据通信结构(和有效的方法)、命令和前述帮助它们使用的描述。
至少在一种实施方式中,利用下述消息实现到仿真控制304去和从仿真控制304来的通信,其中利用参考模型316n中包含的信息创建(或实例化)所述消息。术语称作“包(parcels)”的这些消息可以包含数据或命令。命令可以被用来指示仿真控制304采取动作,例如创建协议仿真会话。数据可以包括对于完成命令或者用于从仿真控制304或向仿真控制304报告数据所必需的消息。具体地说,包被用来传输数据,包括在参考模型的其他段中所引用的数据,例如包括与<filter>标签和<socket>标签相关联的信息。
仿真控制
图4是用于解释至少根据本发明的一种实施方式的仿真控制304的运行的方框图。仿真控制304提供了API 410,以接口到客户420,其中客户420例如是GUI 310(见图3)。API 410提供集中的管道,用作从客户420来和到客户420去的命令和数据的通路。根据至少一种实施方式,客户420可以包括具有代理控制314(见图3)的任何设备或软件。
API 410一般负责在客户420与仿真控制304之间创建并传输消息。类似地,在仿真容器308n中提供API 412来在协议状态机422与仿真控制304之间充当管道。如下所述,至少在某些实施方式中,基于协议仿真定义文件214中的<parcel>标签内包含的数据创建消息。消息创建过程基本上包括基于协议仿真定义文件214的内容创建参考模型,随后基于该参考模型或者它的一部分实例化对象,在待审查美国申请No.10/851,303中更完整地描述了该过程。用来自任何数目的源的数据填充对象,所述源包括协议仿真定义文件214、基于该协议仿真文件214创建的参考模型和用户。通过在API外部的文档中预定义数据结构,不需要仿真具体规定就能以通用的方式构造该API。在下文中讨论诸如使得能够实现通用用户接口和减少的消息带宽之类的其他好处。
API 410形成并传输的消息执行多种功能。这些功能之一是创建、配置和移除会话。如上面所提到的,这里所使用的术语会话一般指协议仿真的实例。表1是描述与仿真控制之间的管理接口的自文档化C++代码的一部分,其形成适于与API 410、API 412和代理控制314n一起使用的API的一部分。
表1
#ifndef APF_EMULATION_CONTROL_H#define APF_EMULATION_CONTROL_H//=====================================================================================////=库// APF安捷伦协议框架////=文件名// apfEmulationControl.h////=描述////仿真控制框架////=作者// GeoffSmith////=版权// (C)Copyright 2004安捷伦科技////=====================================================================================#include″apfParcelStore.h″#include″apfParcelLink.h″//-----------------------------------------------------------------------//=标题// 仿真控制接口////=类类型// 接口////=描述// 到仿真框架的管理接口classAPB_EXPORT_CLASS IApfEmulationControl{public:virtual~IApfEmulationControl(){}//=仿真信息//用唯一的仿真名定义每种协议仿真定义virtual voidlistEmulations(AtoList<AtoString>& emulationList)const=0;//列出用XML定义的仿真名virtual IApfRefEmulation*getRefEmulation(const AtoString& aEmulation)=0;//访问用于仿真的参考数据库virtual IApfRefEmulation*getRefEmulation(uint32_t aSession)const=0;//访问由会话句柄识别的仿真的参考数据库//=会话管理//可以从指定的仿真创建一个或多个仿真会话 |
virtual uint32_tcreateSession(uint32_t aPort,const AtoString& aEmulation,uint32_t aIterationCount=1)=0;//添加新的仿真会话。返回唯一的会话句柄virtual voidremoveSession(uint32_t aSession)=0;//移除现有的仿真会话virtual voidremoveSessionsOnPort(uint32_t aPort=0;//移除在指定端口上运行的所有仿真会话virtual voidlistAllSessions(AtoVector<uint32_t>& sessionList)const=0;//列出所有端口上的所有仿真会话virtual voidlistPorts(Ato Vector<uint32_t& portList)const=0;//因为由应用管理端口,所以该方法不是必需的,//但是提供其是为了方便和用于测试virtual voidlistSessionsOnPort(uint32_t aport,AtoVector<uint32_t>& sessionList)=0;//列出指定端口上的仿真会话virtual boolisValidSession(uint32_t aSession)const=0;virtual boolisValidPort(uint32_t aPort)const=0;//=包存储virtual IApfParcelStore&sessionStore(uint32_t aSession)=0;virtual IApfParcelStore&globalStore()=0;//=会话命令*pG3OH const AtoString&sessionName(uint32_t aSession)const=0;//如果会话未知,则返回“未知”virtual EApbResultsetSessionName(uint32_t aSession,const AtoString& aName)=0;//可以从AgtEmu_GlobalSession.xml中定义的“sessionStatus”包获得会话状态virtual EApbResultsetSessionIterationCount(uint32_t aSession,uint32_t aIterationCount)=0;//设置会话迭代计数。最小有效迭代计数为1virtual EApbResultenableSession(uint32_t aSession)=0;//使能指定的会话,使能的会话可以处理并传输分组virtual EApbResultdisableSession(uint32_t aSession)=0;//禁用指定的会话。禁用的会话将不接收或传输分组。 |
virtual EApfSessionStatesessionState(uint32_t aSession)=0;//提取当前会话状态,同样可以从sessionStatus包获得virtual EApbResulttcpOpen(uint32_t aSession,const AtoString& aSocket)=0;//请求通过指定的TCP套接字的连接,因为该调用是非阻塞的,所以不可能立即在返回上打开该套接字virtual EApbResulttcpClose(uint32_t aSession,const AtoString& aSocket)=0;//关闭通过指定的TCP套接字的连接//分组传输virtual EApbResultsetTransmitCaptureMode(uint32_t aSession,EApfTransmitCaptureMode aMode)=0;virtual EApbResulttransmitPacket(uint32 t aSession,const AtoString& aSocket,const AtoByteString& aPacketData)=0;//通过指定的套接字传输指定的分组数据//=端口命令//可以从AgtEmu_GlobalPort.xml中定义的“portStatus”包中获得端口状态//消息日志virtual voidgetMessageLog(uint32_t aport)=0;virtual voidsetMessageTraceLevel(uint32_t aport,EApbMsgTraceLevel aTraceLevel)=0;virtual voidsetMessageLogMaxLines(uint32_t aPort,uint32_t aMaxLines)=0;//=实用工具virtual IApfParcelLink*parcelLink()=0;//为该仿真控制而访问入parcelLink接口virtual const AtoString&versionString() const=0;};#endif//APF_EMULATION_CONTROL_H |
为了帮助诸如仿真控制304与仿真容器308n之间的通信,可以在仿真控制304中创建一串缓冲区404n(在本实施例中是缓冲区404a至404e)。反过来,仿真容器308n在API 412的指引下,创建与仿真控制304中的缓冲区对应的一串缓冲区404n(在本实施例中是缓冲区404f至404j)。为每个由端口作主机的协议状态机创建相似的一串缓冲区。所使用的缓冲区类型可以由包类型在参考模型316中指定。例如,缓冲区类型可以表示为XLM包定义中的属性。或者,可以将其设计为可由诸如代理控制314n之类的客户应用配置。由包链接424连接这些缓冲区404n,其中所述包链接424一般包括串行通信路径。虽然图4图示了为图示的每种包类型提供匹配的缓冲区,但是,也可以证明在数据流是单向的情况下,只提供接收缓冲区是优选的。
尽管对于本发明的任何给定的实现,缓冲区404的确切的性质会变化,但是可以证明,为要在仿真控制304与仿真容器308n之间传递的每种类型的包创建分离的缓冲区404n是优选的。一般来说,包的类型由在其中封装的数据确定。存在多种缓冲区类型,依赖于如何使用包中的数据,这些缓冲区中的任一种都可以证明是有益的。可以证明,为不同的包类型定义不同的缓冲区类型是有益的。
一般来说,缓冲意味着暂时保持包(或者包的片断),直到接收(或者发送)系统准备好处理在包中所包含的数据。例如,为了最小化主机负载,客户可以从发送一侧的缓冲区拉包。或者,发送一侧可以将包推向接收一侧的多种类型的缓冲区,以优化响应。可以为每种包和/或包类型指定缓冲区类型。或者,可以将一组不同的缓冲区类型初始化,并且可以基于缓冲区的类型将消息存放到缓冲区中。在表2中公开了合适的缓冲区类型的某些示例:
表2
缓冲区类型 | 描述 |
Retain | (推)在循环缓冲区中保留所接收到的每个新包版本,直到由客户删除 |
Fifo | (推)将包置于FIFO缓冲区中,并且当客户读取的时候将其从缓冲区中删除 |
Nwest | (推)由最近到来的版本替代所缓冲的包。可以根据键值将具有指定的根键的包合并。这种特性允许来自许多源的包在目的地处被自动地合并到总的包中。 |
Fetch | (推)直到目的地请求,才将包发送到目的地存储 |
图4图示了为特定的包类型创建缓冲区,所述包类型包括会话数据、统计数据、路由池、路由池类型和全局统计数据。表3提供了对某些可能的包类型及其合适的缓冲区类型的更详细的描述。
表3
消息类型 | 定义上下文 | 缓冲区 | 描述 |
ParcelClass | 全局 | 最新 | 关于协议状态机的状态信息 |
SessionData | 每个会话 | 最新 | 与建立协议状态机相关联的数据 |
TopologySummary | 每个仿真 | 最新 | 协议状态机中关于拓扑的概述信息 |
DestinationPools | 全局 | 取回 | 用于流量集成的目的地地址信息 |
TopologyData | 每个仿真 | 取回 | 用于协议状态机的详细的拓扑数据 |
Globalstatistics | 全局 | 最新 | 预定义的统计数据 |
Statistics | 每个仿真 | 最新 | 每个仿真的统计数据 |
EventLog | 全局 | 取回 | 用于仿真的事件数据 |
messageTrace | 全局 | FIFO | 用于仿真的Tx/Rx消息跟踪 |
缓冲区和用于帮助它们运行的例程都是在这里称作包存储402和404的一组过程的一部分。在一种实施方式中,由API 410和412分别创建并维护包存储402和404的功能组件。包存储的其他功能包括存储并维护包参考模型,从该包参考模型可以将消息对象实例化。包对象自身被存储在缓冲区404中,并从缓冲区404被读取。表4是描述包存储的功能的自文档化C++代码的一部分。
表4
#ifndef APF_PARCEL_STORE_H#define APF_PARCEL_STORE_H//==========================================================================////=库// APF安捷伦协议框架////=文件名// ApfParcelStore.h////=描述 |
////到包存储的接口。定义的接口//IApfParcelStore//DECLARE_PARCEL_TYPE和DEFINE_PARCEL_TYPE//ApfParcel<ParcelType>//IApfParcelBuffer//ApfParcelBuffer<ParcelType>////=作者// Geoff Smith////=版权// (C)Copyright 2004安捷伦科技////===============================================================================#include″emuframework/include/apfParcel.h″class IApfParcelBuffer;//---------------------------------------------------------------------//=标题// 包存储////=类类型// 接口////=描述//到包存储的客户接口。为每个会话创建I ApfParcel Store接口//is created for each sessionclass APB_EXPORT_CLASS IApfParcelStore{public://=基础virtual~IApfParcelStore(){}//=访问virtual EApfStoreTypestoreType()const=0;virtual uint32_tsessionHandle()const=0;virtual const AtoString&sessionName()const=0;virtual uint32_tport()const=0;virtual IApfRefEmulation*refEmulation()const=0;virtual uint32_tmaxIteration()const=0;virtual IApfRefParcel*refParcel(const AtoString& aParcelName)const=0;//=发出分组 |
virtual voidsendParcel(const CApfParcel& aParcel)=0;//=进入命令分组//客户可以订阅,以在接收到特定的命令包时被通知virtual voidsubscribeCommandParcel(const AtoString& aParcelName,AtoObserverBC<CApfParcel>& aObserver)=0;virtual voidunsubscribeCommandParcel(const AtoString& aParcelName,AtoObserverBC<CApfParcel>& aObserver)=0;//=进入包缓冲区//根据包的缓冲区类型对进入的会话包进行缓冲//经由IApfParcelBuffer接口或者ApfParcelBuffer类型化的接口访问包//如果所请求的缓冲区不可用,则这些方法将返回Ovirtual IApfParcelBuffer*getBufferByName(const AtoString& aParcelName)=0;virtual IApfParcelBuffer*getBufferByClass(EApfParcelClass aClass)=0;virtual voidlistBuffers(AtoVector<IApfParcelBuffer*>& aBufferList)const=0;};//---------------------------------------------------------------------//=标题// 包类型声明和定义//为包对象提供编译时类型安全////=用法// 在头文件中:// DECLARE_PARCEL_TYPE(myParcel);//在cpp文件中:// DEFINE_PARCEL_TYPE(myParcel);////在cpp实现中:////假设IApfParcelStore& myStore已知://////创建某些包//ApfParcel<myParcel>parcel1(myStore);//ApfParcel<myParcel>parcel2(myStore);//ApfParcel<otherPcl>parcel3(myStore);//////赋值//parcel2=parcel1;//OK//parcel3=parcel1;//编译时错误//////将进入包缓冲区复制到包中//parcel2.refresh();//////发送包//parcel2.send();//////访问进入包缓冲区//ApfParcelBuffer<myParcel>bufl(myStore); |
//const ApfParcel<myParcel>& inParcel=bufl.typedParcel();//---------------------------------------------------------------------class APB_EXPORT_CLASS CApfParcelTypeBC{public:CApfParcelTypeBC(IApfParcelStore& aParcelStore,IApfRefParcel& aRefParcel);IApfParcelStore&getParcelStore();const IApfParcelStore&getParcelStore()const;IApfRefParcel&getRefParcel();const IApfRefParcel&getRefParcel()const;private:IApfParcelStore& m_parcelStore;IApfRefParcel& m_refParcel;};//---------------------------------------------------------------------class APB_EXPORT_CLASS ApfDynamicParcelType:public CApfParcelTypeBC{public:ApfDynamicParcelType(IApfParcelStore& aStore,IApfRefParcel& aRefParcel):CApfParcelTypeBC(aStore,aRefParcel){}};//---------------------------------------------------------------------#define DECLARE_PARCEL_TYPE(aParcelType_)class APB_EXPORT_CLASS aParcelType_:public CApfParcelTypeBC{public:aParcelType_(IApfParcelStore& aStore);};#define DEFINE_PARCEL_TYPE(aParcelType_)aParcelType_::aParcelType_(IApfParcelStore& aStore):CApfParcelTypeBC(aStore,*aStore.refParcel(#aParcelType_)){ATO_ENSURE(&getRefParcel()!=0,atoAbortCtorFailure,″Unable to create parcel type=″<<#aParcelType_);}template<class ParcelType>class ApfParcelBuffer;//---------------------------------------------------------------------//=标题// 类型化包////=类类型// 模板////=描述//类型安全包////由使用上面的DECLARE_PARCEL_TYPE/DEFINE_PARCLE_TYPEE宏所定义的类“ParcelType”来定义类型 |
template<class ParcelType>class ApfParcel:private ParcelType,public CApfParcel{public://=基础ApfParcel(IApfParcelStore& aStore,EApfParcelState aInitialState=APF_PARCEL_STATE_OPEN);ApfParcel(const ParcelType& aType,EApfParcelState aInitialState=APF_PARCEL_STATE_OPEN);//类型安全复制运算符和赋值运算符。//企图复制不匹配的包将导致编译时错误ApfParcel(const ApfParcel& aTypedParcel);ApfParcel& operator=(const ApfParcel& aTypedParcel);//非类型安全赋值运算符。//企图赋不匹配的包将导致运行时错误ApfParcel& operator=(const CApfParcel& aParcel);//=实用方法void send();//使用关联的包存储发送该包void refresh();//如果新的数据可用,则从进入包缓冲区更新该包ApfParcelBuffer<ParcelType>buffer();//创建到与该包类型相关联的进入包的类型化缓冲区接口//注意AfpParcelBuffer仅仅是接口-该方法不能创建新的缓冲区};//---------------------------------------------------------------------//=标题// 包缓冲区////=类类型// 接口////=描述//到进入包缓冲区的接口。缓冲区提供到在该缓冲区的寿命期间存在的单个包对象的访问//依赖于缓冲区类型,可以将进入包的更新排队,或者自动地将其应用到下面的包对象://缓冲区类型 动作//RETAIN & FIFO 将进入包排队,并且不改变包对象,除非包对象当前为关闭//NEWEST & FETCH 用进入包来更新包对象class APB_EXPORT_CLASS IApfParcelBuffer{public://=基础virtual~IApfParcelBuffer(){}//=包事件 |
virtual voidsubscribeBufferUpdates(AtoObserverBC<IApfParcelBuffer>& anObserver)=0;virtual voidunsubscribeBufferUpdates(AtoObserverBC<IApfParcelBuffer>& anObserver)=0;//=访问virtual EApfBufferTypebufferType()const=0;virtual const CApfParcel&parcel()const=0;//访问缓冲区包virtual const ApfParcel<ApfDynamicParcelType>&dynamicTypedParcel()const=0;//访问作为ApfParcel<ApfDynamicParcel Type>Type>的缓冲区包//该方法主要是要用于结合下面定义的类型化包缓冲区ApfParcel<ApfDynamicParcelType>一起使用//virtual voidfetchUpdate()=0;//向包的服务器发送请求,以发送包//主要是要用于缓冲区类型=FETCH。如果当前包状态为关闭的,则该方法必须用来更新包//缓冲区管理(仅仅FIFO和RETAIN缓冲区类型)virtual uint32_tbufferCount()const=0;//见下面的setMaxParcelCount()virtual voidpopBuffer()=0;//用缓冲区中的下一个包刷新包。客户必须确保bufferCount()>0。PopBuffer将缓冲区计数减1virtual voiduseBuffer(uint32_t aIndex)=0;//用指定的缓冲区条目刷新包。客户必须确保alndex<parcelCount。SetParcel()不影响包计数virtual voiddeleteBuffer(uint32_t aIndex)=0;virtual voidclearBuffers()=0;//删除所有的缓冲区//包缓冲区具有缺省最大缓冲区计数1//这避免了下述可能性:即当不是所有的代理都有活动客户来管理缓冲区时,//由多个代理将包接收到FIFO或RETAIN缓冲区中导致内存泄漏//如果客户需要缓冲区来保持多于一个包,则明确地设置最大计数virtual uint32_tmaxBufferCount()const=0;//缺省=1,用setMaxBufferCount()调整virtual void |
setMaxBufferCount(uint32_t aCount)=0;//只对RETAIN和FIFO缓冲区有效};//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.//=标题// 类型化的包缓冲区////=类类型// 模板////=描述//到包缓冲区模板<class ParcelType>的类型安全接口class ApfParcelBuffer:private ParcelType,public IApfParcelBuffer{public://=基础ApfParcelBuffer(IApfParcelStore& aStore);//=类型化的包const ApfParcel<ParcelType>&typedParcel()const;//到包的编译时类型安全访问//=IApfParcelBuffer方法voidsubscribeBufferUpdates(AtoObserverBC<IApfParcelBuffer>& anObserver);voidunsubscribeBufferUpdates(AtoObserverBC<IApfParcelBuffer>& anObserver);EApfBufferType bufferType()const;const CApfParcel& parcel()const;const ApfParcel<ApfDynamicParcelType>& dynamicTypedParcel()const;void fetchUpdate();uint32_t bufferCount()const;void popBuffer();void useBuffer(uint32_t aIndex);void deleteBuffer(uint32_t aIndex);void clearBuffers();uint32_t maxBufferCount() const;void setMaxBufferCount(uint32_t aCount);private:IApfParcelBuffer& m_buffer;};//*********************************************************************** |
//ApfParcel<ParcelType>实现//**************************************************************************template<class ParcelType>ApfParcel<ParcelType>::ApfParcel(IApfParcelStore& aStore,EApfParcelState aInitialState):ParcelType(aStore),CApfParcel(getRefParcel(),aInitialState){}//---------------------------------------------------------------------------template<class ParcelType>ApfParcel<ParcelType>::ApfParcel(const ParcelType& aType,EApfParcelState aInitialState):ParcelType(aType),CApfParcel(getRefParcel(),aInitialState){}//---------------------------------------------------------------------------template<class ParcelType>ApfParcel<ParcelType>::ApfParcel(const ApfParcel& aTypedParcel):ParcelType(aTypedParcel.getParcelStore()},CApfParcel(aTypedParcel){}//---------------------------------------------------------------------------template<class ParcelType>ApfParcel<ParcelType>&ApfParcel<ParcelType>::operator=(const ApfParcel<ParcelType>& aTypedParcel){//编译器确保在编译时类型匹配CApfParcel::assign(aTypedParcel,getParcelStore().storeType());return*this;}//---------------------------------------------------------------------------template<class ParcelType>ApfParcel<ParcelType>&ApfParcel<ParcelType>::operator=(const CApfParcel& aParcel){//如果在运行时类型不匹配,则将断言赋值CApfParcel::assing(aParcel,getParcelStore().storeType());return*this;}//---------------------------------------------------------------------------template<class ParcelType>voidApfParcel<ParcelType>::send(){getParcelStore().sendParcel(*this);}//---------------------------------------------------------------------------template<class ParcelType>voidApfParcel<ParcelType>::refresh(){ApfParcelBuffer<ParcelType>buffer(getParcelStore());const ApfParcel<ParcelType>& in=buffer.typedParcel();if(in.parcelState()==APF_PARCEL_STATE_OPEN && in.isParcelChanged()){CApfParcel::assign(in,getParcelStore().storeType());}} |
//--------------------------------------------------------------------------template<class ParcelType>ApfParcelBuffer<ParcelType>ApfParcel<ParcelType>::buffer(){return ApfParcelBuffer<ParcelType>(getParcelStore());}//**************************************************************************//ApfParcelBuffer<ParcelType>实现//**************************************************************************template<class ParcelType>ApfParcelBuffer<ParcelType>::ApfParcelBuffer(IApfParcelStore& aStore):ParcelType(aStore),m_buffer(*aStore.getBufferByName(getRefParcel().name())){}//---------------------------------------------------------------------------template<class ParcelType>const ApfParcel<ParcelType>&ApfParcelBuffer<ParcelType>::typedParcel() const{//m_buffer.dynamicTypedParcel()返回//ApfParcel<ApfDynamicParcelType>&,其被小心地构造来在除了构造器外的各个方面//与ApfParcel<ParceType>相匹配//由于对象已被构造,所以其对reinterpret_cast是安全的。返回reinterpret_cast<const ApfParcel<ParcelType>&>(m_buffer.dynamicTypeParcel)}//---------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::subscribeBufferUpdates(AtoObserverBC<IApfParcelBuffer>& anObserver){m_buffer.subscribeBufferUpdates(anObserver);}//---------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::unsubscribeBufferUpdates(AtoObserverBC<IApfParcelBuffer>& anObserver){m_buffer.unsubscribeBufferUpdates(anObserver);}//---------------------------------------------------------------------------template<class ParcelType>EApfBufferTypeApfParcelBuffer<ParcelType>::bufferType()const{return m_buffer.bufferType();}//---------------------------------------------------------------------------template<class ParcelType>const CApfParcel&ApfParcelBuffer<ParcelType>::parcel() const{ |
return m_buffer.parcel();}//--------------------------------------------------------------------------template<class ParcelTyPe>const ApfParcel<ApfDynamicParcelType>&ApfParcelBuffer<ParcelType>::dynamicTypedParcel()const{return m_buffer.dynamicTypedParcel();}//--------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::fetchUpdate(){m_buffer.fetchUpdate();}//--------------------------------------------------------------------------template<class ParcelTyPe>uint32_tApfParcelBuffer<ParcelType>::bufferCount()const{return m_buffer.bufferCount();}//--------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::popBuffer(){m_buffer.popBuffer();}//--------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::useBuffer(uint32_t aIndex){m_buffer.useBuffer(aIndex);}//--------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::deleteBuffer(uint32_t aIndex){m_buffer.deleteBuffer(aIndex);}//--------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::clearBuffers(){m_buffer.clearBuffers();}//--------------------------------------------------------------------------template<class ParcelType>uint32 t |
ApfParcelBuffer<ParcelType>::maxBufferCount()const{return m_buffer.maxBufferCount();}//--------------------------------------------------------------------------template<class ParcelType>voidApfParcelBuffer<ParcelType>::setMaxBufferCount(uint32_t aCount){m_buffer.setMaxBufferCount(aCount);}//--------------------------------------------------------------------------#endif//APF PARCEL STORE H |
可以配置包存储402a来保留发送到仿真容器308n的每个包的最近的拷贝。利用这种配置,通过在包存储402a中保存包括最近传输的包在内的包,可以实现保存仿真控制304的当前配置的备份功能。通过序列化每个活动会话实现备份。通过在包存储中序列化所有的包将每个活动会话序列化。然后通过重新创建每个保存的会话,并且用保存的包来将其填充,可以恢复配置。
仿真容器
仿真容器308一般在GPF 210与诸如协议状态机308n之类的嵌入的定制组件之间起接口作用。仿真容器308接收序列化的包的形式的消息、重建包、并且将包中的数据分发到嵌入的定制组件中的组件。反过来,仿真容器308从嵌入的定制组件中的组件接收数据、基于其创建包、并且将所述的包传输到仿真控制304。在协议仿真系统的上下文中,每个会话都具有依次与仿真控制304通信的仿真容器308n。
图5是根据本发明实施方式的通用协议会话模型的方框图。一般来说,在测试端口上运行的协议状态机(以及相关的支持代码)的实例称作会话。图5图示了在两个端口306x和306y上运行的八个会话S1-S8。端口306n和会话Sn对仿真控制304作出响应,其中仿真控制304维护表502来跟踪各个会话。
仿真控制304为每个会话提供API服务和缓冲区。如上文所述,API和缓冲区帮助实现仿真控制304与会话Sn之间的通信。仿真容器308m和308n为在端口306n上运行的每个会话提供API和缓冲区。仿真容器308n负责创建和删除指定端口306n上的会话。
每个会话Sn需要数种资源来运行。这些资源包括:硬件模式匹配;以在其上运行的套接字(例如TCP/IP套接字);以及用于通信和控制的API。图6是根据本发明实施方式的协议基础设施的方框图。在图6中,示出了协议状态机602,其与API 604(其可能是图4中示出的API 412的实例)、套接字管理器606和匹配器管理器608通信。API 604、套接字管理器606和匹配器管理器608共同形成仿真容器308(见图3和图4)的实施方式。
启动时API 604基于协议仿真定义文件610生成参考模型。协议仿真定义文件610是协议仿真定义文件214的拷贝,其应当意味着在API 604控制下生成的参考模型与在API 410控制下生成的参考模型相匹配。从而,API 504利用实例化的包的实例,能够与主机302上的仿真控制304(见图3)通信。
API 604从仿真控制304接收数据,并且将数据分发到仿真容器的其他组件和协议状态机602。反过来说,API 604从仿真容器308的其他组件和协议状态机602接收数据,并且将其转发到仿真控制304。利用上文所述的包存储串和与它们相伴随的缓冲区,可以实现与仿真控制304的通信。
API 604还管理协议状态机602、匹配器管理器608和套接字606的配置数据。在一种实施方式中,配置参考模型来存储关于具体仿真类型的所有会话的静态信息。套接字管理器606通过读取从仿真控制304传输来的值(例如使用会话数据包),将关于具体会话的静态信息与易失信息结合起来。可以配置参考模型中的套接字定义来交叉引用会话数据包中的值。
套接字管理器606建立并维护通信信道。在图6中示出的实施例中,套接字管理器606维护TCP/IP栈606a。当仿真容器308n中的协议仿真会话被使能时,参考由API 604构建的参考模型来寻找该会话所需要的套接字配置。对于每个套接字,套接字管理器606使用参考模型来构建所需的套接字。可以为每个会话、每个接口单独地创建套接字,或者为容器全局地创建套接字。因此,套接字管理器606维护由多个会话共享的套接字引用计数。例如,当使用全局套接字时,在会话第一次请求套接字时创建该套接字。为后来的会话分配已存在的套接字,而不是创建一个新的套接字。只有在使用全局套接字的所有会话都被禁用或者销毁时,才销毁该全局套接字。
仿真匹配管理器608管理也被称作“过滤器”的硬件匹配器。过滤器可以用来选择由协议状态机602从被测路由器接收的协议消息的消息或者该消息的多个部分。可以存储所选择的消息用于分析和作报告。于2004年6月15日提交的美国专利申请号为10/861,618的待审查申请中讨论了这种过滤器的一种可能的实现方式,该申请被结合于此作为参考。当协议仿真会话在仿真容器308n内被使能时,参考参考模型来寻找该会话所需要的过滤器。对于每个过滤器,匹配器管理器608(或者过滤器管理器)使用参考模型来构建所需要的过滤器。通常来说,过滤器由参考模型中的静态信息完整定义。过滤器可以由相同类型的所有会话共享。因此,匹配器管理器608维护引用计数,以确保硬件资源不会因为创建具体类型的过滤器副本而不必要地消耗。当会话被禁用时,只有当使用相应过滤器的所有会话都被禁用时才移除该过滤器。
代理控制
参考图3,代理控制器314n一般包括与上文所述的那些API相似的API和关联的协议仿真定义文件。这种API为与主机302上的仿真控制304通信提供方便的封装解决方案。因为使用包对象实现了消息传递,所以对仿真的控制可以驻留在具有创建包对象的能力的任何设备中,例如任何具有合适的API的设备。在图3所示的实施例中,将代理控制器314a和314b提供给GUI 310和Tcl API 312。这种嵌入设计准许用Tcl脚本控制会话,包括创建、配置、控制和删除会话。
可以通过实现表1中所提出的IapfEmulationControl来形成代理控制器314n。每个代理控制314n维护与仿真控制304中的参考模型相同的参考模型316n。每个代理控制器314n向相关联的仿真控制304注册。当仿真控制304从容器308n接收到包时,将该包不作改变地转发到每个注册过的代理控制314n。类似地,当代理控制314n向容器308n发送包时,经由仿真控制304发送该包。仿真控制304保留包的拷贝,并且将其复制到任何其他代理控制器314n。这样,仿真控制304和所有的代理控制314n都维持包缓冲区404n的镜像集合(见图4)。驱动客户接口的就是包缓冲区404n的这个集合。
TCL接口
表5是示出了使用Tcl中创建的接口的实施例的屏幕快照,所述接口用于经由仿真控制来控制端口上的会话。
表5
C:Program FilesAgilentN2XRouterTester9006.4.0.0bin>tclsh83%load emuframework.dllGeneric Protocol FrameworkType″gpfServerHostname<host>″to use a remote server″gpfConnect <session>″to connect to a test session″gpfDisconnect″to disconnect from the session%gpfConnect1Gcneric Protocol Framework().Copyright(C)2004 Agilent TechnologiesType″gpfHelp″for list of commandsGlobal%Global%gpfCreateSession 2 bgp4 lbgp4-2%gpfListBuffersbgpSessionData packetCapture test_parcel2bgp4-2%gpfCreateParcel bgpSessionData0bgp4-1 bgpSessionData%gpfHelpParcelParameters for bgpSessionData:local_port=integer(default=179)remote_port=integer(default=179)subinterface=integer(default=0)prefix_length=integer(default=24)local_ip=ipv4_address(default=0.0.0.0)remote_ip=ipv4_address(default=0.0.0.0)server_port=integer(default=0)server_ip=ipv4_address(default=0.0.0.0)bgp4-1 bgpSessionData%gpfSetValues local_ip=192.1.1.2,remote_ip=192.1.1.1,subinterface=1000bgp4-1 bgpSessionData%gpfPrintParcelbgp4 Parcel,class=sessionData,9 nodes-showing current rows onlyCurrent node:3 subinterface0 Set″bgpSessionData″8 members:local_port(1),remote_port(2),subinterface(3),prefix_length(4),local_ip(5),remote_ip(6),server_port(7),server_ip(8)1 Value″local_port″=1792 Value″remote_port″=179* 3 Value″subinterface″=l004 Value″prefix_length″=245 Value″local_ip″=192.1.1.26 Value″remote_ip″=192.1.1.17 Value″server_port″=08 Value″server_ip″=0.0.0.0bgp4-l bgpSessionData%bgp4-1 bgpSessionData%gpfSendParcel |
使用诸如Tcl的脚本语言可以复制由协议状态机308n执行的功能。本质上,应当使用XML标签定义各种协议状态,并且一组Tcl过程应当被嵌入到定义214n中来处理状态转变。可以随同编码服务库一起将解码服务库提供给Tcl解释器,其中所述编码服务库用于对用于发送的PDU流执行编码,所述解码服务库用于对入PDU流执行解码。表6是结合注释中所描述的适当的Tcl函数的XML文件,其可以用来模拟GPF 210内的协议状态机的某些功能。
表6
<?xml version=″1.0″standalone=″yes″?><EmulationSet xmlns=″x-schema:AgtEmulSchema.xml″version=″1″providedBy=″Agilent Technologies″><!-- -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- --><!-- 安捷伦协议框架 --><!-- -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- --><!-- 文件类型:协议仿真 --><!-- 内容:MLD版本1 --><!-- -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- --><!-- Copyright 2004安捷伦科技 --><!-- -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- --><filter name=″ICMPv6_routerAlert″><!-- 硬件模式匹配器--><!-- 逐跳选项(用于路由器报警) --><hwMatch type=″ipv6_emulation″offset=″48″length=″8″value=″0″/><!-- ICMPv6 --><hwMatch type=″ipv6_emulation″offset=″320″length=″8″value=″58″/></filter><!-- 仿真 --><emulation name=″MLDvl″standard=″RFC 2710″protocols=″IPv6 ICMP_v6″filter=″ICMPv6_routerAlert″><!-- 会话概述 --><parcel name=″mldSessionSummary″type=″data″class=″se<value name=″num_address_pools″fullName=″Number of address pools″length=″32″format=″integer″/><value name=″num_addresses″fullName=″Number of addresses″length=″32″format=″integer″/></parcel><!--会话数据--><!--定义每个仿真会话使用的变量--><parcel name=″mldSessionData″type=″data″clasa=″sessionData″> |
<value name=″tester_ll_address″fullName=″Tester IPv6 link-local address″length=″128″defaultBinding=″tester_native_ipv6_ll_address″format=″ipv6_address″/><value name=″sub_interface″fullName=″Sub-interface identifier″length=″32″defaultValue=″0″format=″integer″/><value name=″robustness″fullName=″Robustness variable″length=″16″format=″integer″defaultValue=″2″/><value name=″queryResponseInterval″fullName=″Query response interval (mSec )″length=″32″format=″integer″defaultValue=″10000″/><value name=″unsolicitedReportInterval″fullName=″Query response interval (mSec)″length=″32″format=″integer″defaultValue=″10000″/></parcel><!--拓扑概述--><parcel name=″mldTopologySummary″fullName=″MLD Topology summary″class=″topologySummary″><use ref=″mldSessionData:tester_ll_address″/><use ref=″mldSessionData:sub_interface″/></parcel><!--拓扑数据 --><parcel name=″poolList″fullName=″Multicast address pools″class=″topologyData″><parcel ref=″:destinationPools″/></parcel><!--统计--><!--这里定义的任何统计量是预定义统计量的补充statistics--><parcel name=″mldStats″class=″statistics″fullName=″MLD Version 1 Statistics″><value name=″ReportMessagesSent″fullName=″Outgoing MLD Report messages count″type=″count″length=″32″format=″integer″/><value name=″DoneMessagesSent″fullName=″Outgoing MLD Done messages count″type=″count″length=″32″ |
format=″integer″/><value name=″QueryMessagesReceived″fullName=″Incoming MLD Query messages count″type=″count″length=″32″format=″integer″/><value name=″ReportMessagesReceived″fullName=″Incoming MLD Report messages count″type=″count″length=″32″format=″integer″/><value name=″MulticastAddressCount″fullName=″Number of active multicast addresses″type=″count″length=″32″format=″integer″/></parcel><!--绑定--><bind name=″mldSocket″socketType=″subinterface″subInterface=″$sub_interface″filter=″ICMPv6_routerAlert″><importPdu protocol=″IPv6″packetType=″″><decodeMatch pdu=″mldQuery″protocol=″ICMPv6″protocolInstance=″1″field=″mld_query_v1″statistic=″QueryMessagesReceived″proc=″onMldQuery″/><decodeMatch pdu=″mldReport″protocol=″ICMPv6″protocolInstance=″1″field=″mld report v1″statistic=″ReportMessagesReceived″proc=″onMldReport″/></importPdu></bind><tclProc name=″onMldQuery″>set multicastAddress [value [findElement ICMPv6 multicast_address 1]]aebLog info ″MLD Query message received for address:[formatValue$multicastAddress ipv6_address]″# notify the state machine of the incoming packet. Notification willbe dropped# if no instance is present for $multicastAddressaebNotify mld_listener $multicastAddress query_received</tclProc><tclProc name=″onMldReport″>set multicastAddress[value[findElement ICMPv6 multicast_address 1]]aebLog info″MLD Report message received for address:[formatValue$multicastAddress ipv6_address]″# notify the state machine of the incoming packet.Notification willbe dropped if no# instance is present for $multicastAddress |
aebNotify mld_listener $multicastAddress report_received</tclProc><!--命令--><command name=″join″fullName=″Join a set of multicast addresses″proc=″join″><parcel ref=″poolList″/></command><command name=″leave″>fullName=″Leave a set of multicast addresses″proc=″leave″/><parcel ref=″poolList″/></command><command name=″leaveAll″fullName=″Leave all multicast addresses″proc=″leaveAll″/></command><command name=″listPools″fullName=″List all multicast pools″proc=″listPools″event=″poolList″/><!--会话专用数据--><value name=″allRoutersMcastAddress″fullName=″All routers multicast address″length=″128″format=″ ipv6_address″value=″0xff02 0000 0000 0000 0000 0000 0000 0001″/><!--PDU模板--><pduTemplate name=″reportPdu″protocol=″″packetType=″MLD″proc=″createReportPdu″/><pduTemplate name=″donePdu″protocol=″″packetType=″MLD″proc=″createDonePdu″/><tclProc name=″createReportPdu″>set eIcmp [findProtocol″ICMP_v6″1]setContainedElements $eIcmp mld_report_v1set eSrcAddr [findElement″IPv6 source_address 1″]setValue $eSrcAddr $tester_ll_address</tclProc><tclProc name=″createDonePdu″>set eIcmp [findProtocol″ICMP_v6″1]setContainedElements $eIcmp mld_doneset eSrcAddr [findElement″IPv6 source_address 1″]set eDstAddr [expr $eSrcAddr+1]setValue $eSrcAddr $tester_ll_addresssetValue $eDstAddr $allRoutersMcastAddress</tclProc><!--命令实现--><tclProc name=″join″packet=″poolList″># Check whether this is a new pool or a changed poolif {[packetChanged″poolList″]}{# Existing pool-delete the old one firstleave |
}# Create the new poolset poolFirstAddr($handle) $firstAddrset poolModifier($handle) $modifierset poolCount($handle) $countfor{set i O}{$i<$count}{incr i}{set addr [aebCalculateIpv6Address $firstAddr $modifier $i]if {[info exists stateMachineRefCount($addr)]}{incr stateMachineRefCount{$addr)} else {set stateMachineRefCount($addr) 1aebCreate mld_listener $addr}}</tclProc><tclProc name=″leave″parameters=″handle″>if {[info exists $poolFirstAddr($handle) == 0] {aebLog error ″Leave command for unknown handle $handle″} else {aebLog info″Leaving pool $handle″for {set i O] ($i<$poolCount($handle)} {incr i} {set addr[aebCalculateIpv6Address $poolFirstAddr($handle)$poolModifier($handle) $i]if {[info exists stateMachineRefCount($addr)} {incr stateMachineRefCount($addr) -1if {stateMachineRefCount($addr) == 0) (aebNotify mld_listener $addr stop_listeningunset stateMachineRefCount($addr)}}}}</tclProc name=″leaveAll″>foreach handle [array names $poolFirstAddr] (leave $handle}</tclProc><tclProc name=″listAddresses″>aebCreatePacket poolListforeach handle [array names $poolFirstAddr] {aebAppendList pool_list {$handle $poolFirstAddr($handle)$poolModifier($handle) $poolCount($handle)}}aebSendEvent poolList</tclProc><!--状态机--><stateMachine name=″mld_listener″>createProc=″listenToAddress″createParameter=″multicast_address″firstState=″delaying_listener″><!--状态机变量(由框架为每个状态机实例维护)machine instance)--><value name=″smMulticastAddress″fullName=″Multicast Address″format=″ipv6_address″/><value name=″smActiveFlag″defaultValue=″1″/><value name=″smDelayTimeout″defaultValue=″$unsolicitedReportInterval″/> |
<!--状态定义--><state name=″delaying_listener″><onEntry><startTimer name=″delay_timer″minTimeout=″0″maxTimeout=″$smDelayTimeout″expireAction=″timer_expire″/><tclEval″set smDelayTimeout $queryResponseInterval″></onEntry><action name=″stop_listening″fullName=″Stop listening to a multicast address″proc=″sendDoneIfActive″newState=″aebDestroyInstance″/><action name=″report_received″fullName=″Report for this address received from another node″newState=″idle_listener″pdu=″mldReport″><tclEval″set smActiveFlag 0″/><stopTimer name=″delay_timer″/></action><action name=″timer_expire″fullName=″Delay timer expired″proc=″sendReport″newState=″idle_listener″><tclEval″set smActiveFlag 1″/></action><action name=″query_received″fullName=″Query received from router″proc=″conditionalResetTimer″></action></state><state name=″idle_listener″<action name=″query_received″fullName=″Query received from router″newState=″delaying_listener″><action name=″stop_listening″fullName=″Stop listening to a multicast address″proc=″sendDoneIfActive″newState=″aebDestroyInstance″/></state><!--State machine procedures--><tclProc name=″listenToAddress″parameters=″multicast_address″>set smMulticastAddress $multicast_addresssendReport</tclProc><tclProc name=″sendReport″>copyPdu reportPduset eDstAddr [findElement″IPv6 destination_address 1″]# report messages are sent to the address being reportedsetValue $eDstAddr $smMulticastAddressset eMrd [findElement ICMPv6 max_response_delay 1]set eAddr [expr $eMrd + 2];# mcastAddress is 2nd field past mrdsetValue $eMrd $smDelayTimeoutsetValue $eAddr $smMulticastAddressaebSendPdu mldSocketaebLog info″MLD report sent for [formattedvalue $addrelem]″ |
aebIncrementStatistic ReportMessagesSent</tclProc><tclProc name=″sendDoneIfActive″>if{$smActiveFlag==0}{return}copyPdu donePduset eMrd [findElement ICMPv6 max_response_delay 1]set eAddr [expr $eMrd + 2];# mcastAddress is 2nd field past mrdsetValue $eMrd $smDelayTimeoutsetValue $eAddr $smMulticastAddressaebSendPdu mldSocketaebLog info″MLD done sent for {formattedvalue $addrelem]″aebIncrementStatistic DoneMessagesSent</tclProc><tclProc name=″conditionalResetTimer″># Current pdu is an mld query-retrieve the max responseset maxResponse [value [findElement ICMPv6 max_response_delay 1]]aebLog info″Received MLD query max response=$maxResponse″if {$maxResponse==0 || [aebGetTimer delay_timer] <$maxResponse} {aebExpireTimer delay_timer ;# will trigger timer action}</tclProc></stateMachine></emulation><!-- ==================================================================== --></EmulationSet> |
可以创建提供简单仿真和一致性测试的Tcl脚本。配置仿真容器308n来将由端口接收到的协议分组传递到Tcl API 312的控制。类似地,仿真容器308n可以配置来将Tcl API 312生成的协议分组传递过被测网络。TclAPI 312可以配置来与分组建立软件相接口,例如在美国专利申请序列号为No.10/266,507、公开号为No.US20040068681 A1的申请中所公开的那样。或者,通过使得状态机可基于与协议仿真定义214在格式上相似的定义来配置,可以将本发明的某些概念扩展到协议状态机。
GUI
在可能是优选的实施方式中,以通用的方式构建GUI 310,其中显示器上元素的布局响应于消息参考模型和对象的结构。参考图3,利用协议仿真定义214n驱动GUI 310,在仿真定义214n中,可以为每个将要显示的数据片断创建属性,该属性描述将如何格式化该显示。类似地,如果需要来自用户的输入,则可以使用这种输入所寻求的数据元素的属性来将寻求这种输入的显示格式化。GUI 310将具有预先设计并建造的对话框,用于数据的每个主要功能模块,这或许是有益的。每个模块的显示格式将根据实现方式而变化;然而,可以证明为每个模块提供其自己的窗口是有益的。GPF对话框的特定内容(字段、列等)将由所接收到的数据填充。
主要功能块的适当列表的一个实施例包括:会话管理器、会话编辑器、拓扑编辑器、会话统计、会话日志和消息跟踪。会话管理器模块可以包括用于创建、删除、使能和禁用会话的数据,以及会话状态和摘要信息的视图。会话编辑器模块可以包括用于创建、浏览和编辑诸如SUT地址、选项和计时器之类的会话全局数据的数据。拓扑编辑器模块可以包括用于创建诸如模拟的路由或路由器之类的会话拓扑视图的数据。拓扑编辑器模块还可以包括用于发送命令和将PDU注入仿真会话的功能。会话统计模块可以提供每种会话类型所特有的实时统计的视图。会话日志模块可以提供由每个会话生成的事件消息日志的视图。最后,消息跟踪模块可以提供由每个会话发送和接收的消息的实时消息跟踪的视图。
协议仿真定义
也许本发明实施方式的基础概念是使用逻辑上在GPF 210外的协议仿真定义。图7是XML标签层次结构,其适于在根据本发明实施方式的通用协议框架中使用。根据本发明的某些实施方式,基于利用图7中阐述的XML标签层次结构的协议仿真定义文件来形成参考模型。虽然将协议仿真定义描述为使用XML格式,但是本领域的普通技术人员将认识到可以使用其他格式。更具体地说,是要用易于访问的格式来格式化协议仿真描述,以便于创建和修改协议仿真描述。
文件的优选数据结构是层次结构,其中每个节点可以包含值、子节点、函数、值数组或值表。由XML提供的嵌套标签结构便于实现层次关系和表结构的文档。消息定义可以与下述文本文件一样简单,所述文本文件提供一列功能单元,并且指定包括每个功能单元的元素(这里称作“节点”)、每个节点的类型和节点的相互关系。可以用描述性属性来标注每个节点(示例将在下文讨论)。
仿真定义文件的每节可以包括头部和一组元素。元素一般分为两类,提供结构的包容器(container)元素和存储一个值或一串值的数据元素。XML标签可以用来组织头部和元素。例如,可以在<emulationset>标签中封装单独的一类协议仿真所需要的数据和命令。在<emulationset>标签中,可以基于元素的功能进一步组织这些元素。参见图7,其示出了一种可能的组织方案,其中用下述标签封装元素:<parcel>,<command>,<filter>,<emulation>和<enumset>。
在待审查美国专利申请No.10/851,303中讨论了<parcel>节的形式和格式。<command>节遵循与<parcel>节相同的基本格式。在表7中示出了用于<parcel>消息段的一组元素类型的实施例。
表7
元素类型 | 包容器 | 描述 |
值 | 否 | 单个值(布尔,数字或字符串)。可以为任何长度的值 |
数组 | 否 | 一组同质值(都是相同的类型) |
集合 | 是 | 包含其他包元素的包元素,例如值、数组、集合、表或键表 |
表 | 是 | 表。表的每个成员代表一列。表中的行被编索引 |
键表(keyedtable) | 是 | 表。表的每个成员代表一列。必须是值的一列被指定为键列。表中的每一行在该键列中必须具有唯一的值。通过键值访问行 |
可以用XML定义来定义由API所使用的命令。这可以通过添加间接级实现,所以API自身只提供少数常规命令,而不是具有数以百计的协议特有命令的API。例如,表8中描述的命令代表最低要求的命令集合,该命令集合准许用户识别并调用在协议定义中所定义的命令。
表8
命令 | 参数 | 目的 |
ListCommands | 仿真名或空白 | 列出可用于仿真的命令,或如果没有指定仿真,则列出全局命令 |
Help | 命令名 | 显示关于命令的帮助信息 |
invoke | XML定义的命令和参数 | 调用命令 |
可以在协议仿真定义214n中定义为每种仿真提供的命令。例如见表9:
表9
<command name=”setKeepalive”fullName=”Set the value of the Keep alivetimer”><value name=”keepalive”fullName=”Keepalive Value”length=”16”defaultValue=”100”/></command> |
在这种简单的情形中,所需求的参数被定义为一个或多个值。在其他情况中,将命令参数定义为包中的表行是有用的,例如见表10:
表10
<command name=”advertise”fullName=”Advertise route pool”><use rowRef=”routePools”/></command> |
对于这种实例,我们可以假设已经定义了称作“routePools”的包,这是一个表,对于该表,其每行代表单个路由池。命令“advertise”在路由池上运行,并且我们用“rowRef”属性将二者相关联。
命令的这种风格对于GUI非常有用,因为其允许用户选择路由池表中的行,并且点击“advertise”。命令定义允许自动地将适当的命令和参数相关联。
在待审查美国申请10/861,618中讨论了用于<filiter>节的一种可能的实现方式。在一种实施方式中,为<filter>定义单个标签<hwMatch>。由于过滤器一般被格式化为预定义的位流,所以<hwMatch>包含与实现的仿真匹配器直接对应的位流(以二进制或者十六进制)。为了示例,用于安捷伦路由器测试仪900的<hwMatch>参数为IP协议id和IP有效载荷的前32位,以及关联的掩码。总地来说,<hwMatch>标签的有效载荷仅仅包含对硬件接口编程所需要的数据。
<emulation>节包含关于特定协议仿真的<socket>和<parcel>标签。<emulation>也可以引用一个或多个在<emulation>外定义的过滤器。
表11包含用于<socket>消息段的元素类型的示例集合。
表11
元素类型 | 描述 |
Enumset | 名/值对的表-见下面的描述 |
Option | 定义套接字选项。支持所有的标准TCP/IP套接字选项 |
Parameter | 指定用来配置套接字的参数。示例参数包括:localPort、remotePort、localAddress、remoteAddress、subInterface、prefixLength和protocol。不同的套接字类型(例如BPF、Raw或TCP客户)具有不同的需求,因为参数对于其是强制的。可以用XML静态地指定参数值,或者可以引用sessionData包中的值 |
TcpReassembly | TCP套接字提供流接口。多数应用要求将TCP有效载荷组装到离散的分组中,通过嵌入在数据中的长度字段识别。这种标签用来对用于执行这种操作的TCP重新组装例程进行编程 |
bpfMatch | BPF套接字是通用的第2层套接字,其用工业标准“伯克利分组过滤器”软件匹配器来选择分组。传统上,BPF过滤器是由嵌入式软件硬编码的。在GPF中,<bfpMatch>标签提供简单的XML接口,用于从仿真定义出发对BPF过滤器编程 |
表12包含说明<filter>和<socket>节的一段协议仿真定义。
表12
<?xml version=″1.0″standalone=″yes″?><EmulationSet version=″1″providedBy=″Agilent Technologies″><!--Copyright 2004安捷伦科技--><!--==========================================================================--><!--注意:protocolMask默认为0xFF,dataMask默认为0xFFFFFFFF--><filter name=″bgp4_filter″><hwMatch type=″ipv4″protocolValue=″6″dataValue=″0xb3″dataMask=″0xffff″/><hwMatch type=″ipv4″protocolValue=″6″dataValue=″0xb30000″dataMask=″0xffff0000″/><hwMatch type=″ipv6″protocolValue=″6″dataValue=″0xb3″dataMask=″0xffff″/> |
<hwMatch type=″ipv6″protocolValue=″6″dataValue=″0xb30000″dataMask=″0xffff0000″/></filter><filter name=″isis_filter″><hwMatch type=″bpf″/></filter><emulation name=″bgp4″filters=″bgp4_filter″><socket name=″clientSkt″id=″1″type=″tcp″role=″client″instance=″session″><tcpReassembly offset=″128″length=″16″lengthMultiplier=″8″/><option name=″so_linger″value=″0″/><option name=″so_reuseaddr″value=″0″/><option name=″ip_ttl″value=″1″/><option name=″ip_tos″value=″64″/><parameter name=″local_jp″purpose=″local_address″valueRef=″bgpSessionData:local_ip″/><parameter name=″remote_ip″purpose=″remote_address″valueRef=″bgpSessionData:remote_ip″/><parameter name=″remote_port″purpose=″remote_port″valueRef=″bgpSessionData:remote_port″/><parameter name=″subinterface″purpose=″subinterface″valueRef=″bgpSessionData:subinterface″/><parameter name=″prefix_length″purpose=″prefix_length″valueRef=″bgpSessionData:prefix_length″/></socket><socket name=″serverSkt″id=″2″type=″tcp″role=″server″instance=″global″><option name=″so_linger″value=″0″/><option name=″so_reuseaddr″value=″0″/><parameter name=″local_port″purpose=″local_port″valueRef=″bgpSessionData:local_port″/></socket><packet name=″bgpSessionData″class=″sessionData″><value name=″local_port″fullName=″Local port″length=″16″format=″integer″defaultValue=″179″writable=″no″/><value name=″remote_port″fullName=″Remote port″length=″16″format=″integer″defaultValue=″l79″writable=″no″/><value name=″subinterface″fullName=″Sub-interface identifier″length=″32″format=″integer″/><value name=″prefix_length″fullName=″Address prefix length″format=″integer″length=″32″defaultValue=″24″/><value name=″local_ip″fullName=″Source IP Address″ |
format=″ipv4_address″length=″32″initialise=″required″/><value name=″remote_ip″fullName=″Destination IP Address″format=″ipv4_address″length=″32″initialise=″required″/></packet></emulation><emulation name=″isis″filters=″isis_filter″><socket name=″tx″type=″bpf″instance=″subinterface″><!--默认bpf将丢弃所有进入分组--><parameter name=″subinterface″purpose=″subinterface″valueRef=″isisSessionData:subinterface″/></socket><socket name=″L1_rx_broadcast″type=″bpf″instance=″subinterface″><bpfMatch program=″offsetMatch″offset=″0″length=″48″matchRef=″isisSessionData:L1_mac_address″><bpfMatch program=″offsetMatch″offset=″112″length=″16″match=″0xFEFE″/></bpfMatch><parameter name=″subinterface″purpose=″subinterface″valueRef=″isisSessionData:subinterface″/></socket><socket name=″L2_rx_broadcast″type=″bpf″instance=″subinterface″><bpfMatch program=″offsetMatch″offset=″0″length=″48″matchRef=″isisSessionData:L2_mac_address″/><bpfMatch program=″offsetMatch″offset=″112″length=″l6″match=″0xFEFE″/><parameter name=″subinterface″purpose=″subinterface″valueRef=″isisSessionData:subinterface″/></socket><socket name=″rx_ptop″type=″bpf″instance=″subinterface″><bpfMatch program=″offsetMatch″offset=″16″length=″16″match=″0x0023″><bpfMatch program=″offsetMatch″offset=″32″length=″8″match=″0x83″/><bpfMatch program=″offsetMatch″offset=″32″length=″8″match=″0x82″/></bpfMatch><parameter name=″subinterface″purpose=″subinterface″valueRef=″isisSessionData:subinterface″/></socket><packet name=″isisSessionData″class=″sessionData″><value name=″subinterface″fullName=″Sub-interface identifier″length=″32″format=″integer″/><value name=″L1_mac_address″fullName=″L1 Destination MAC address″format=″mac_address″length=″48″defaultValue=″0x0l80C2000014″writable=″no″/><value name=″L2_mac_address″ |
fullName=″L2 Destination MAC address″format=″mac_address″length=″48″defaultValue=″0x0180C2000015″writable=″no″/></packet></emulation></emulationSet> |
<enumSet>是名/值对的表,并且用来将有意义的名字映射到特定的值或者值范围。这对于某些数据的GUI表示尤其有用,其中与有意义的值一起更好地呈现未经处理的值。此外,可以将enumSet概念扩展到允许包和包值基于具体的值相互引用。表13示出了<enumSet>的实施例。
表13
<enumSet name=”Topology Types”><enum value=”1”name=”Route Pool”parceRef=”RoutePool”/><enum value=”2”name=”Grid”parcelRef=”Grid”/><enum value=”2”name=”Ring”parcelRef=”Ring”/></enumSet> |
这里将例如“1”的特定的值映射到名字“Route Pool”,也映射到包。这可以在GUI中使用,其中列出了例如拓扑项的概括表。当用户选择该表中的行时,他将看到从根据拓扑类型引用的包中提取出的详细数据。
可以用描述性的属性对文件中的每个元素进行注解。这些属性文档化该元素,允许消息定义自文档化。通过将消息定义,或许还有消息参考模型与属性一起存储,被提供来处理消息并与消息相接口的例程本质上可以是通用的,例如不在该例程中对数据结构编码,而是在运行期中提供数据结构。例如,可以将属性用来提供利用通用的图形用户界面呈现和编辑任何消息或者消息段所需要的所有信息。在表14中示出了可能的属性的某些实施例。本领域的普通技术人员将认识到表14中给出的列表不是穷尽性的——取决于本发明的实现方式,可以证明其他属性是有益的。
表14
属性 | 目的 |
FullName | 用于包元素的GUI表现名 |
Description | 目的和用法的描述 |
Length | 对于值和数组元素,长度属性定义保持该值所需要的位数 |
Format | 表现格式。定义的格式包括“整数”,“十六进制”,“布尔”,“ipv4_地址”等 |
MinValue/maxValue | 许可值的范围,允许GUI或API执行自动范围检查 |
为了示例,表15包含用XML写的协议仿真定义的实施例。具体地说,表15包含示例bgp4定义文件。
表15
<?xml version=″1.0″standalone=″yes″?><EmulationSet version=″1″providedBy=″Agilent Technologies″><!--Copyright 2004安捷伦科技--><!--===========================================================--><filter name=″bgp4_filter″><hwMatch type=″ipv4″protocolValue=″6″dataValue=″0xb3″dataMask=″0xffff″/><hwMatch type=″ipv4″protocolValue=″6″dataValue=″0xb30000″dataMask=″0xffff0000″/><hwMatch type=″ipv6″protocolValue=″6″dataValue=″0xb3″dataMask=″0xffff″/><hwMatch type=″ipv6″protocolValue=″6″dataValue=″0xb30000″dataMask=″0xffff0000″/></filter><!--===========================================================--><emulation name=″bgp4″shortName=″BGP4″ |
fullName=″BGP4 emulation″standard=″RFC 1771″description=″Sample BGP4 emulation description″filter=″bgp4_filter″><socketn name=″clientSkt″type=″tcpClient″instance=″session″><option name=″soLinger″value=″0″/><option name=″soReuseaddr″value=″0″/><option name=″ipTtl″value=″1″/><option name=″ipServiceOctet″value=″64″/><parameter purpose=″localAddress″valueRef=″bgpSessionData:local_ip″/><parameter purpose=″remoteAddress″valueRef=″bgpSessionData:remote_ip″/><parameter purpose=″remotePort″valueRef=″bgpSessionData:remote_port″/><parameter purpose=″subinterface″valueRef=″bgpSessionData:subinterface″/><parameter purpose=″prefixLength″valueRef=″bgpSessionData:prefix_length″/><tcpReassembly offset=″128″length=″l6″lengthMultiplier=″8″/></socket><socket name=″serverSkt″type=″tcpServer″client=″clientSkt″instance= ″global″><option name=″soLinger″value=″0″/><option name=″soReuseaddr″value=″0″/><parameter purpose=″localPort″valueRef=″bgpSessionData:local_port″/><parameter purpose=″localAddress″valueRef=″bgpSessionData:local_ip″/><parameter purpose=″subinterface″valueRef=″bgpSessionData:subinterface″/></socket><parcel name=″bgpSessionData″fullName=″BGP4 Session Data″class=″sessionData″flow=″toServer″buffer=″newest″><value name=″local_port″fullName=″Local port″purpose=″localPort″length=″16″format=″integer″defaultValue=″179″/><value name=″remote_port″fullName=″Remote port″purpose=″remotePort″length=″16″format=″integer″defaultValue=″179″/><value name=″subinterface″fullName=″Sub-interface identifier″purpose=″subinterface″length=″32″format=″integer″/><valuename=″prefix_length″fullName=″Address prefix length″ |
format=″integer″purpose=″prefixLength″length=″32″defaultValue=″24″/><value name=″local_ip″fullName=″Source IP Address″format=″ipv4_address″purpose=″localAddress″length=″32″/><value name=″remote_ip″fullName=″Destination IP Address″format=″ipv4_address″purpose=″remoteAddress″length=″32″/><value name=″server_port″fullName=″Server TCP Port″format=″integer″purpose=″localPort″length=″16″/><value name=″server_ip″fullName=″Server IP Address″format=″ipv4_address″purpose=″localAddress″length=″32″/></parcel><parcel name=″routeSummary″class=″topologySummary″buffer=″newest″><value name=″v4Pools″fullName=″Number of IPv4 pools″format=″integer″/><value name=″v4Addresses″fullName=″Number of IPv4 Addresses″format=″integer″/><value name=″v6Pools″fullName=″Number of Ipv6 Pools″format=″integer″/><value name=″v6Addresses″fullName=″Number of IPv6 Addresses″format=″integer″/></parcel><enumSet name=″poolState″fullName=″Route pool State″><enumvalue=″0″name=″Withdrawn″/><enum value=″1″name=″Advertised″/></enumSet><parcel name=″routePools″fullName=″Route Pools″class=″topologyData″buffer=″fetch″><table name=″ipv4Pools″fullName=″IPv4 Route Pools″> |
<value name=″v4StartAddr″fullName=″Start Address″length=″32″format=″ipv4_address″/><value name=″v4PrefixLen″fullName=″Prefix Length″minValue=″1″defaultValue=″24″maxValue=″32″/><value name=″v4Count″fullName=″Count″/><value name=″state″fullName=″State″length=″1″enumRef=″poolState″/></table><table name=″ipv6Pools″fullName=″IPv6 Route Pools″><value name=″v6StartAddr″fullName=″Start Address″length=″128″format=″ipv6_address″/><value name =″v6PrefixLen″fullName=″Prefix Length″minValue=″1″defaultValue=″64″maxValue=″128″/><value name=″v6Count″fullName=″Count″/><value name=″state″fullName=″State″length=″1″enumRef=″poolState″/></table></parcel><command name=″advertise″><use rowRef=″routePools:ipv4Pools″/><use rowRef=″routepools:ipv6Pools″/></command><command name=″withdraw″><use rowRef=″routePools:ipv4Pools″/><use rowRef=″routePools:ipv6Pools″/></command><parcel name=″statistics″class= ″statistics″buffer=″newest″><value name=″OpenTx″fullName=″Transmitted Open messages″/><value name=″OpenRx″fullName=″Received Open messages″/> |
<value name=″UpdateTx″fullName=″Transmitted Update messages″/><value name=″UpdateRx″fullName=″Received Update messages″/><value name=″KeepAliveTx″fullName=″Transmitted KeepAlive messages″/><value name=″KeepAliveRx″fullName=″Received KeepAlive messages″/><value name=″NotificationTx″fullName=″Transmitted Notification messages″/><value name=″NotificationRx″fullName=″Received Notification messages″/></parcel></emulation><!--=====================================================================--></EmulationSet> |
常常需要为其值根据在定义内部或者外部指定的其他值而变化的元素设定缺省值。在这种情形中,将可以调用来执行这种任务的工具命令语言(TCL)过程集成是有益的。可以在协议仿真定义文件中指定这种功能。TCL的集成在本领域的普通技术人员的能力范围之内,同样地在这里将不描述这种集成的具体细节。在表16中示出了结合TCL功能的包定义的一部分的实施例:
表16
<value name=”holdTimer”fullName=”Hold Timer”length=”16”defaultValue=30/><value name=”keepalive”fullName=”Keepalive Valu”length=”16”valueFunction=”multiply:holdTimer 2”/> |
在该实施例中,不管为holdTimer设置何值,都在holdTimer的两倍处维护keepalive的缺省值。当实例化包时,可以执行TCL函数,例如创建包的实例。此外,可以创建例程来再检查消息定义和/或模型,并且在运行期中更新由这些函数所影响的值。
参考图3,可以将协议仿真定义存储在主机302上,并且由仿真控制304在运行期时提取。类似地,可以向与主机302通信的任何进程(例如端口306n、GUI 310和Tcl API 312)提供该协议仿真定义的拷贝。
在运行期时,解析协议仿真定义来创建参考模型。通常来说,参考模型是诸如用C++表示的数据结构。参考模型起两种功能。第一功能是保持由系统的各种功能元件所引用的数据。第二功能是担当创建包的模型,所述包用来将数据传输到仿真控制304以及从仿真控制304传输包。这种包可以包括协议仿真定义的实例或者它的一个或多个段。或许与参考模型最相似的结构是c++的通用类型。一种区别是必须在编译时定义通用类型,而参考模型可以在运行期中引入。在本发明的至少一种实施方式中,从其派生出包的参考模型定义类型。使用中可以证明在系统启动时解析所有协议仿真定义,以便生成所有潜在的包的参考模型是有益的,其中在工作期间可能需要所述潜在的包。然而,如果考虑到时间和存储,则建议只生成当前会话最有可能需要的那些参考模型。
GPF 210的每种主要元素(例如仿真控制304、仿真容器306n和代理控制314n)应当都有协议仿真定义214的拷贝。这可以通过向一个元素(一般是仿真控制304)提供协议仿真定义214,随后将拷贝分发给其他元素来实现。可以实现这种功能的一种方式是手工向GPF 210的每个元件提供自展(bootstrap)定义文件,所述自展定义文件使能包存储的配置和运行。此后,一旦系统初始化,就可以通过将协议仿真定义文件214的当前集合封装在包中,并且用包存储402n传输他们,将包存储用来传输协议仿真定义文件214的当前集合。
包链接
如上文所述,到仿真控制304去的通信和从仿真控制304来的通信优选地通过预定义的消息传输格式发生,其中所述消息传输格式基于如待审查美国专利申请#10/851,303所述的包概念。可以利用包链接424(见图4)的概念传输包。
包链接424可以包括简单的接口,所述接口仅仅发送和接收字节字符串,如果需要的话,使其直接在串行接口上实现,或者在任何类型的网络上实现。物理实现细节对GPF应当是透明的,并且将省略进一步的讨论。
用于传输包的一种方法是通过从结构中抽取数据来序列化包中的数据。应当提供足够的数据结构来识别可以用来对二进制流进行解码,并在接收侧创建该包的参考模型(或者它的一部分)。在这种重建期间,包含在参考模型中的结构信息也许可以用来解析二进制流中的数据。因此,接收序列化的消息的接收者应当具有合适的消息定义的拷贝。接收者必须对该消息定义进行解析来生成参考模型,其应当是参考模型204a的拷贝。一旦接收到序列化的消息,接收者通过将参考模型(或者它的一部分)实例化形成消息对象,并且用二进制数据填充作为结果的数据结构,从而重建消息对象。
表17是自文档化C++代码的一部分,所述代码描述适于在根据本发明实施方式的消息传输中使用的通信链接。
表17
#ifndef APF_PAKCEL_LINK_H#define APF_PARCEL_LINK_H//=======================================//////=库// APF安捷伦协议框架////=文件名 |
// ApfparcelLink.h////=描述////包存储相互链接的接口////=作者// Geoff Smith////=版权// (C)Copyright 2004安捷伦科技////==============================================#include″acl/acl.h″#include″acl/afc/afc.h″#include″pdubuilder/include/apbExport_.h″//---------------------------------------------------------------------//=标题// 包链接////=类类型// 接口////=描述//包存储相互链接的接口。可以通过在GPF之外的居间系统层来实现用于这种接口的代理和存根,//所述居间系统层用于链接驻留在不同平台上的GPF包存储////这种接口的实现由在链接的每一端口处的//包存储提供。注意,每个包存储都提供并使用这种接口的实现来与其他包存储通信class APB_EXPORT_CLASS IApfParcelLink{public://=基础virtual~IApfParcelLink(){}virtual voidparcelData(uint32_taPort,uint32_t aSession,const AtoString&aName,const AtoByteString&aParcel)=0;};#endif//APF PARCEL LINK H |
结论
最后,本发明实现了通用协议仿真的可能方法,其中可以用XML和Tcl定义整个协议仿真以在框架中运行。这使用户和技术支持工程师能够具有下述能力,即立即对新协议进行测试,而不用等待供应商提供协议模块。尽管可能存在性能限制,但是这种通用仿真看起来与内建仿真具有相同的API和GUI。然而,这解决了上市时间窗,并且如果需要的话提供了跟上高性能内建仿真方案的机会。孤立的框架易于部署在多种目标平台中。可以在自含式GPF环境中开发并测试协议模块,并且将其部署在部署了GPF的任何平台上。由于三个GPF组件的灵活的星形连线特性,以及用来将这些组件连接到一起的非常简单的异步parcelLink API,所以可以容易地将GPF部署在各种目标平台中,甚至分布式环境中。
Claims (22)
1.一种协议仿真系统,包括:
至少一个由协议仿真定义配置的仿真容器,用于根据包含在所述协议仿真定义文件内的数据来启动协议仿真会话;和
由所述协议仿真定义配置的接口,其显示与由所述仿真容器创建的所述会话相关的数据,并且协助来自用户的命令和配置数据的输入,所述命令和配置数据被传输到所述仿真容器,并且修改所述仿真容器的行为;和
仿真控制器,其分发协议仿真定义,并且充当所述仿真容器与所述接口之间的数据和命令的管道。
2.如权利要求1所述的协议仿真系统,其中,所述仿真容器使用所述协议仿真定义文件来构建数据结构,其存储在运行期间所使用的数据。
3.如权利要求1所述的协议仿真系统,其中,所述接口使用所述协议仿真定义文件来构建参考模型,其存储在运行期间所使用的数据。
4.如权利要求3所述的协议仿真系统,其中,所述仿真容器使用所述协议仿真定义文件来构建参考模型,其存储在运行期间所使用的数据。
5.如权利要求4所述的协议仿真系统,其中,所述接口使用所述参考模型来为所述仿真容器例示消息。
6.如权利要求4所述的协议仿真系统,其中,所述仿真容器使用所述参考模型来为所述接口例示消息。
7.如权利要求1所述的协议仿真系统,还包括:
与所述仿真容器通信的协议状态机,所述协议状态机创建协议消息,并对协议消息作出响应。
8.如权利要求1所述的协议仿真系统,还包括:
脚本,其描述如何创建协议消息和如何对协议消息作出响应;并且
其中所述仿真容器将所接收到的协议消息传递给所述脚本,并且将由所述脚本生成的响应传输到被测网络上。
9.如权利要求1所述的协议仿真系统,其中,所述接口包括图形用户界面,其基于所述协议仿真定义中包含的信息来创建显示。
10.如权利要求1所述的协议仿真系统,其中,所述接口是文本的。
11.如权利要求1所述的协议仿真系统,其中,用脚本语言创建所述接口。
12.一种便携分布式应用框架,包括:
定义文件,其描述由所述框架用来与应用接口的命令和数据的结构;
代理,响应于定义文件,用于基于所述定义文件创建和接收消息,所创建的消息包含用来控制应用的数据和命令,所接收的消息包含来自所述应用的数据;
控制,响应于所述定义文件,用于在所述代理和所述应用之间中继消息;和
容器,响应于所述定义文件和来自所述代理的消息,向所述应用提供配置信息,并从所述应用接收数据。
13.如权利要求12所述的便携分布式应用框架,其中,所述应用是协议状态机。
14.如权利要求12所述的便携分布式应用框架,其中,所述代理、控制和容器中的每一个都基于所述定义文件创建内部数据结构,所述内部数据结构被用于例示消息。
15.如权利要求12所述的便携分布式应用框架,其中,所述代理、控制和容器中的每一个都具有用于接收和发送消息的缓冲区,所述缓冲区用来实现包括推和拉的不同通信类型。
16.如权利要求12所述的便携分布式应用框架,其中,独立于所述代理、控制和容器来设计应用。
17.如权利要求12所述的便携分布式应用框架,还包括:
第二定义文件,其描述由所述框架用来与第二应用相接口的命令和数据的结构;
第二容器,响应于所述定义文件和来自所述代理的消息,向所述第二应用提供配置信息,并从所述应用接收数据;并且
其中所述代理响应于所述第二定义文件,用于基于所述定义文件来创建和接收消息,所创建的消息包含用来控制所述第二应用的数据和命令,所接收的消息包含来自所述第二应用的数据,所述控制响应于所述第二定义文件,用于在所述代理和所述第二应用之间中继消息。
18.如权利要求12所述的便携分布式应用框架,还包括:
第二代理,响应于定义文件,用于基于所述定义文件来创建和接收消息,所创建的消息包含用来控制所述应用的数据和命令,所接收的消息包含来自所述应用的数据。
19.一种控制应用的方法,包括:
创建定义,所述定义描述用于与所述应用相接口的数据和命令;
使用所述定义来配置通用接口,所述接口创建基于所述定义而构建的消息;
使用所述定义来配置通用容器,所述容器从所述接口接收消息,从所述定义中抽取数据和命令,并将所述数据和命令提供给所述应用,所述容器基于所述定义,将从所述应用接收到的数据封装到消息中,所述消息被传输到所述接口。
20.如权利要求19所述的方法,其中,所述应用是协议状态机。
21.一种与远程应用通信的方法,所述方法包括:
定义将被用来与所述远程应用通信的消息的结构;
将所定义的结构提供给中央控制和至少两个接口;
创建一串位于所述远程应用本地的缓冲区以保存来自所述接口的消息,其中针对每种类型的消息来定义缓冲区;
创建一串位于所述接口本地的缓冲区以保存来自所述远程应用的消息,其中针对每种类型的消息来定义缓冲区;
基于所定义的消息结构,在所述用户接口本地为所述远程应用创建第一消息;
基于所定义的消息结构,在所述远程应用本地为所述接口创建第二消息;
将所述第一消息传输到中央控制;
将所述第二消息传输到所述中央控制;
基于所述消息的类型,缓冲在所述中央控制中接收到的消息;
将所述中央控制中的缓冲区镜像映射到位于所述接口本地的缓冲区,使得每个接口中的缓冲区的内容与所述中央控制中的缓冲区同步;并且
将由所述中央控制接收到的第一消息传输到所述远程应用。
22.如权利要求21所述方法,还包括:
维持从所述中央控制发送到所述远程应用的最近消息的拷贝;
将所述消息与所述最近消息的拷贝一起备份在所述中央控制中的缓冲区中;以及
在必要时恢复所备份的消息。
Applications Claiming Priority (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US10/893,668 US7467078B2 (en) | 2004-07-16 | 2004-07-16 | Portable distributed application framework |
US10/893,668 | 2004-07-16 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN1722681A true CN1722681A (zh) | 2006-01-18 |
Family
ID=34912808
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN200510077480.2A Pending CN1722681A (zh) | 2004-07-16 | 2005-06-21 | 便携分布式应用框架 |
Country Status (6)
Country | Link |
---|---|
US (1) | US7467078B2 (zh) |
EP (1) | EP1617625A3 (zh) |
JP (1) | JP2006033829A (zh) |
CN (1) | CN1722681A (zh) |
DE (1) | DE102005016032A1 (zh) |
GB (1) | GB0514689D0 (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109116781A (zh) * | 2018-09-03 | 2019-01-01 | 中国汽车工程研究院股份有限公司 | 以太网高速数据采集系统 |
Families Citing this family (30)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7814198B2 (en) | 2007-10-26 | 2010-10-12 | Microsoft Corporation | Model-driven, repository-based application monitoring system |
US20080059954A1 (en) * | 2002-06-18 | 2008-03-06 | Martin Joseph B | Universal system component emulator with human readable output |
US9332069B2 (en) * | 2012-12-28 | 2016-05-03 | Wandisco, Inc. | Methods, devices and systems for initiating, forming and joining memberships in distributed computing systems |
US7793268B2 (en) * | 2006-08-28 | 2010-09-07 | International Business Machines Corporation | Method, system, and program product for composing a virtualized computing environment |
EP2479627A3 (en) * | 2007-03-29 | 2013-03-06 | iRobot Corporation | Robot operator control unit configuration system and method |
US8024396B2 (en) * | 2007-04-26 | 2011-09-20 | Microsoft Corporation | Distributed behavior controlled execution of modeled applications |
US8316351B2 (en) * | 2007-05-07 | 2012-11-20 | Microsoft Corporation | Utilizing a schema for documenting managed code |
US8239505B2 (en) * | 2007-06-29 | 2012-08-07 | Microsoft Corporation | Progressively implementing declarative models in distributed systems |
US7970892B2 (en) * | 2007-06-29 | 2011-06-28 | Microsoft Corporation | Tuning and optimizing distributed systems with declarative models |
US8230386B2 (en) | 2007-08-23 | 2012-07-24 | Microsoft Corporation | Monitoring distributed applications |
US8225308B2 (en) * | 2007-10-26 | 2012-07-17 | Microsoft Corporation | Managing software lifecycle |
US8181151B2 (en) * | 2007-10-26 | 2012-05-15 | Microsoft Corporation | Modeling and managing heterogeneous applications |
US8099720B2 (en) | 2007-10-26 | 2012-01-17 | Microsoft Corporation | Translating declarative models |
US20090112932A1 (en) * | 2007-10-26 | 2009-04-30 | Microsoft Corporation | Visualizing key performance indicators for model-based applications |
US7974939B2 (en) | 2007-10-26 | 2011-07-05 | Microsoft Corporation | Processing model-based commands for distributed applications |
US7926070B2 (en) | 2007-10-26 | 2011-04-12 | Microsoft Corporation | Performing requested commands for model-based applications |
US8621198B2 (en) * | 2008-02-19 | 2013-12-31 | Futurewei Technologies, Inc. | Simplified protocol for carrying authentication for network access |
US8793117B1 (en) * | 2008-04-16 | 2014-07-29 | Scalable Network Technologies, Inc. | System and method for virtualization of networking system software via emulation |
US7958387B2 (en) | 2008-05-30 | 2011-06-07 | Spirent Communications, Inc. | Realtime test result promulgation from network component test device |
US8264972B2 (en) * | 2008-05-30 | 2012-09-11 | Spirent Communications, Inc. | Method and apparatus for emulating network devices |
US9292248B2 (en) * | 2011-06-22 | 2016-03-22 | Microsoft Technology Licensing, Llc | Span out load balancing model |
US8526470B2 (en) * | 2011-07-05 | 2013-09-03 | Ixia | Synchronized commands for network testing |
US9430345B2 (en) | 2011-09-23 | 2016-08-30 | Roche Diabetes Care, Inc. | Command interface for communication test framework |
US9489488B2 (en) | 2011-09-23 | 2016-11-08 | Roche Diabetes Care, Inc. | Protocol independent interface supporting general communications interface debugging and testing tool |
US9521062B2 (en) * | 2011-09-23 | 2016-12-13 | Roche Diabetes Care, Inc. | Communication test framework |
US9652264B2 (en) * | 2012-09-21 | 2017-05-16 | Ixia | Methods, systems, and computer readable media for providing a unified framework to support diverse data generation engines |
ES2881606T3 (es) | 2014-03-31 | 2021-11-30 | Wandisco Inc | Sistema de ficheros geográficamente distribuido que usa replicación de espacio de nombres coordinada |
WO2016170512A1 (en) * | 2015-04-24 | 2016-10-27 | Tager Sean | Universal game controller |
US11360942B2 (en) | 2017-03-13 | 2022-06-14 | Wandisco Inc. | Methods, devices and systems for maintaining consistency of metadata and data across data centers |
US11182399B2 (en) | 2018-09-04 | 2021-11-23 | Spirent Communications, Inc. | Effective correlation of multiple time-series result sets |
Family Cites Families (19)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5371736A (en) * | 1992-12-21 | 1994-12-06 | Abb Power T&D Company, Inc. | Universal protocol programmable communications interface |
US5448566A (en) * | 1993-11-15 | 1995-09-05 | International Business Machines Corporation | Method and apparatus for facilitating communication in a multilayer communication architecture via a dynamic communication channel |
JPH08180001A (ja) * | 1994-04-12 | 1996-07-12 | Mitsubishi Electric Corp | 通信方式及び通信方法及びネットワークインタフェース |
US5473599A (en) * | 1994-04-22 | 1995-12-05 | Cisco Systems, Incorporated | Standby router protocol |
US5774695A (en) * | 1996-03-22 | 1998-06-30 | Ericsson Inc. | Protocol interface gateway and method of connecting an emulator to a network |
US5857074A (en) * | 1996-08-16 | 1999-01-05 | Compaq Computer Corp. | Server controller responsive to various communication protocols for allowing remote communication to a host computer connected thereto |
US5946311A (en) | 1997-05-27 | 1999-08-31 | International Business Machines Corporation | Method for allowing more efficient communication in an environment wherein multiple protocols are utilized |
JP3343054B2 (ja) | 1997-07-01 | 2002-11-11 | ケイディーディーアイ株式会社 | インターネット対応リンクモニタ方法 |
WO1999014891A2 (en) | 1997-09-12 | 1999-03-25 | Communication & Control Electronics Limited | Development and test tools for communication system |
US6317438B1 (en) * | 1998-04-14 | 2001-11-13 | Harold Herman Trebes, Jr. | System and method for providing peer-oriented control of telecommunications services |
US20050027870A1 (en) * | 1998-04-14 | 2005-02-03 | Trebes Harold Herman | System and method for providing peer-oriented control of telecommunication services |
US6996085B2 (en) * | 2000-12-22 | 2006-02-07 | Nortel Networks Limited | System, device, and method for providing network access in a communication system |
US8078730B2 (en) * | 2000-12-22 | 2011-12-13 | Rockstar Bidco, LP | System, device, and method for maintaining communication sessions in a communication system |
US20020156886A1 (en) * | 2001-04-23 | 2002-10-24 | Krieski William George | Protocol monitor |
US20020156885A1 (en) * | 2001-04-23 | 2002-10-24 | Thakkar Bina Kunal | Protocol emulator |
US20020157041A1 (en) * | 2001-04-23 | 2002-10-24 | Bennett David Charles | Protocol parser-code generator |
US20020186697A1 (en) * | 2001-04-23 | 2002-12-12 | Thakkar Bina Kunal | Protocol encoder and decoder |
US7107597B2 (en) | 2001-09-10 | 2006-09-12 | Ericom Software 8 2001 Ltd. | Method of and system for controlling task-oriented systems utilizing an application programming interface |
US20030220781A1 (en) * | 2002-02-25 | 2003-11-27 | Oak Technology, Inc. | Communication architecture utilizing emulator interface |
-
2004
- 2004-07-16 US US10/893,668 patent/US7467078B2/en active Active
-
2005
- 2005-04-07 DE DE102005016032A patent/DE102005016032A1/de not_active Withdrawn
- 2005-06-21 CN CN200510077480.2A patent/CN1722681A/zh active Pending
- 2005-07-08 JP JP2005199534A patent/JP2006033829A/ja active Pending
- 2005-07-18 GB GBGB0514689.9A patent/GB0514689D0/en not_active Ceased
- 2005-07-18 EP EP05254472A patent/EP1617625A3/en not_active Withdrawn
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109116781A (zh) * | 2018-09-03 | 2019-01-01 | 中国汽车工程研究院股份有限公司 | 以太网高速数据采集系统 |
Also Published As
Publication number | Publication date |
---|---|
EP1617625A2 (en) | 2006-01-18 |
DE102005016032A1 (de) | 2006-02-09 |
EP1617625A3 (en) | 2007-06-27 |
US7467078B2 (en) | 2008-12-16 |
JP2006033829A (ja) | 2006-02-02 |
GB0514689D0 (en) | 2005-08-24 |
US20060013252A1 (en) | 2006-01-19 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN1722681A (zh) | 便携分布式应用框架 | |
CN101031882B (zh) | 用于通用设备互操作性平台的设备组招募和内容再现的体系结构、装置和方法 | |
CN110674027B (zh) | 面向p4编程语言的sdn数据平面软件一致性测试系统及方法 | |
CN1650287A (zh) | 用于改变网络拓扑的方法和系统 | |
CN1700665A (zh) | 分布式数据模型 | |
US12131149B1 (en) | Updating method for programmable data plane at runtime, and apparatus | |
CN106656980A (zh) | 一种自动化配置Docker容器访问控制的方法 | |
US8868532B2 (en) | Message exchange pattern rendezvous abstraction | |
JP4896532B2 (ja) | 通信チャネルモデル | |
CN105389120A (zh) | 支持通过活动消息的rma api | |
CN1987798A (zh) | 数据平面与控制平面之间的通讯方法 | |
CN117061352A (zh) | 多模态虚拟网元的实现方法、装置、设备及介质 | |
US20150082322A1 (en) | Data Upgrade Framework for Distributed Systems | |
Santos et al. | Managing O-RAN networks: xApp development from zero to hero | |
CN114138259B (zh) | 适配多云平台的多微服务分布式框架的构建系统及方法 | |
CN114020359B (zh) | 一种基于插件的分布式平台集成方法 | |
CN113162677B (zh) | 一种实物设备与虚拟网络仿真平台的通信方法及装置 | |
CN104579837A (zh) | 一种OpenFlow协议一致性测试的方法和系统 | |
Ratan | Practical Network Automation: Leverage the power of Python and Ansible to optimize your network | |
Schottelius | High speed nat64 with p4 | |
CN109302398A (zh) | 对于IPv6网络UDP数据包的接收解析与存储方法 | |
CN118714059B (zh) | 测试网关设备的方法、装置和存储介质 | |
CN114741126B (zh) | 小程序运行方法、装置、电子设备、存储介质及程序产品 | |
Quant | An Engineer's Journey into Network Function Virtualization & 5G Research | |
Qin et al. | A behavior consistent service discovery and substitution mechanism in osgi |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C02 | Deemed withdrawal of patent application after publication (patent law 2001) | ||
WD01 | Invention patent application deemed withdrawn after publication |