In OMNET++ with INET framework, I want to find out how many packets are received from each sending node.I found the below code. Can anyone tell me what is function of "it->second++" command in below code?
std::map<L3Address, uint64_t> recPkt;
auto it = recPkt.find(senderAddr);
if (it == recPkt.end())
recPkt[senderAddr] = 1;
else
it->second++;
Also, can anyone suggest how to display the number of received packets per node.
it is an iterator to an element of std::map. Iterator is something like a pointer. it points to a pair: <L3Address, uint64_t>. Probably the address of sender is the first element of this pair, and the second one is the number of received packets.
The first element of this pair may be obtained using it->first while the second via it->second.
Operation recPkt.find(senderAddr) checks whether recPkt contains an entry with the address senderAddr:
if not, it points to recPkt.end(), then a new entry is created and 1 is set as value (because first packet has been just received),
if entry for senderAddr already exists, the second value of this element (counter) is incremented using it->second++
To show current value of received packets to internal log window one may use:
for (auto it : recPkt) {
EV << "From address " << it.first << " received " << it.second << " packets." << std::endl;
}
However, the better way is to write these values to statistics. The best place for it is a finish() method of your module:
void YourModule::finish() {
// ..
for (auto it : recPkt) {
std::string name = "Received packet from ";
name += it.first.str(); // address
recordScalar(name, it.second);
}
}
Reference: C++ Reference, std::map
EDIT
One more thing. The declaration of recPkt i.e. line:
std::map<L3Address, uint64_t> recPkt;
must be in your class. recPkt cannot be declared just before use.
Related
I am using the newly released INET 4.0 framework for OMNET++ and I would like to obtain the received signal strength value in a wireless host (of type AdhocHost). How may I do that?
In INET 4.0.0 the packet received by a module contains several tags. Between others there is SignalPowerInd tag. According to SignalTag.msg:
This indication specifies the average analog signal power that was detected during receiving the packet.
It may be present on a packet from the phyiscal layer to the application.
This tag is present in packet processing by a wireless MAC layer, for example:
And packet received by application layer contains SignalPowerInd too:
One can obtain the value of `SignalPowerInd` from received radio packet in any layer using standard API. For example, to obtain it in `UdpBasicApp` one should add in `UdpBasicApp.cc`:
#include "inet/physicallayer/common/packetlevel/SignalTag_m.h"
// ...
void UdpBasicApp::socketDataArrived(UdpSocket *socket, Packet *packet) {
if (packet->findTag<SignalPowerInd>() != nullptr) {
auto signalPowerInd = packet->getTag<SignalPowerInd>();
auto rxPower = signalPowerInd->getPower().get();
EV_INFO << "RX power= " << rxPower << "W" << endl;
}
// process incoming packet
processPacket(packet);
}
The program below is outputting unexpected use_count() value when shared pointer is printed using iterator de-reference of std::vector:
#include<iostream>
#include<memory>
#include<vector>
class A;
typedef std::shared_ptr<A> sharedPtr;
typedef std::vector<sharedPtr> sharedPtrVect;
typedef sharedPtrVect::const_iterator vectItr;
class A
{
public:
A(int inp): m_Val(inp) { /*std::cout << "*** A ctor called: " << m_Val << " ***" <<std::endl;*/ }
~A() { /*std::cout << "### A dtor called: " << m_Val << " ###" <<std::endl; */}
int getVal() const { return m_Val; }
private:
int m_Val;
};
int main()
{
sharedPtrVect myVect1, myVect2;
vectItr myVectItr;
std::shared_ptr<A> tmpPtr;
for(int i = 1 ; i <= 5 ; i++ ) {
std::cout << "Pushed back: " << i << std::endl;
tmpPtr = std::make_shared<A>(i);
myVect1.push_back(tmpPtr);
}
myVectItr = myVect1.begin();
for( ; myVectItr != myVect1.end() ; ++myVectItr) {
std::cout << "-----------------------------" << std::endl;
std::cout << "Element number: " << (*myVectItr).get()->getVal() << std::endl;
std::cout << "Element use count: " << (*myVectItr).use_count() << std::endl;
std::cout << "-----------------------------" << std::endl;
}
return 0;
}
The output of the above code is:
Pushed back: 1
Pushed back: 2
Pushed back: 3
Pushed back: 4
Pushed back: 5
-----------------------------
Element number: 1
Element use count: 1
-----------------------------
-----------------------------
Element number: 2
Element use count: 1
-----------------------------
-----------------------------
Element number: 3
Element use count: 1
-----------------------------
-----------------------------
Element number: 4
Element use count: 1
-----------------------------
-----------------------------
Element number: 5
Element use count: 2 //I am not sure why or how this is 2?
-----------------------------
I don't understand how the use_count() for the last vector element is 2. Shouldn't it be 1 like others? I am not creating any copies of the shared pointer stored in the last element of the vector.
What am I missing here?
EDIT: I have good experience in C++98, but less experience in C++11.
Shouldn't it be 1 like others? I am not creating any copies of the shared pointer stored in the last element of the vector. What am I missing here?
But you are creating a copy. You push_back() from tmpPtr. push_back() puts a copy of its argument into the vector, unless you tell it to move instead. (More on that later!)
Therefore, what happens for all but the last element is this:
tmpPtr holds the only reference to the shared resource
You push_back() a copy, so the copy-constructor of shared_ptr increments the use count to 2
You then assign the next element to tmpPtr, releasing the reference to, and thereby decrementing the use count of, the previous element's resource.
But, of course, there is no subsequent assignment on the last iteration of the loop. So, at the point of printing, tmpPtr is still in scope, and it retains a reference to the last resource that was allocated. Hence the 1-higher refcount on the last element. This seems perfectly expected to me. ;)
To see the results you expected, you need to either destroy tmpPtr after you copy it but before you print, or simply avoid the copy from it in the first place. The former could be done by moving its declaration into the for loop, as SirGuy pointed out in the comments.
However, clearly, the latter is superior. How do we do that? Well, C++11 lets us move instead. So, you could emplace_back( std::move(tmpPtr) ), in which the move will cast to an rvalue and thus invoke the move-constructor of the vector element. This will cause tmpPtr to release its reference upon being moved into the vector, effectively ensuring the use count is always 1. This leaves tmpPtr (like any moved-from object) in a valid-but-unspecified state, i.e. useful only to be reassigned-to.
(Note: push_back() will achieve the same thing, but I generally prefer using emplace_back() wherever possible, as it's more efficient in other situations, so it's a better default.)
Of course, you can then combine both of these: declare tmpPtr within the scope of the for loop, and move from it. However... you don't even need tmpPtr at all! It does not appear to serve any useful purpose. So, you could just not use it, and instead directly emplace_back() the result of make_shared(). Because the return value thereof will be an rvalue, it will implicitly be moved into the vector; no cast by std::move is needed.
vector<int> a = { 1,2,3,4,5,6,7 };
pair<vector<int>, vector<int>::iterator> pair_of_itr; //not working showing wrong directional error!
auto pair_of_itr = minmax_element(a.begin(), a.end());
cout << *pair_of_itr.first << " " << *pair_of_itr.second << endl; // working with auto but not with the PAIR of iterator.
//cout << pair_of_itr->first << " " << pair_of_itr->second << endl // not working
return 0;
here i have explained via comments. plz do refer comments.
a->b is the same as (*a).b. *a.b is the same as *(a.b). So they differ in whether a is dereferenced, or a.b is dereferenced.
In your case, auto pair_of_itr = std::minmax_element ... creates a std::pair of iterators, and it is the iterator you want to dereference. So that would be *pair_of_itr.first. *pair_of_itr is ill-formed because a std::pair is not itself a pointer or iterator.
The problem with pair<vector<int>, vector<int>::iterator> pair_of_itr; is simply that the first element of the pair is a std::vector, not a std::vector::iterator. So in that case neither pair_of_itr nor pair_of_itr.first can be dereferenced. *pair_of_itr.second would compile, because the second element is an iterator.
It's usually a good idea to add redundant parentheses, particularly if you needed to ask whether they were necessary. Other people also might not remember that *a.b means *(a.b), and the parentheses don't cost a lot.
My compound module is multiple layers as show in the attached figure.
Here Layer2 has a cPacketQueue buffer and I want the Layer1 module to directly insert packets into this cPacketQueue of Layer2. Layer1 and Layer2 gates are connected unidirecttionally as show in the figure.
Layer1Gate --> Layer2Gate
UPDATED:
Layer 1 creates Packets with different priorities (0-7) and injects to 8 different cPacketQueues in Layer2 named as priorityBuffers[i], (i is the index).
The Layer2 then sends self messages in intervals of 10ns to poll all these buffers in each iteration and send the packets.
This is all I am doing now. It works fine. But I know 10ns polling is definitely not an efficient way to do this and achieve QoS. So requesting for a better alternative.
I suggest adding a ControlInfo object with priority to every packet from Layer1, send the packet using send() command, then checking ControlInfo of received packet in Layer2, and insert the packet into a specific queue.
Firstly, one should define a class for ControlInfo, for example in common.h:
// common.h
class PriorityControlInfo : public cObject {
public:
int priority;
};
Then in C++ code of Layer1 simple module:
#include "common.h"
// ...
// in the method where packet is created
cPacket * packet = new cPacket();
PriorityControlInfo * info = new PriorityControlInfo();
info->priority = 2; // 2 is desired queue number
packet->setControlInfo(info);
send (packet, "out");
And finally in Layer2:
#include "common.h"
// ...
void Layer2::handleMessage(cMessage *msg) {
cPacket *packet = dynamic_cast<cPacket *>(msg);
if (packet) {
cObject * ci = packet->removeControlInfo();
if (ci) {
PriorityControlInfo * info = check_and_cast<PriorityControlInfo*>(ci);
int queue = info->priority;
EV << "Received packet to " << static_cast<int> (queue) << " queue.\n";
priorityBuffers[queue].insert(packet);
EV << priorityBuffers[queue].info() << endl;
}
}
}
According to using of self messages: I do not understand clearly what is your intention.
Does Layer2 should send a packet immediately after receiving it? If yes why do you use a buffer? In that situation instead of inserting a packet to a buffer, Layer2 should just send it to the Layer3.
Does Layer2 should do something else after receiving a packet and inserting it in a buffer? If yes, just call this action (function) in the above handleMessage().
In the both above variants there is no need to use self messages.
I have 2 cases:
Client connects, send no bytes and wait for server response.
Client connects, send more than 1 bytes and wait for server response.
Problem is next:
in 1st case I should read no bytes and get some server response.
in 2nd case I should read at least 1 byte and only then I'll get a server response.
If i try to read at least 0 bytes, like this:
async_read(sock, boost::asio::buffer(data),
boost::asio::transfer_at_least(0),
boost::bind(&server::read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
I will never get proper server reposonse in 2nd case.
But if I read at least 1 byte than this async_read operation will never ends.
So, how can I process this cases?
Update 1:
I'm still searching for solution without using time limit.
How do you expect this to work? Does the response vary between the first and second case? If it does vary, you cannot do this reliably because there is a race condition and you should fix the protocol. If it does not vary, the server should just send the response.
The solution to this problem is not an asio issue.
here is what I did
while (ec != boost::asio::error::eof) {
vector<char>socketBuffer(messageSize);
size_t buffersize = socket->read_some(
boost::asio::buffer(socketBuffer),ec);
if (buffersize > 0) {
cout << "received" << endl;
for (unsigned int i=0; i < buffersize; ++i) {
cout << socketBuffer.at(i);
}
cout << "" << endl;
}
socketBuffer.clear();
}
if(!ec){
cout<<"error "<<ec.message()<<endl;
}
socket->close();
That is a small snippet of my code I hope it helps you can read a set amount of data and append it to a vector of bytes if you like and process it later.
Hope this helps
I guess u need to use the data which the client send to make the proper server response in case 2, and maybe make a default response in case 1.
So there is no time limit about how long the client should send the data after connected the server? Maybe u should start a timer waiting for the special limited time after the server accepted the connection. If the server receive the data in time, it's case 2. If time is over, then it's case 1.