ndnSIM学习(十一)——data.cpp和interest.cpp源码分析

前言

data.cppinterest.cpp 用于处理兴趣包和数据包。

data.hpp

删掉了部分我认为不重要的东西,比如 class Error 。这里面的 wireEncode 属于是经典的模板编程的例子,看这种代码真是吐了。不过看懂了其实还好,这个代码的意思就是先用 EncodingEstimator 计算出需要的 buffer 的大小,然后再用 EncodingBuffer 造出一个真正的 buffer ,对这个 buffer 执行 wireDecode 函数,更新自己的成员函数。

class Data : public PacketBase, public std::enable_shared_from_this<Data>
{
public:
  // 构造一个Name为name的空Data包
  explicit Data(const Name& name = Name());
  // 通过对Block进行解码,构造出一个Data包
  explicit Data(const Block& wire);

  // 对内容进行Encode,其中TAG分为EncodingEstimator和EncodingBuffer
  template<encoding::Tag TAG>
  size_t wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
  const Block& wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
  // 先执行wireEncode<EncodingEstimator>,这部分用于计算buffer的大小,不执行操作
  // 再执行wireEncode<EncodingBuffer>,这部分用于真正创建一个buffer,并对它进行Encode操作
  // 最后把buffer用于执行wireDecode,更新本Data的成员函数
  const Block& wireEncode() const;
  
  // 按照Name->MetaInfo(?)->Content(?)->SignatureInfo->SignatureValue的顺序解码到自己的成员函数里
  void wireDecode(const Block& wire);

  bool hasWire() const { return m_wire.hasWire(); }
  const Name& getFullName() const;  // return m_name(以及对应的ImplicitSha256Digest组件)

public: // 数据的Get和Set
  const Name& getName() const { return m_name; }
  Data& setName(const Name& name);  // return m_name
  const MetaInfo& getMetaInfo() const { return m_metaInfo; }
  Data& setMetaInfo(const MetaInfo& metaInfo);
  const Block& getContent() const;
  Data& setContent(const Block& block);
  Data& setContent(const uint8_t* value, size_t valueSize);
  Data& setContent(ConstBufferPtr value);
  const Signature& getSignature() const { return m_signature; }
  Data& setSignature(const Signature& signature);
  Data& setSignatureValue(const Block& value);

public: // MetaInfo的Get和Set
  uint32_t getContentType() const { return m_metaInfo.getType(); }
  Data& setContentType(uint32_t type);
  time::milliseconds getFreshnessPeriod() const { return m_metaInfo.getFreshnessPeriod(); }
  Data& setFreshnessPeriod(time::milliseconds freshnessPeriod);
  const optional<name::Component>& getFinalBlock() const { return m_metaInfo.getFinalBlock(); }
  Data& setFinalBlock(optional<name::Component> finalBlockId);

protected:
  void resetWire();    // 每次set后都要重置wire

private:
  Name m_name;
  MetaInfo m_metaInfo;
  Block m_content;
  Signature m_signature;

  mutable Block m_wire;
  mutable Name m_fullName; ///< cached FullName computed from m_wire
};

#ifndef DOXYGEN
extern template size_t
Data::wireEncode<encoding::EncoderTag>(EncodingBuffer&, bool) const;

extern template size_t
Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
#endif

std::ostream& operator<<(std::ostream& os, const Data& data);

bool operator==(const Data& lhs, const Data& rhs);

inline bool operator!=(const Data& lhs, const Data& rhs) { return !(lhs == rhs); }

关于具体的编解码过程,请参考ndnSIM学习(五)——data包和interest包的tlv编码、解码过程以及如何判断包的类型这篇文章,这里面主要讲了 tlv 相关的东西。ndnSIM学习(八)——apps之ndn-producer.cpp和ndn-consumer.cpp源码分析这篇文章里主要讲了发包和收包的过程。

interest.hpp

删掉了部分我认为不重要的东西,比如 class Error 。大部分内容和 Data 是类似的,不过其中关于 SHA256 加密这块我还是没怎么搞明白。

// 默认interest生存时间为4s
const time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;

class Interest : public PacketBase, public std::enable_shared_from_this<Interest>
{
public:
  // 初始化Name&lifetime
  explicit Interest(const Name& name = Name(), time::milliseconds lifetime = DEFAULT_INTEREST_LIFETIME);
  // 用Block造一个Interest
  explicit Interest(const Block& wire);

  template<encoding::Tag TAG>
  size_t wireEncode(EncodingImpl<TAG>& encoder) const;
  // 先执行wireEncode<EncodingEstimator>,这部分用于计算buffer的大小,不执行操作
  // 再执行wireEncode<EncodingBuffer>,这部分用于真正创建一个buffer,并对它进行Encode操作
  // 最后把buffer用于执行wireDecode,更新本Data的成员函数
  const Block& wireEncode() const;

  // Name(SHA256?)->CanBePrefix?->MustBeFresh?->ForwardingHint?->Nonce->InterestLifetime?->HopLimit?->ApplicationParameters?
  void wireDecode(const Block& wire);

  bool hasWire() const { return m_wire.hasWire(); }
  std::string toUri() const;

public: // 匹配
  // 看Interest是否能匹配上Data
  bool matchesData(const Data& data) const;
  // 比较Name和CanBePrefix和MustBeFresh
  bool matchesInterest(const Interest& other) const;

public: // element access
  const Name& getName() const noexcept { return m_name; }
  // set m_name,并且如果自己的m_parameters有SHA256参数,则添加到m_name
  Interest& setName(const Name& name);
  static void setDefaultCanBePrefix(bool canBePrefix) { s_defaultCanBePrefix = canBePrefix; }
  bool getCanBePrefix() const noexcept { return m_canBePrefix; }
  Interest& setCanBePrefix(bool canBePrefix) {
    m_canBePrefix = canBePrefix;
    m_wire.reset();
    m_isCanBePrefixSet = true;
    return *this;
  }
  bool getMustBeFresh() const noexcept { return m_mustBeFresh; }
  Interest& setMustBeFresh(bool mustBeFresh) {
    m_mustBeFresh = mustBeFresh;
    m_wire.reset();
    return *this;
  }
  const DelegationList& getForwardingHint() const noexcept { return m_forwardingHint; }
  Interest& setForwardingHint(const DelegationList& value);
  template<typename Modifier>
  Interest& modifyForwardingHint(const Modifier& modifier) {
    modifier(m_forwardingHint);
    m_wire.reset();
    return *this;
  }
  bool hasNonce() const noexcept { return m_nonce.has_value(); }
  uint32_t getNonce() const;
  Interest& setNonce(uint32_t nonce);
  void refreshNonce();
  time::milliseconds getInterestLifetime() const noexcept { return m_interestLifetime; }
  Interest& setInterestLifetime(time::milliseconds lifetime);
  optional<uint8_t> getHopLimit() const noexcept { return m_hopLimit; }
  Interest& setHopLimit(optional<uint8_t> hopLimit);
  bool hasApplicationParameters() const noexcept { return !m_parameters.empty(); }
  Block getApplicationParameters() const {
    if (m_parameters.empty())
      return {};
    else
      return m_parameters.front();
  }
  Interest& setApplicationParameters(const Block& parameters);
  Interest& setApplicationParameters(const uint8_t* value, size_t length);
  Interest& setApplicationParameters(ConstBufferPtr value);
  Interest& unsetApplicationParameters();

public: // ParametersSha256DigestComponent support
  static bool getAutoCheckParametersDigest() { return s_autoCheckParametersDigest; }
  static void setAutoCheckParametersDigest(bool b) { s_autoCheckParametersDigest = b; }
  bool isParametersDigestValid() const;

private:
  void setApplicationParametersInternal(Block parameters);
  NDN_CXX_NODISCARD shared_ptr<Buffer> computeParametersDigest() const;
  // 添加SHA256组件
  void addOrReplaceParametersDigestComponent();
  // 如果有1个SHA256组件,返回pos;没有返回-1;多个返回-2
  static ssize_t findParametersDigestComponent(const Name& name);

#ifdef NDN_CXX_HAVE_TESTS
public:
  /// If true, not setting CanBePrefix results in an error in wireEncode().
  static bool s_errorIfCanBePrefixUnset;
#endif // NDN_CXX_HAVE_TESTS

private:
  static boost::logic::tribool s_defaultCanBePrefix;
  static bool s_autoCheckParametersDigest;

  Name m_name;
  DelegationList m_forwardingHint;
  mutable optional<uint32_t> m_nonce;
  time::milliseconds m_interestLifetime;
  optional<uint8_t> m_hopLimit;
  mutable bool m_isCanBePrefixSet = false;
  bool m_canBePrefix = true;
  bool m_mustBeFresh = false;

  std::vector<Block> m_parameters;

  mutable Block m_wire;
};

// 输出CanBePrefix和MustBeFresh和Nonce和Lifetime和HopLimit
std::ostream& operator<<(std::ostream& os, const Interest& interest);

总结

里面内容细节太多了,其中部分我在其他文章中分析过,所以只给 .hpp 文件加了注释,没有分析 .cpp 文件的函数。这篇文章写得有点水……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
paho.mqtt.cpp是一个用于MQTT(Message Queuing Telemetry Transport)协议的C++库。它提供了一组用于与MQTT代理进行通信的函数和类。这个库是基于paho.mqtt.c库封装实现的,可以在C++项目环境下作为组件使用。 如果我们想要对paho.mqtt.cpp代码进行分析,我们可以通过查看paho.mqtt.cpp.zip压缩包中的工程文件来了解其内部结构和功能。该压缩包包含了VS2019编译好的paho.mqtt.cpp的工程文件。 在代码分析过程中,我们可以查看头文件和源文件,了解库的类、函数和成员变量的定义和实现。通过分析这些代码,我们可以了解库的功能和使用方法。同时,我们还可以参考相关博客或教程,以获取更详细的信息和示例代码。 需要注意的是,为了能够正确使用paho.mqtt.cpp库,我们需要先安装paho.mqtt.c库。这样才能在C++项目中正确使用paho.mqtt.cpp库的功能。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [VS2019编译完成的paho.mqtt.cpp库](https://download.csdn.net/download/zhh763984017/12195122)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [基于paho.mqtt.c用C++封装实现mqtt](https://download.csdn.net/download/qq_25662827/77133536)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值