NS2学习(1)——分裂对象模型
来源:互联网 发布:域名邮箱反差 编辑:程序博客网 时间:2024/05/16 09:33
NS2使用了C++和OTcl两种不同的编程语言,其中C++负责后端的封包处理,OTcl负责前端的控制管理。如此有很多优势,却也增加了学习门槛。许多类,许多方法,好像怎么理都理不清,无奈写文记下,以备查看。这里以TCP协议为例,按照执行顺序一步步查看源码,大致上理解所谓“分裂对象模型”,具体细节以后再慢慢总结了。
例子中涉及到两个类:编译类TcpAgent和解释类Agent/TCP,这两个类由类TCPClass连接。
一. OTcl注册的过程
ns启动后,因为class_tcp是静态对象,所以首先建立。
建立静态对象class_tcp的步骤:
文件:~ns/tcp/tcp.cc
源代码:
static class TcpClass : public TclClass {
public:
TcpClass() : TclClass("Agent/TCP") {}
TclObject* create(int , const char*const*) {
return (new TcpAgent());
}
} class_tcp
1.首先会执行父类TclClass的构造函数(参数为Agent/TCP)
2.执行TcpClass的构造函数(不执行任何操作)
步骤1.执行父类TclClass的构造函数,主要功能为存储类名和调用TclClass::bind()方法。
//存储类名Agent/TCP至 classname_
文件:~tclcl/Tcl.cc
源代码:
TclClass::TclClass(const char* classname) : class_(0), classname_(classname)
{
if (Tcl::instance().interp()!=NULL) {
bind(); //调用bind()函数,定义如下
} else {
next_ = all_;
all_ = this;
}
}
bind()函数定义如下:
void TclClass::bind()
{
Tcl& tcl = Tcl::instance(); //获取Tcl句柄
tcl.evalf("SplitObject register %s", classname_);
//(1)调用SplitObject的过程register{}
class_ = OTclGetClass(tcl.interp(), (char*)classname_);
//将字符串转为class pointer
OTclAddIMethod(class_, "create-shadow",
(Tcl_CmdProc *) create_shadow, (ClientData)this, 0);
OTclAddIMethod(class_, "delete-shadow",
(Tcl_CmdProc *) delete_shadow, (ClientData)this, 0);
//为解释类Agent/TCP增加了两个过程 create-shadow{}和delete-shadow{},以便调用TclClass::create_shadow()和TclClass::delete_shadow()
otcl_mappings();
}
(1)调用SplitObject的过程register{}
文件:~tclcl/tcl-object.tcl
源代码:
SplitObject proc register className {
set classes [split $className /]
set parent SplitObject
set path ""
set sep ""
foreach cl $classes {
set path $path$sep$cl
if ![$self is-class $path] {
Class $path -superclass $parent
}
set sep /
set parent $path
}
}
功能:在解释类层次的路径上依次建立多个新的解释类。例子中Agent解释类已经存在,所以只建立Agent/TCP一个解释类,并将其置入解释类层次。
至此完成了TclClass的构造函数的初始化工作。
//调用SplitObject的过程getid{}, 为将要建立的Otcl实例取得UID (1)实例化Agent/TCP 依据OTcl的说明网页(~otcl/doc/class.html),create{}会执行alloc{},并调用Agent/TCP的init{}过程。依序执行完所有解释类的init{}后,Agent/TCP的实例(一个split object):tcp,就完成了建立工作。 先记下这些了,有点条理了,只是还有很多细节函数没有解释清楚,以后再接再厉了。 参考: http://203.208.37.132/search?q=cache:I90w-_gM7-EJ:203.68.111.3:8080/97_1_course/CSIE_G_ACN/03_c_in_OTcl.pdf+C%2B%2B%E4%B8%8EOtcl&cd=27&hl=zh-CN&ct=clnk&gl=cn&client=aff-cs-360se&st_usg=ALhdy29Sa2TiDgok7Wk68JgcAxy7JEgs9w
二.实例化的过程
1.建立split object
当你在Tcl脚本中使用语句 set tcp [new Agent/TCP]时,即调用了全局过程new{}
文件:~tclcl/tcl-object.tcl
源代码:
proc new { className args } {
set o [SplitObject getid]
if [catch "$className create $o $args" msg] { //(1)实例化Agent/TCP
if [string match "__FAILED_SHADOW_OBJECT_" $msg] {
delete $o
return ""
}
global errorInfo
error "class $className: constructor failed: $msg" $errorInfo
}
return $o
}
代码"$className create $o $args"使用Agent/TCP的过程create{}来实例化Agent/TCP,但是Agent/TCP是由编译类利用TclClass机制产生的,而由此机制自动建立的解释类只被增加了两个过程,即 create-shadow{} 和delete-shadow{}。因此应调用其父类Agent的create{}过程,但是Agent类也是由编译类自动产生,同理应调用Agent的父类SplitObject的create{}过程。但是在~tclcl/tcl-object.tcl 中,SplitObject并沒有create{}过程,所以此处的 create{}应该是直接使用 Class(OTcl 中所有 classes 的 root)所定义的过程create{}。
2.建立shadow object
因为要建立的OTcl object属于split object,所以最后会调用SplitObject的init{},来建立相应的shadow object。
文件:~tclcl/tcl-object.tcl
源代码:
SplitObject instproc init args {
$self next
if [catch "$self create-shadow $args"] { //(1)调用create_shadow()
error "__FAILED_SHADOW_OBJECT_" ""
}
}
(1)调用create_shadow()
$self即Agent/TCP的实例,所以调用的是Agent/TCP的create-shadow{}过程,其对应的方法是TclClass::create_shadow()
定义如下:
int TclClass::create_shadow(ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char *argv[])
{
TclClass* p = (TclClass*)clientData;
TclObject* o = p->create(argc, argv); //(2)调用TcpClass::create()
Tcl& tcl = Tcl::instance();
if (o != 0) {
o->name(argv[0]);
tcl.enter(o);
if (o->init(argc - 2, argv + 2) == TCL_ERROR) {
tcl.remove(o);
delete o;
return (TCL_ERROR);
}
tcl.result(o->name());
OTclAddPMethod(OTclGetObject(interp, argv[0]), "cmd",
(Tcl_CmdProc *) dispatch_cmd, (ClientData)o, 0);
OTclAddPMethod(OTclGetObject(interp, argv[0]), "instvar",
(Tcl_CmdProc *) dispatch_instvar, (ClientData)o, 0);
//增加两个过程cmd{}和instvar{}
o->delay_bind_init_all();
return (TCL_OK);
} else {
tcl.resultf("new failed while creating object of class %s",
p->classname_);
return (TCL_ERROR);
}
}
(2)调用TcpClass::create()
此过程见文章开头,只有一条语句return (new TcpAgent());至此建立了shadow object,即TcpAgent,在文件~ns/tcp/tcp.cc中定义。
- NS2学习(1)——分裂对象模型
- NS2分裂对象模型浅析(一)
- NS2入门学习(五)之分裂对象模型和TclCL
- NS2的分裂对象机制学习总结
- NS2笔记 之 OTcl与C++ (分裂对象模型的深入理解)
- NS2 OTcl/C++分裂模型接口TclCL
- NS笔记1:分裂对象模型
- ns笔记:分裂对象模型
- ns2相关学习——tcl脚本编写(1)
- NS2学习笔记(1)
- NS2学习(2)——看源码,学命令
- NS2学习(3)——mac定时器
- NS2学习(4)——事件调度机制
- NS2学习(5)——Packet传输流程
- NS2学习(6)——Tcl类
- ns2相关学习——TCL脚本编写(2)
- ns2相关学习——TCL脚本编写(3)
- 【转】Leach协议学习(1)——NS2.27+leach协议安装
- Very Busy Recently
- 关于Java中自定义包的创建
- 设置单文档应用程序的背景图片
- Apache+MySQL+PHP环境配置
- SIFT进阶
- NS2学习(1)——分裂对象模型
- reactos操作系统实现(96)
- getsockopt/setsockopt 函数用法(转)
- 15个优秀的第三方 Web 技术集成
- PHP5.1.5_Apache2.2.3_MySQL5.0.24安装配置
- 与ASP.NET服务器端结合返回JSON数据实现ExtJS GridPanel客户端分页
- 2010年MBA英语的整体备考思路
- 在Java中利用cglib实现代理
- java.lang.NoSuchMethodError解决方法