文章目录

  • 前言
  • ndn-producer.hpp
  • ndn-consumer.hpp
  • ndn-consumer-cbr.hpp
  • 其他消费者

前言

在前面的文章ndnSIM学习(四)——examples之ndn-simple.cpp超详细剖析中,我们逐行剖析了 ndn-simple.cpp 这个example的代码逻辑。其中消费者consumer和生产者producer是整个代码运行的重点。

在前面的文章ndnSIM学习(九)——从consumer发兴趣包到producer返回data包的全过程中,我们剖析了整个兴趣包的发包收包过程。今天,就让我们一起来看看消费者consumer和生产者producer都在做些什么吧

因为producer的代码相比consumer的代码更简单,仿照庖丁解牛,我们从难啃的硬骨头间的空隙(producer)出发,来分析apps的工作流程。

ndn-producer.hpp

~/ndnSIM/ns-3/src/ndnSIM/apps/ndn-producer.hpp 文件中定义了ndnSIM中生产者(producer)类的定义,代码如下(我手动加了一些注释,直接看注释应该就能看懂了吧,不详细讲了)——

class Producer : public App {public:// 接口,返回关于本类对象的TypeId信息,方便外部配置static TypeId GetTypeId(void);// 构造函数,每当构造一个对象时,日志里输出相关信息// e.g. 输出[+0.000000000s 2 ndn.Producer:Producer()]Producer();  // 收到interest包后,装载一个data包(内部有编码为block的成员),最后把任务交接给到m_appLink->onReceiveData// 后续详见下面的流程图virtual void OnInterest(shared_ptr<const Interest> interest);protected:// 调用App创建相关的App管理接口,如AppLinkService这种东西,并把管理链路层和传输层的接口放到Ndn Stack里virtual void StartApplication(); // Called at time specified by Start// m_active = false并关闭m_facevirtual void StopApplication(); // Called at time specified by Stopprivate:Name m_prefix;  // 前缀Name m_postfix;  // 后缀uint32_t m_virtualPayloadSize;  // 一个包装载数据byte数Time m_freshness;  // Fresh timeuint32_t m_signature;  // SignatureValueName m_keyLocator;
};

发包收包过程流程图

ndn-consumer.hpp

~/ndnSIM/ns-3/src/ndnSIM/apps/ndn-consumer.hpp 文件中定义了ndnSIM中消费者(consumer)类的定义,代码如下(我手动加了一些注释,直接看注释应该就能看懂了吧,不详细讲了)——

class Consumer : public App {public:// 接口,返回关于本类对象的TypeId信息static TypeId GetTypeId();// 构造函数以及虚析构函数(便于派生)Consumer();virtual ~Consumer(){};// 收到消费者返回的Data包,执行相应的处理与回显,并更新RTT(Round-Trip Time)virtual void OnData(shared_ptr<const Data> contentObject);// 如果Not ACK,显示对应的信息与原因virtual void OnNack(shared_ptr<const lp::Nack> nack);// 超时就重传(RTT翻倍)virtual void OnTimeout(uint32_t sequenceNumber);// 发interest包,该函数由ScheduleNextPacket设置事件触发// 该函数给interest包填充信息后把任务交接给m_appLink->onReceiveInterest准备向自己的链路层发interestvoid SendPacket();// 在兴趣包实际发送之前的准备工作virtual void WillSendOutInterest(uint32_t sequenceNumber);public:typedef void (*LastRetransmittedInterestDataDelayCallback)(Ptr<App> app, uint32_t seqno, Time delay, int32_t hopCount);  // 函数指针类型typedef void (*FirstInterestDataDelayCallback)(Ptr<App> app, uint32_t seqno, Time delay, uint32_t retxCount, int32_t hopCount);  // 函数指针类型protected:// 调用App创建相关的App管理接口,如AppLinkService这种东西,并把管理链路层和传输层的接口放到Ndn Stack里// 创建完执行ScheduleNextPacket,调用派生类的发包控制函数virtual void StartApplication();// m_active = false并关闭m_facevirtual void StopApplication();// 发包的调度策略,如Cbr就是以恒定速率发包(纯虚函数,由子类实现)virtual void ScheduleNextPacket() = 0;// 检查数据包是否需要超时重传void CheckRetxTimeout();// 设置检查重传超时的频率void SetRetxTimer(Time retxTimer);// 获取当前检查重传超时的频率Time GetRetxTimer() const;protected:Ptr<UniformRandomVariable> m_rand; // 随机数nonce生成器uint32_t m_seq;      // 标志目前的请求序列数值sequint32_t m_seqMax;   // 最多请求多少个seqEventId m_sendEvent; // 发包对应的事件Id,在子类的发包事件中会返回一个发包事件Id,当App结束时,将会取消掉该事件Time m_retxTimer;    // 重传时间EventId m_retxEvent; // m_retxEvent对应的事件IdPtr<RttEstimator> m_rtt; // RTT估计器Time m_offTime;          ///< \brief Time interval between packetsName m_interestName;     // 就是ndn-simple.cpp设置的PrefixTime m_interestLifeTime; // 就是ndn-simple.cpp设置的LifeTime// 省略部分定义RetxSeqsContainer m_retxSeqs; // 重传序列,每当超时的时候,就将目标序列号加入该重传序列SeqTimeoutsContainer m_seqTimeouts; // 超时序列号+时间SeqTimeoutsContainer m_seqLastDelay;// SeqTimeoutsContainer m_seqFullDelay;std::map<uint32_t, uint32_t> m_seqRetxCounts;TracedCallback<Ptr<App> /* app */, uint32_t /* seqno */, Time /* delay */, int32_t /*hop count*/>m_lastRetransmittedInterestDataDelay;TracedCallback<Ptr<App> /* app */, uint32_t /* seqno */, Time /* delay */,uint32_t /*retx count*/, int32_t /*hop count*/> m_firstInterestDataDelay;
};

ndn-consumer-cbr.hpp

ndn-simple.cpp 里的消费者是 ConsumerCbr ,其中我推测 Cbr 的含义是 Constant BitRate 的缩写,所以 ConsumerCbr 其实就是以常数速率发包的消费者。这里我对这种类型的消费者进行一些讲解,还是老规矩,看代码注释,我不说废话

class ConsumerCbr : public Consumer {public:static TypeId GetTypeId();ConsumerCbr();virtual ~ConsumerCbr();protected:// 发包规则:以常数频率Frequence发interestvirtual void ScheduleNextPacket();// 设置随机性规则,可以选择均匀分布、泊松分布void SetRandomize(const std::string& value);// 获取随机规则std::string GetRandomize() const;protected:double m_frequency;  // 发包频率bool m_firstTime;  // 标志是不是第一次请求Ptr<RandomVariableStream> m_random;  // 随机数生成器std::string m_randomType;  // 随机的规则
};

其他消费者

因为基类 Consumer 的函数 ScheduleNextPacket 是纯虚函数,所以消费者一定得用其派生类,比如前面的 ConsumerCbr 就是一个派生类。这里列举一下ndnSIM的消费者(我没细看,可能有错误,仅供参考)

  • ConsumerBatches 用于批量管理消费者,下面管理了一个消费者的节点链表。一旦 ConsumerBatches::StartApplication 被执行,整个类就会为它管理的所有节点执行 ConsumerBatches::ScheduleNextPacket 。其中每过 m_rtt->RetransmitTimeout() 就会触发该消费者的 Consumer::SendPacket
  • ConsumerCbr 是以恒定速率发送兴趣包请求的消费者。
  • ConsumerZipfMandelbrot 继承了 ConsumerCbr ,发包服从Zipf-Mandelbrot律,我也不知道是什么玩意。
  • ConsumerWindow 似乎是以滑动窗口的方式执行拥塞控制的消费者,我没有仔细看里面的代码,所以并不确定。代码里提到本类是高度实验性的,要小心使用
  • ConsumerPcon 继承了 ConsumerWindow 类,参考了论文https://dl.acm.org/citation.cfm?id=2984369

ndnSIM学习(十)——apps之ndn-producer.cpp和ndn-consumer.cpp源码分析相关推荐

  1. 分布式定时任务—xxl-job学习(四)——调度中心web页面端api调用源码分析

    分布式定时任务-xxl-job学习(四)--调度中心web页面端api调用源码分析 前言 一.controller目录下非controller类 1.1 PermissionLimit自定义注解 1. ...

  2. RocketMQ:Producer启动流程与消息发送源码分析

    文章目录 Producer 1.方法和属性 2.启动流程 3.消息发送 3.1验证消息 3.2查找路由 3.3选择队列 3.4发送消息 3.5发送批量消息 Producer 在RocketMQ中,消息 ...

  3. 【Android 逆向】整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )

    文章目录 前言 一.DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 二./bin/dexopt 源码分析 前言 上一篇博客 [Android 逆向]整体加固脱壳 ...

  4. activiti学习(二十一)——流程虚拟机源码分析(三)——从进入到离开userTask

    前言 承接上文<activiti学习(二十)--流程虚拟机源码分析(二)--从开始节点离开到下个节点前>,假设execution接下来进入的节点是userTask,本文分析一下进入user ...

  5. Java的wait()、notify()学习三部曲之一:JVM源码分析

    原文链接:https://blog.csdn.net/boling_cavalry/article/details/77793224 综述 Java的wait().notify()学习三部曲由三篇文章 ...

  6. 【vue-router源码】十二、useRoute、useRouter、useLink源码分析

    [vue-rouer源码]系列文章 [vue-router源码]一.router.install解析 [vue-router源码]二.createWebHistory.createWebHashHis ...

  7. Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树

    Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 文章目录 Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 0x00 摘要 0x01 背景概念 1.1 词向量 ...

  8. 近200篇机器学习深度学习资料分享(含各种文档,视频,源码等)(1)

    原文:http://developer.51cto.com/art/201501/464174.htm 编者按:本文收集了百来篇关于机器学习和深度学习的资料,含各种文档,视频,源码等.而且原文也会不定 ...

  9. 深度学习库 caffe使用 源码分析 依赖库分析 caffe glog gflags openBlas prototxt yolo_darknet 转 caffe

    深度学习库 caffe使用 源码分析 依赖库分析 caffe glog gflags openBlas 本文github链接 yolo_darknet 转 caffe caffe 安装 Caffe代码 ...

  10. Spring 源码分析衍生篇十 :Last-Modified 缓存机制

    文章目录 一.前言 二.Last-Modify 三.实现方案 1. 实现 org.springframework.web.servlet.mvc.LastModified接口 1.1. 简单演示 1. ...

最新文章

  1. python写的程序怎么打包成exe_python--- 如何将自己的程序打包成exe ?
  2. mysql通用日志不打印_解决logback不打印mybatis的SQL日志的问题
  3. 李飞飞夫妇打造了两件秘密武器,让机器人快速学习人类技能
  4. 神奇的反爬措施--大众点评
  5. 9. Document getElementsByName() 方法
  6. 服务器系列和酷睿系列,三大系列 从英特尔主流处理器选择服务器(2)
  7. 周志华-机器学习.pdf 学习心得 附整理材料
  8. 实对称矩阵的特征值求法_正交矩阵学习小结
  9. vue清除路由历史记录
  10. 微信开放平台基于网站应用授权登录源码(java)
  11. W33 - 999、Web站点安全监控
  12. 漫步数学分析三十九——隐函数定理
  13. volatile限定符——C++讲解
  14. php收短信,PHP飞信接收短信类
  15. 【全网热点】打造全网最全爱心代码仓库【火速领取爱心】
  16. 10-200 C2-2修改特定职工的订单运费
  17. LeetCode(数据库)- Users That Actively Request Confirmation Messages
  18. springboot整合mysql5.7_SpringBoot+MySQL,如何整合并使用MyBatis框架
  19. deepin 输入法频繁重启,无法正常输入汉字解决方法
  20. 大学生个人网页模板 简单网页制作作业成品 极简风格个人介绍HTML(个人博客 4页)

热门文章

  1. ftp服务器为我方,对方发送数据,巡检光衰数据导入es
  2. 驱动开发指南 第八章 汇编LED灯实验
  3. 【人工智能】3.谓词与机器推理
  4. python绘制随机网络图形
  5. opencv把图片转换成二进制_Python+OpenCV实现将图像转换为二进制格式
  6. 微博html5到桌面,HTML 分享页面到QQ/微信、微博等平台
  7. 【多校训练】2021牛客多校第一场
  8. PDPS软件:机器人工作站工艺仿真操作流程
  9. 北邮php,周琳娜-北京邮电大学网络空间安全学院
  10. 编译原理——自上而下语法分析