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实验--给包添加标签的主要内容,如果未能解决你的问题,请参考以下文章