ndnSIM实验--给包添加标签

Posted chenqy930

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ndnSIM实验--给包添加标签相关的知识,希望对你有一定的参考价值。

实验用到的版本是ndnSIM2.7。

添加标签的主要步骤有三个:添加标签定义、在处理包时加入标签处理、在需要的地方插入标签。前面两处的代码修改是固定的,而最后一个“在需要的地方插入标签”的实现则很灵活。

 

1、添加标签(Tag)的定义

需要修改../src/ndnSIM/ndn-cxx/ndn-cxx/lp下的fields.hpp、tlv.hpp和tags.hpp三个文件。

1.1 tags.hpp修改

修改该文件,添加Tag的定义。这里以添加一个LcdInsertTag为例。

1 typedef SimpleTag<uint64_t, 0x60000001> LcdInsertTag;

SimpleTag的定义为template<typename T, int TypeId> class SimpleTag: public Tag,它有两个模版参数。上面定义的uint64_t为typename,0x60000001为TypeId。

TypeId的规范在https://redmine.named-data.net/projects/ndn-cxx/wiki/PacketTagTypes中。在某个范围内是可以自己定义的,在这里选择0x60000001是因为前面ndnSIM定义了一个HopCountTag的TypeId为0x60000000,因此按顺序给TypeId加一。

1.2 tlv.hpp修改

修改该文件,添加Tag的tlv-numbers定义。

ndnSIM中已有一些其他tag的定义了,所以这里也是类似地写上。如下面代码的红色部分。

 1 enum {
 2   LpPacket = 100,
 3   Fragment = 80,
 4   Sequence = 81,
 5   FragIndex = 82,
 6   FragCount = 83,
 7   HopCountTag = 84,
 8   Nack = 800,
 9   NackReason = 801,
10   NextHopFaceId = 816,
11   IncomingFaceId = 817,
12   CachePolicy = 820,
13   CachePolicyType = 821,
14   CongestionMark = 832,
15   Ack = 836,
16   TxSequence = 840,
17   NonDiscovery = 844,
18   PrefixAnnouncement = 848,
19   LcdInsertTag = 849,
20 };

1.3 fields.hpp修改

1.3.1 添加Tag内容的定义,一般是Tag name+Field。例如一个Tag的名字是HopCountTag,那么这里Tag的内容名字为HopCountTagField。

这里有一系列的ndnSIM定义的其他Tag,因此可以仿照它们的定义来写。例如下面的代码加入了一个LcdInsertTagField。

//加入一个LcdInsertTagField
1
typedef FieldDecl<field_location_tags::Header, 2 uint64_t, 3 tlv::LcdInsertTag> LcdInsertTagField; 4 BOOST_CONCEPT_ASSERT((Field<LcdInsertTagField>));

1.3.2 将上面的LcdInsertTagField加入集合中。这个集合也是已有的,里面已经加入了ndnSIM定义的其他TagField,这里将上面自定义的LcdInsertTagField加入即可,如下面代码的红色部分。

 1 typedef boost::mpl::set<
 2   FragmentField,
 3   SequenceField,
 4   FragIndexField,
 5   FragCountField,
 6   NackField,
 7   NextHopFaceIdField,
 8   CachePolicyField,
 9   IncomingFaceIdField,
10   CongestionMarkField,
11   AckField,
12   TxSequenceField,
13   NonDiscoveryField,
14   PrefixAnnouncementField,
15   HopCountTagField,
16   LcdInsertTagField
17   > FieldSet;

 

2、在处理包时加入标签处理

需要修改../src/ndnSIM/NFD/daemon/face/generic-link-service.cpp,这里是将Interest和Data packet转成lp::packet的地方,因此在Interest/Data->lp::packet和lp::packet->Interest/Data两个方向都要加入标签处理。

2.1 修改generic-link-service.cpp

2.1.1 Interest/Data->lp::packet方向,修改encodeLpFields()方法。

ndnSIM中已经有其他Tag的处理了,这里是按照他们的处理方法将LcdInsertTag加上去。

 1 void
 2 GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
 3 {
 4   /**
 5   * 其他原有的Tag处理
 6   **/
//判断Interest/Data中是否有LcdInsertTag,如果有,加入到lpPacket中。
7 shared_ptr<lp::LcdInsertTag> lcdInsertTag = netPkt.getTag<lp::LcdInsertTag>(); 8 if(lcdInsertTag != nullptr){ 9 lpPacket.add<lp::LcdInsertTagField>(*lcdInsertTag); 10 NFD_LOG_DEBUG("LcdInsertTag in generic-link-service in encodeLpFields: " << *lcdInsertTag); 11 }else{ 12 NFD_LOG_DEBUG("LcdInsertTag in generic-link-service in encodeLpFields: lost**********"); 13 } 14 }

2.2.2 lp::packet->Interest/Data方向,修改decodeData()或者decodeInterest()方法

如果标签是加入在Data中,那么需要修改decodeData();如果标签是加入Interest中,那么需要修改decodeInterest()。

以修改decodeData()为例,

 1 void
 2 GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
 3 {
 4  /**
 5    * 其他原有Tag的处理
 6    */
 7   //判断packet中是否有LcdInsertTagField,如果有,构造Tag加入到数据包中。
 8   if(firstPkt.has<lp::LcdInsertTagField>()){
 9     data->setTag(make_shared<lp::LcdInsertTag>(firstPkt.get<lp::LcdInsertTagField>()));
10   }
11 
12   this->receiveData(*data);
13 }

 

3、在需要的地方插入标签

这个可以根据实验的算法在代码的任意位置插入。比较常用的有两处:一是在消费者/生产者产生数据包或兴趣包时,即在Consumer/Producer的实现类中;二是在路由节点处理每个到达的的兴趣包或数据包时,即在../NFD/daemon/forwarder.cpp中。

如果某处代码以前没有使用过标签,要记得加上头文件 #include<ndn-cxx/lp/tags.hpp>

以在Producer产生数据包时加入标签为例,可以通过修改../src/ndnSIM/apps/ndn-producer.cpp中的onInterest()实现:

 1  #include <ndn-cxx/lp/tags.hpp>
 2  void
 3   Producer::OnInterest(shared_ptr<const Interest> interest)
 4   {
 5     /**
 6      * 其他处理
 7      */
 8     //使用setTag()方法加入LcdInsertTag,并且Tag的数值设置为2.
 9     data->setTag(make_shared<lp::LcdInsertTag>(2));
10     //输出LcdInsertTag的值进行检查
11    NS_LOG_INFO("Data packet add LcdInsertTag: " << data->getTag<lp::LcdInsertTag>()->get());
12  
13    // to create real wire encoding
14    data->wireEncode();
15  
16    m_transmittedDatas(data, this, m_face);
17    m_appLink->onReceiveData(*data);
18  }

 

4、实验验证

以0-->1-->2这样的拓扑为例,节点2为producer,在producer产生的Data中加入标签,可以看到节点1和节点0收到的Data中都能读到这个标签中的数据。

技术图片

 

以上是关于ndnSIM实验--给包添加标签的主要内容,如果未能解决你的问题,请参考以下文章

ndnSIM学习——ndnSIM源码阅读计划

操作栏标签片段中的片段?

在标签片段android中添加谷歌地点选择器

如何在 FragmentPagerAdapter 中添加片段标签以便稍后引用片段?

在 JSP 中的 <% %> 代码片段中添加链接

在片段中添加 ListView