//without comments

 int chooseECNSlot()
{
double maxProgress=;
for(int i=;i<=nslot_;i++)
{
if(slot_[i]!=NULL && window_i>*count)
{
double ti=window_i/(*count);
double iProg=umap[slot_[i]]+(window_i+ti/)*ti;
for(int j=;j<=nslot_;j++)
{
if(slot_[j]!=NULL && window_j>*count)
{
double jProg=umap[slot_[j]]+(window_j+ti/)*ti;
if(jProg>iProg) break;
}
if(j==nslot_)
{
return i;
}
}
}
}//for
return -;//no flow satisfies the condition.(maybe should return the flow with max progress)
} int PortClassifier::recv(Packet* p, Handler*h)
{
NsObject* node = find(p);//find调用classify,classify返回dport。
if (node == NULL) {
Packet::free(p);
return;
} umap[node]++; if(flag)
{
hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
if(hf->ce()==)
{
hf->ce()=;
mark=chooseECNSlot();
}
if (mark != - &&node==slot_[mark])
{
hf->ce()=;
mark = -;
}
}//end of flag node->recv(p,h);
} void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
{
if (slot >= nslot_)
alloc(slot);
slot_[slot] = p; if (slot >= maxslot_)
maxslot_ = slot; count++;
if(count>=)
flag=; } ================================================================================================================================== 15.1. rewrite: classifier-port.h里需要添加的:
()include处
#include <unordered_map> 还要using namespace std?或者不用?在底下定义的时候用std::unordered_map<NsObject*,double> umap
#include "flags.h"//里面有很多需要的变量和函数,如ce()
()3个变量
count=; flag=; mark=-;//可以考虑用复杂些的变量名,防止别的需要include的文件里有重名的
count不止表示agent个数,同时它是server的个数!
flag用来标志receiver; //【但是这样全局变量对吗?sender那边如果使用portclassifier时会累加上吗?不会的。这方法可以。亲测有效。】
//【如果不行就用遍历slot的方法。每次遍历一下看有多少agent。】
()
unordered_map<NsObject*,double> umap;//看看用不用指定std:: ------------------------------------------------------------------------------------------------------------------------------
//with comments int chooseECNSlot()//根据umap里的统计来获取各流进度值。返回值是slot_的下标。
//这个函数还是改成专门筛选流的函数吧(筛选出需要窗口减半的流)
{
//该函数需要能访问到umap以及各流的window大小。
//注意:这里说的按进度排序不是按当前进度排序,而是按下次发生ECN的时刻的进度排序。 double maxProgress=;//初始化最大进度值maxProgress
// mark=-1;//用来标记选中的流
// int flagMax=0;
for(int i=;i<=nslot_;i++)//下标能否等于nslot?
{ //其实遍历slot就行!slot_中有一些是empty,所以虽然知道共有count个agent,还是得完整遍历一遍slot_.
if(slot_[i]!=NULL && window_i>*count)// 这是能“参赛”的流的入门条件。
{//在window大于2N的流里面找[下次ECN时刻]进度最大的。
//这里count就是server数目N。
//ASSUME flow with index[i] will be the maxProgress-flow at next ECN
double ti=window_i/(*count);//the time gap from now when next ECN happens
int newProg=umap[slot_[i]]+(window_i+ti/)*ti;
for(int j=;j<=nslot_;j++)
{
if(slot_[j]!=NULL && window_j>*count)//参赛门槛
{
double tj=window_j/(*count);
tmpProg=umap[slot_[j]]+(window_j+tj/)*tj;
if(tmpProg>newProg) break;//说明i不是下次ecn时进度最快的,假设不成立。
}
}
// if(umap[slot_[i]]>maxProgress)
// {
// maxProgress=umap[slot_[i]];//更新maxProgress
// mark=i;//标记下该流的node在slot_中对应的下标i;
// }
} // else
// {//如果没有window>2N的流,就选当前进度最大的流?这是后话。
// } }//for // if(mark!=-1)
return mark;// 返回下标
// else//没有window>2N的流
// return mark2; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int PortClassifier::recv(Packet* p, Handler*h)
{
NsObject* node = find(p);//find调用classify,classify返回dport。
if (node == NULL) {
Packet::free(p);
return;
} if(flag)//当前node是receiver时才执行下面的算法。
{
// mark=-1;//slot_下标的初始值置为-1?
umap[node]++;//需要在classifier.h中classifier类内部定义unordered_map umap<NsObject*,double>。 (但是注意,当umap里有流已传输完毕后要剔除出去,否则影响排序XXXX如果不用mark2的话那就不会影响到,因为首先是按window来看的,只有window足够大才会看进度。已经传输完成的流window应该变为0吧(如果没变要记得调整))。
hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
if(hf->ce()==)// 说明switch中发生了拥塞
{
hf->ce()=;//首先清零。然后再根据算法分配ce。
mark=chooseECNSlot();//用chooseECNSlot()选出应当减半的流。
} if (mark != - &&node==slot_[mark]) //这个recv()程序一开始就用到了find,把packet转换成了agent(这里是用node变量来表示的agent)。所以可以用这个node来和slot_[mark]直接比较。
//对每一个到来的packet都检查,直到发现是mark所标记的那个。可通过portclassifier里的classify返回dport。(参照slideshare P15,为什么通过classifier类,调用的却是portclassifier里的classify ?)
{
hf->ce()=;
mark = -;//任务完成,使mark失效。
}
}//end of flag
node->recv(p,h);
} void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
{
if (slot >= nslot_)
alloc(slot);
slot_[slot] = p; if (slot >= maxslot_)
maxslot_ = slot; count++;
if(count>=) flag=; } ==================================================================================================================================
//below is original source code void Classifier::recv(Packet* p, Handler*h)//original
{
NsObject* node = find(p);
if (node == NULL) {
/*
* XXX this should be "dropped" somehow. Right now,
* these events aren't traced.
*/
Packet::free(p);
return;
} node->recv(p,h);
} ///////////////////////////////////////////////////////////////////////////////////////////////////// void Classifier::install(int slot, NsObject* p)
{
if (slot >= nslot_)
alloc(slot);
slot_[slot] = p;
if (slot >= maxslot_)
maxslot_ = slot;
} //above is original source code
===============================================================================================================

updated 15.1.8

 void Classifier::recv(Packet* p, Handler*h)//original
{
NsObject* node = find(p);
if (node == NULL) {
/*
* XXX this should be "dropped" somehow. Right now,
* these events aren't traced.
*/
Packet::free(p);
return;
} node->recv(p,h);
} =============================================================================================================== int chooseECNSlot()
//这个函数还是改成专门筛选流的函数(筛选出需要窗口减半的流)
{//在打ecn的地方引入调用这个函数,通过该函数来打ECN?或者通过该函数有针对性的回调打ecn的函数。
//该函数需要能访问到umap以及各流的window大小。 //sort(window)其实不用。用下面的方法只需遍历一次,O(N)复杂度即可。如果sort要O(NlogN)。
int maxProgress=;//初始化最大进度值maxProgress
int mark=-;//用来标记选中的流s
for(i=;i<=n;i++)//其实遍历slot就行!
{
if(window>*N)//在window大于2N的流里面找进度最大的。(如何获取该流的window?)
{
if(该流的进度值(umap.second)>maxProgress)
{
maxProgress=该进度值(umap.second);//更新maxProgress
mark=i;//标记下该流的node;
}
}
else
{//如果没有window>2N的流,就选当前进度最大的流。 }
}
if(mark!=-)
return mark;
else//没有window>2N的流
return mark2; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
15.1. rewrite: #include "flags.h"//里面有很多需要的变量和函数,如ce()
void Classifier::recv(Packet* p, Handler*h)
{
NsObject* node = find(p);//find调用classify,classify返回dport。
if (node == NULL) {
Packet::free(p);
return;
}
umap[node]++;//需要在classifier.h中classifier类内部定义unordered_map umap<NsObject*,long long int>。 (但是注意,当umap里有流已传输完毕后要剔除出去,否则影响排序XXXX如果不用mark2的话那就不会影响到,因为首先是按window来看的,只有window足够大才会看进度。已经传输完成的流window应该变为0吧(如果没变要记得调整))。 hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
if(hf->ce()==)// 说明switch中发生了拥塞
{
hf->ce()=;//首先清零。然后再根据算法分配ce。
int mark=function(筛选出需要窗口减半的流的slot下标);//该函数参照上面的chooseECNSlot
} if (mark != - &&当前packet的dport==slot[mark])//对每一个到来的packet都检查,直到发现是mark所标记的那个。可通过portclassifier里的classify返回dport。(参照slideshare P15,为什么通过classifier类,调用的却是portclassifier里的classify ?)
{
hf->ce()=;
mark = -;//使mark失效。
}
node->recv(p,h);
}

http://www.slideshare.net/TBear76/20100403-classifiers

classifier.cc-recv() [ns2.35]的更多相关文章

  1. ubuntu 14.04 ns2.35 ***buffer overflow detected **: ns terminated解决办法

    1.按照如下教程安装 Install With Me !: How to Install NS-2.35 in Ubuntu-13.10 / 14.04 (in 4 easy steps) 2.运行一 ...

  2. 在ns2.35下完成柯老师lab18实验

    说明:柯志亨老师<ns2仿真实验-----多媒体和无线网络通信>这本书lab18实验为“无线网络封包传输遗失模型”的实验.该无线传输遗失模型是柯老师自己开发的,原始的ns-allinone ...

  3. 在ns2.35中添加myevalvid框架

    在用ns2进行网络视频通信仿真的时候,先要为我们自己的ns2添加evalvid或者myevalvid框架.其中myevalvid框架是由柯志亨老师整合evalvid和ns2之后得出的新框架,笔者建议大 ...

  4. Ubuntu14.04下安装ns2.35

    我选择的版本是2.35最新版本,安装环境是Ubuntu 14.04. 1.下载ns2的安装包,这里我选择的是ns-allinone-2.35.tar.gz压缩格式的all in one安装包,all ...

  5. Ubuntu12.04 LTS 32位 安装ns-2.35

    ubuntu12.04lts 32-bit默认采用gcc 4.6和g++4.6,而ns的最新版本ns 2.3.5也采用了相同到版本,所以这方面不会有版本不同到问题 收回上面这句话..../valida ...

  6. Ubuntu 16——安装——ns2.35和nam

    Ubuntu 16.04 安装ns2.35+nam 总结出以下安装步骤 1: 更新源 sudo apt-get update #更新源列表 sudo apt-get upgrade #更新已经安装的包 ...

  7. NS2安装过程中环境变量设置的问题(ns-2.35)

    nam: Can't find a usable tk.tcl in the following directories: */ns-allinone-2.35/tcl8.5.10/library/t ...

  8. ns2.35-classifier.cc

    line143:recv() /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* * Copyri ...

  9. NS2仿真:公交车移动周期模型及性能分析

    NS2仿真实验报告3 实验名称:公交车移动周期模型及性能分析 实验日期:2015年3月16日~2015年3月21日 实验报告日期:2015年3月22日 一.实验环境(网络平台,操作系统,网络拓扑图) ...

随机推荐

  1. $bzoj1025-SCOI2009$游戏 群论 $dp$

    题面描述 \(windy​\)学会了一种游戏.对于\(1​\)到\(N​\)这\(N​\)个数字,都有唯一且不同的1到N的数字与之对应.最开始\(windy​\)把数字按顺序\(1,2,3,\cdot ...

  2. es第二篇:Document APIs

    文档CRUD API分为单文档API和多文档API.这些API的索引名参数既可以是一个真正的索引的名称,也可以是某个索引的别名alias. 单文档API有:Index API.Get API.Dele ...

  3. C#编写运行在Linux环境下的采用Mediainfo来获取多媒体文件信息的代码

    项目开始设计的是运行在windows下,所以一开始采用的是windows服务模式来获取多媒体文件信息,后来要求调整为可以在Linux下运行,经过这两天的资料查找,实现了Linux下通过.NET来获取多 ...

  4. SQL操作Json数据

    转载自: http://blog.csdn.net/yapingxin/article/details/16913275 有小改动.. 支持复杂结构的使用.. 使用Parent_ID来对应Object ...

  5. (转)mysql帮助命令使用说明

    https://www.ilanni.com/?p=8157------- 烂泥:mysql帮助命令使用说明

  6. 【ExtJS】关于标准模块化封装组件

    在此之前,自己封装自定义控件用的是这样的方式: Ext.define('My.XXX',{ extend: 'Ext.YYY', xtype: 'ZZZ', . . . items:[ ... ] } ...

  7. Android ListView中EditView再次焦点获取

    问题:在ListView中使用EditView,当第一次将焦点给到EditView的时候弹出小键盘.使得EditView失去焦点. 分析:因为在第一次使用EditView弹出小键盘之后,会重新的调用一 ...

  8. Linux上用户之间对话

    Linux上用户之间对话 昨天想在CentOS7上与另外一个用户对话,但把命令忘记了,特此记录下来. Write命令 write命令是单向发送一条消息给同机器的Linux用户.首先通过who命令查看谁 ...

  9. vue 使用Slot 分发内容 学习总结。

    https://cn.vuejs.org/v2/guide/components.html#使用-Slot-分发内容    官方API地址 我对solt的理解是当组件中某一项需要单独定义,那么就应该使 ...

  10. Java - 如何进行安全发布

    首先让我简单解释一下所谓"发布". 发布(publish),使对象可以在当前作用域之外的代码中可见,如果该对象被发布,则该对象的非私有域中引用的所有实例同样也会被发布. 不仅仅是作 ...