ndnsim上实现数据推送功能
NDNSIM上实现数据推送,首先需要新添一个推送类型,然后修改数据包编码方式。
- 在tlv.hpp中新添推送类型
1 | IFPUSH = 101, |
- 然后修改数据包编解码,data.hpp和data.cpp
1 | //data.hpp中添加若干方法和两个新的数据成员 |
然后就是对转发管道forwarder进行修改,首先对是否是推送包进行判断,如果是推送包,直接进入onIncomingPushData管道1
2
3
4//2022.12.21新添加,对是否是推送包进行判断
if(data.getIfpush() == true) {
this->onIncomingPushData(ingress, data);
}
然后需要添加onIncomingPushData和onOutgoingPushData管道,其中onIncomingPushData开始接受数据包和缓存部分参考了onIncomingData,根据NextHopFaceId进行查找进行数据包转发参考了onIncomingInterest1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73//2022.12.21 节点受到推送包,这里应该负责判断本节点是否要缓存数据,然后根据一定的转发方法交给onOutgoingPushData转发,基本就是把onIncomingData中PIT的部分删掉。
void
Forwarder::onIncomingPushData(const FaceEndpoint& ingress, const Data& data)
{
// receive Data
NFD_LOG_DEBUG("onIncomingPushData in=" << ingress << " data=" << data.getName().get(-2));
data.setTag(make_shared<lp::IncomingFaceIdTag>(ingress.face.getId()));
++m_counters.nInPushData;
// /localhost scope control
bool isViolatingLocalhost = ingress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
scope_prefix::LOCALHOST.isPrefixOf(data.getName());
if (isViolatingLocalhost) {
NFD_LOG_DEBUG("onIncomingPushData in=" << ingress << " data=" << data.getName() << " violates /localhost");
// (drop)
return;
}
//添加缓存策略,这部分和前面的onIncomingData一样
if(*(m_cs.getPolicy()->getPolicyNames().begin())=="lcdlru") {
if(ingress.face.getLocalUri().toString()=="appFace://") {
data.setTag(make_shared<lp::CachePlacementPolicyTag>(1));
}
NS_LOG_DEBUG("LZH 2022-12-21 ingress.face:" << ingress.face.getLocalUri()
<< " remoteUri:" << ingress.face.getRemoteUri() << " Id:" << ingress.face.getId());
}
// CS insert
m_cs.insert(data);
//然后根据NextHopFaceId进行查找,再对数据包进行转发,模仿兴趣包,具体兴趣包怎么添加上的tag后面还得看
// has NextHopFaceId?
auto nextHopTag = data.getTag<lp::NextHopFaceIdTag>();
if (nextHopTag != nullptr) {
// chosen NextHop face exists?
Face* nextHopFace = m_faceTable.get(*nextHopTag);
if (nextHopFace != nullptr) {
NFD_LOG_DEBUG("onContentStoreMiss interest=" << data.getName()
<< " nexthop-faceid=" << nextHopFace->getId());
// go to outgoing Interest pipeline
// scope control is unnecessary, because privileged app explicitly wants to forward
this->onOutgoingPushData(data, FaceEndpoint(*nextHopFace, 0));
}
return;
}
}
//应该根据NextHopFaceId进行转发,参考了onOutgoingData
void
Forwarder::onOutgoingPushData(const Data& data, const FaceEndpoint& egress)
{
if (egress.face.getId() == face::INVALID_FACEID) {
NFD_LOG_WARN("onOutgoingPushData out=(invalid) data=" << data.getName().getSubName(-2));
return;
}
NFD_LOG_INFO("onOutgoingPushData out=" << egress << " data=" << data.getName());
// /localhost scope control
bool isViolatingLocalhost = egress.face.getScope() == ndn::nfd::FACE_SCOPE_NON_LOCAL &&
scope_prefix::LOCALHOST.isPrefixOf(data.getName());
if (isViolatingLocalhost) {
NFD_LOG_INFO("onOutgoingPushData out=" << egress << " data=" << data.getName() << " violates /localhost");
// (drop)
return;
}
// TODO traffic manager
// send Data
egress.face.sendData(data, egress.endpoint);
++m_counters.nOutPushData;
}
此外还需要修改forwarder.hpp头文件和forwarder-counters.hpp头文件
2022.12.21修改
首先为了实现订阅机制,需要新添数据包注册的文件,data-filter.hpp,data-filter.cpp和data-filter-record.hpp,同时还需要修改ndn-cxx中的face.hpp,添加回调功能,基本就是在interest基础上改成了data,变化不大。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329//data-filter.hpp
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
namespace ndn {
class RegexPatternListMatcher;
/**
* @brief declares the set of Interests a producer can serve,
* which starts with a name prefix, plus an optional regular expression
*/
class DataFilter
{
public:
class Error : public std::runtime_error
{
public:
using std::runtime_error::runtime_error;
};
/**
* @brief Construct an DataFilter to match Interests by prefix
*
* This filter matches Interests whose name start with the given prefix.
*
* @note DataFilter is implicitly convertible from Name.
*/
DataFilter(const Name& prefix);
/**
* @brief Construct an InterestFilter to match Interests by prefix
*
* This filter matches Interests whose name start with the given prefix.
*
* @param prefixUri name prefix, interpreted as ndn URI
* @note InterestFilter is implicitly convertible from null-terminated byte string.
*/
DataFilter(const char* prefixUri);
/**
* @brief Construct an InterestFilter to match Interests by prefix
*
* This filter matches Interests whose name start with the given prefix.
*
* @param prefixUri name prefix, interpreted as ndn URI
* @note InterestFilter is implicitly convertible from std::string.
*/
DataFilter(const std::string& prefixUri);
/**
* @brief Construct an InterestFilter to match Interests by prefix and regular expression
*
* This filter matches Interests whose name start with the given prefix and
* the remaining components match the given regular expression.
* For example, the following InterestFilter:
*
* InterestFilter("/hello", "<world><>+")
*
* matches Interests whose name has prefix `/hello` followed by component `world`
* and has at least one more component after it, such as:
*
* /hello/world/%21
* /hello/world/x/y/z
*
* Note that regular expression will need to match all components (e.g., there are
* implicit heading `^` and trailing `$` symbols in the regular expression).
*/
DataFilter(const Name& prefix, const std::string& regexFilter);
/**
* @brief Implicit conversion to Name
* @note This allows InterestCallback to be declared with `Name` rather than `InterestFilter`,
* but this does not work if InterestFilter has regular expression.
*/
operator const Name&() const;
/**
* @brief Check if specified Interest name matches the filter
*/
bool
doesMatch(const Name& name) const;
const Name&
getPrefix() const
{
return m_prefix;
}
bool
hasRegexFilter() const
{
return m_regexFilter != nullptr;
}
const RegexPatternListMatcher&
getRegexFilter() const
{
return *m_regexFilter;
}
/** \brief Get whether Interest loopback is allowed
*/
NDN_CXX_NODISCARD bool
allowsLoopback() const
{
return m_allowsLoopback;
}
/** \brief Set whether Interest loopback is allowed
* \param wantLoopback if true, this DataFilter may receive Interests that are expressed
* locally on the same \p ndn::Face ; if false, this InterestFilter can only
* receive Interests received from the forwarder. The default is true.
*/
DataFilter&
allowLoopback(bool wantLoopback)
{
m_allowsLoopback = wantLoopback;
return *this;
}
private:
Name m_prefix;
shared_ptr<RegexPatternListMatcher> m_regexFilter;
bool m_allowsLoopback = true;
};
std::ostream&
operator<<(std::ostream& os, const DataFilter& filter);
} // namespace ndn
//data.filter.cpp
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
namespace ndn {
DataFilter::DataFilter(const Name& prefix)
: m_prefix(prefix)
{
}
DataFilter::DataFilter(const char* prefixUri)
: m_prefix(prefixUri)
{
}
DataFilter::DataFilter(const std::string& prefixUri)
: m_prefix(prefixUri)
{
}
DataFilter::DataFilter(const Name& prefix, const std::string& regexFilter)
: m_prefix(prefix)
, m_regexFilter(make_shared<RegexPatternListMatcher>(regexFilter, nullptr))
{
}
DataFilter::operator const Name&() const
{
if (hasRegexFilter()) {
NDN_THROW(Error("Please update InterestCallback to accept `const InterestFilter&'"
" (non-trivial InterestFilter is being used)"));
}
return m_prefix;
}
bool
DataFilter::doesMatch(const Name& name) const
{
return m_prefix.isPrefixOf(name) &&
(!hasRegexFilter() ||
m_regexFilter->match(name, m_prefix.size(), name.size() - m_prefix.size()));
}
std::ostream&
operator<<(std::ostream& os, const DataFilter& filter)
{
os << filter.getPrefix();
if (filter.hasRegexFilter()) {
os << "?regex=" << filter.getRegexFilter();
}
return os;
}
} // namespace ndn
//data-filter-record.hpp
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
namespace ndn {
/**
* @brief Opaque type to identify an InterestFilterRecord
*/
class DataFilterId;
static_assert(sizeof(const DataFilterId*) == sizeof(RecordId), "");
/**
* @brief associates an InterestFilter with Interest callback
*/
class DataFilterRecord : public RecordBase<DataFilterRecord>
{
public:
/**
* @brief Construct an Interest filter record
*
* @param filter an InterestFilter that represents what Interest should invoke the callback
* @param interestCallback invoked when matching Interest is received
*/
DataFilterRecord(const DataFilter& filter,
const PushDataCallback& pushdataCallback)
: m_filter(filter)
, m_pushdataCallback(pushdataCallback)
{
}
const DataFilter&
getFilter() const
{
return m_filter;
}
/**
* @brief Check if Interest name matches the filter
* @param name Interest Name
*/
bool
doesMatch(const Data& data) const
{
//std::cout << " ------------DataFilterRecord::doesMatch entry is OK " << std::endl;
return (m_filter.doesMatch(data.getName()));
}
/**
* @brief invokes the PushdataCallback 这里用于处理推送包回调
* @note This method does nothing if the Interest callback is empty
*/
void
invokeDataCallback(const Data& data) const
{
if (m_pushdataCallback != nullptr) {
m_pushdataCallback(m_filter, data);
}
}
private:
DataFilter m_filter;
//需要修改face.hpp
PushDataCallback m_pushdataCallback;
};
} // namespace ndn
修改face.hpp1
2
3
4
5//2022.12.22新添加推送数据包的回调
/**
* @brief Callback invoked when incoming PushData matches the specified InterestFilter
*/
typedef function<void(const DataFilter&, const Data&)> PushDataCallback;
修改ndn-cxx的face受到data包的逻辑1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44void
Face::onReceiveElement(const Block& blockFromDaemon) //一方面对本地的兴趣包进行处理,另一方面对NFD返回的数据包进行处理。想要修改推送机制就要在这改
{
lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
// no need to distinguish
Buffer::const_iterator begin, end;
std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
Block netPacket(&*begin, std::distance(begin, end));
switch (netPacket.type()) {
case tlv::Interest: { //处理兴趣包,兴趣包可能是应用层向NFD注册的添加管理信息,不需要NFD转发的,也可能是真正想要请求数据包需要NFD转发的
auto interest = make_shared<Interest>(netPacket);
if (lpPacket.has<lp::NackField>()) {
auto nack = make_shared<lp::Nack>(std::move(*interest));
nack->setHeader(lpPacket.get<lp::NackField>());
extractLpLocalFields(*nack, lpPacket);
NDN_LOG_DEBUG(">N " << nack->getInterest() << '~' << nack->getHeader().getReason());
m_impl->nackPendingInterests(*nack);
}
else {
extractLpLocalFields(*interest, lpPacket);
NDN_LOG_DEBUG(">I " << *interest);
m_impl->processIncomingInterest(std::move(interest));
}
break;
}
case tlv::Data: {
auto data = make_shared<Data>(netPacket);
extractLpLocalFields(*data, lpPacket);
NDN_LOG_DEBUG(">D " << data->getName());
//2022.12.22 添加对NFD向应用层返回的数据包的处理
if(data->getIfpush() == true) {
m_impl->ProcessIncomingPushDatas(std::move(data));
break;
}
else {
m_impl->satisfyPendingInterests(*data);
break;
}
//m_impl->satisfyPendingInterests(*data);
//break;
}
}
}
然后修改face-impl.hpp文件,添加ProcessIncomingPushDatas和dispatchData管道1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30//2022.12.22新添对推送数据包的处理管道
void
ProcessIncomingPushDatas(shared_ptr<const Data> data)
{
const Data& data2 = *data;
dispatchPushData(data2);
//NS_LOG_UNCOND(" ------------ ZY. Face::Impl::processIncomingInterest interest2:" << interest2.getName());
}
void
dispatchPushData(const Data& data)
{
m_dataFilterTable.forEach([&] (const DataFilterRecord& filter) {
if (!filter.doesMatch(data)) {
// NS_LOG_UNCOND(" ZY. processIncomingInterest NOT Match entry:"
// //<< *entry.getInterest()
// );
return;
}
NDN_LOG_DEBUG(" matches " << filter.getFilter());
//entry.recordForwarding();
filter.invokeDataCallback(data);
//NS_LOG_DEBUG(" ZY. processIncomingData Match entry is OK intrest: "
//<<" getIntrest: " << entry.getInterest()->getName()
//<<" getOrigin:" << entry.getOrigin()
//<<" interest: " << interest.toUri()
//<< " entry: " << entry.getInterest() << " " << entry.getId() << " Nonce:" << interest.getNonce()
//);
});
}
后面还需要添加express_data函数,代表推送者推送数据,以及setdatafilter函数
首先添加express_push_data函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40//新添加直接发送推送包的函数供应用层调用,在face.cpp中
void
Face::expressPushData(const Data& data)
{
NS_LOG_LOGIC(" ------------ LZH. Face::expressPushData -------------------------- step 1" );
auto data2 = make_shared<Data>(data);
data2->getNonce();
data2->setIfpush(true);
IO_CAPTURE_WEAK_IMPL(post) {
impl->asyncExpressPushData(data2);
} IO_CAPTURE_WEAK_IMPL_END
return;
}
//修改face-impl.hpp
//2022.12.21新添加
void
asyncExpressPushData(shared_ptr<const Data> data)
{
NDN_LOG_DEBUG("<D " << *data);
this->ensureConnected(true);
const Data& data2 = *data;
lp::Packet lpPacket;
addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, data2);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data2);
m_face.m_transport->send(finishEncoding(std::move(lpPacket), data2.wireEncode(),
'D', data2.getName()));
dispatchPushData(data2); //这里不确定对不对
NS_LOG_DEBUG(" ------------ ZY. Face::Impl::asyncExpressData :"
//<< entry.getInterest()->toUri()
);
}
//2022.12.27新添数据前缀注册功能1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47//12.27新添加对数据前缀进行注册,用于推送,在face.cpp中
DataFilterHandle
Face::setDataFilter(const DataFilter& filter, const PushDataCallback& onPushData)
{
auto id = m_impl->m_dataFilterTable.allocateId();
IO_CAPTURE_WEAK_IMPL(post) {
impl->asyncSetDataFilter(id, filter, onPushData);
} IO_CAPTURE_WEAK_IMPL_END
return DataFilterHandle(*this, reinterpret_cast<const DataFilterId*>(id));
}
//2022.12.27新添,作为回调使用的函数,取消注册前缀
void
Face::clearPushDataFilter(const DataFilterId* dataFilterId)
{
IO_CAPTURE_WEAK_IMPL(post) {
impl->asyncUnsetPushDataFilter(reinterpret_cast<RecordId>(dataFilterId));
} IO_CAPTURE_WEAK_IMPL_END
}
//2022.12.27新添,datafilterhandle实际上就三取消注册前缀
DataFilterHandle::DataFilterHandle(Face& face, const DataFilterId* id)
: CancelHandle([&face, id] { face.clearPushDataFilter(id); })
{
}
//face-impl中也需要对实现进行一定的修改
void
asyncSetDataFilter(RecordId id, const DataFilter& filter,
const PushDataCallback& onPushData)
{
NDN_LOG_INFO("setting InterestFilter: " << filter);
m_dataFilterTable.put(id, filter, onPushData);
}
//2022.12.27新添加
void
asyncUnsetPushDataFilter(RecordId id)
{
const DataFilterRecord* record = m_dataFilterTable.get(id);
if (record != nullptr) {
NDN_LOG_INFO("unsetting InterestFilter: " << record->getFilter());
m_dataFilterTable.erase(id);
}
}
//2022.12.28在ndn-cxx中新添pushConsumer和pushProducer文件,作为推送的应用层1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151//pushconsumer
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
// Enclosing code in ndn simplifies coding (can also use `using namespace ndn`)
namespace ndn {
// Additional nested namespaces should be used to prevent/limit name conflicts
namespace examples {
class pushConsumer
{
public:
void
run()
{
m_face.setDataFilter("/example/testApp",
bind(&pushConsumer::onPushData, this, _1, _2));
// processEvents will block until the requested data is received or a timeout occurs
m_face.processEvents();
}
private:
void
onPushData(const DataFilter&, const Data& data) const
{
std::cout << "Received Data " << data.getName() << std::endl;
}
private:
Face m_face;
};
} // namespace examples
} // namespace ndn
int
main(int argc, char** argv)
{
try {
ndn::examples::pushConsumer pushconsumer;
pushconsumer.run();
return 0;
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
}
//pushproducer
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
// Enclosing code in ndn simplifies coding (can also use `using namespace ndn`)
namespace ndn {
// Additional nested namespaces should be used to prevent/limit name conflicts
namespace examples {
class pushProducer
{
public:
void
run()
{
Name dataName("/example/testApp/randomData");
dataName.appendVersion();
Data data(dataName);
data.setIfpush(true);
data.getNonce();
std::cout << "Sending Data " << data << std::endl;
m_face.expressPushData(data);
m_face.processEvents();
}
private:
Face m_face;
KeyChain m_keyChain;
};
} // namespace examples
} // namespace ndn
int
main(int argc, char** argv)
{
try {
ndn::examples::pushProducer pushproducer;
pushproducer.run();
return 0;
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
}