I have modified UdpClient to send data periodically and receive a reply. But when I call udpClient from more than one node the
is just called for one node
Here is my Code for UdpClient (Send function, ReceivePacket function and StartApplication function)
void
UdpClient::StartApplication (void)
{
NS_LOG_FUNCTION (this);
if (m_socket == 0)
{
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
m_socket = Socket::CreateSocket (GetNode (), tid);
if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
{
if (m_socket->Bind (m_bindAddr) == -1)
{
NS_FATAL_ERROR ("Failed to bind socket");
}
m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom(m_peerAddress), m_peerPort));
}
else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
{
if (m_socket->Bind6 () == -1)
{
NS_FATAL_ERROR ("Failed to bind socket");
}
m_socket->Connect (Inet6SocketAddress (Ipv6Address::ConvertFrom(m_peerAddress), m_peerPort));
}
else if (InetSocketAddress::IsMatchingType (m_peerAddress) == true)
{
if (m_socket->Bind () == -1)
{
NS_FATAL_ERROR ("Failed to bind socket");
}
m_socket->Connect (m_peerAddress);
}
else if (Inet6SocketAddress::IsMatchingType (m_peerAddress) == true)
{
if (m_socket->Bind6 () == -1)
{
NS_FATAL_ERROR ("Failed to bind socket");
}
m_socket->Connect (m_peerAddress);
}
else
{
NS_ASSERT_MSG (false, "Incompatible address type: " << m_peerAddress);
}
}
m_socket->SetRecvCallback (MakeCallback (&UdpClient::ReceivePacket,this));
m_socket->SetAllowBroadcast (true);
m_sendEvent = Simulator::Schedule (Seconds (0.01), &UdpClient::Send, this);
}
void
UdpClient::ReceivePacket(Ptr<Socket> socket)
{
Ptr<Packet> pkt;
std::ofstream outfile;
outfile.open("result.txt", std::ios_base::app);
Address addr;
m_socket->GetSockName(addr);
InetSocketAddress iaddr1 = InetSocketAddress::ConvertFrom(addr);
outfile <<"UdpClient::ReceivePacket by user: "<<count<<" scoket IP Addr: "<<iaddr1.GetIpv4()<<"\n";
std::cout<<"UdpClient Received Packet socket IP addr "<<iaddr1.GetIpv4()<<"\n";
// NS_LOG_FUNCTION (this);
while((pkt = m_socket->Recv())) {
NS_LOG_FUNCTION (this);
}
outfile.close();
}
void
UdpClient::Send (void)
{
m_interval = Seconds(0.5);
NS_LOG_FUNCTION (this);
NS_ASSERT (m_sendEvent.IsExpired ());
SeqTsHeader seqTs;
seqTs.SetSeq (m_sent);
double min = 0.0;
double max = 20.0;
Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> (); //Genrating uniform random number for requestion videos uniformly.
x->SetAttribute ("Min", DoubleValue (min));
x->SetAttribute ("Max", DoubleValue (max));
int randomNumber = (int) x->GetInteger();
randomNumber = randomNumber % 20;
randomNumber++;
std::ofstream outfile;
outfile.open("result.txt", std::ios_base::app);
Ptr<Packet> p;
Address addr;
m_socket->GetSockName(addr); //socket->GetSocjName() for socket's IP address
InetSocketAddress iaddr1 = InetSocketAddress::ConvertFrom(addr);
std::string req = " A request packet for videoID ";
std::ostringstream str1;
str1 << randomNumber;
std::string randNum = str1.str();
std::string msg="";
msg.append(randNum);
msg.append(req);
msg.append(randNum);
std::cout<<"RequestID: "<<randNum<<" from SocketIPAddr "<<iaddr1.GetIpv4 ()<<"\n\n";
outfile << "UdpClient::Send --> Sending data to the RemoteHost with tagId" << randNum<<" from user with userId " <<count<<"and SocketIPAddr "<<iaddr1.GetIpv4 ()<<"\n\n";
p =Create<Packet>((uint8_t*) msg.c_str(), msg.length()+1);
// }
std::cout<<"UdpClient packet size "<< p->GetSize() <<"\n";
outfile.close();
// Ptr<Packet> p = Create<Packet> (m_size-(8+4)); // 8+4 : the size of the seqTs header
p->AddHeader (seqTs);
std::stringstream peerAddressStringStream;
if (Ipv4Address::IsMatchingType (m_peerAddress))
{
peerAddressStringStream << Ipv4Address::ConvertFrom (m_peerAddress);
}
else if (Ipv6Address::IsMatchingType (m_peerAddress))
{
peerAddressStringStream << Ipv6Address::ConvertFrom (m_peerAddress);
}
if ((m_socket->Send (p)) >= 0)
{
++m_sent;
NS_LOG_INFO ("TraceDelay TX " << m_size << " bytes to "
<< peerAddressStringStream.str () << " Uid: "
<< p->GetUid () << " Time: "
<< (Simulator::Now ()).GetSeconds ());
std::cout<<"TraceDelay TX " << m_size << " bytes to "
<< peerAddressStringStream.str () << " Uid: "
<< p->GetUid () << " Time: "
<< (Simulator::Now ()).GetSeconds ()<<"\n\n";
}
else
{
NS_LOG_INFO ("Error while sending " << m_size << " bytes to "
<< peerAddressStringStream.str ());
}
if (m_sent < m_count)
{
m_sendEvent = Simulator::Schedule (m_interval, &UdpClient::Send, this);
}
}
and here's the code where I install multiple UdpClient Application
double delay = 0.00;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
ApplicationContainer clientApps;
Address sinkAddress (InetSocketAddress (ueIpIface.GetAddress (u), sinkPort));
UdpClientHelper ulClient (remoteHostAddr, 49153);
ulClient.SetAttribute ("Interval", TimeValue (Seconds(1)));
ulClient.SetAttribute ("MaxPackets", UintegerValue (100));
ulClient.SetAttribute ("BindAddr", AddressValue (sinkAddress)); //Added this attribute in UdpClient for binding the socket with socket address
clientApps.Add (ulClient.Install (ueNodes.Get(0)));
clientApps.Start (Seconds (0.01 + delay));
delay += 0.01;
}
output of the result.txt
UdpClient::ReceivePacket by user: 1 scoket IP Addr: 7.0.0.2
I only see one UE ReceivePacket Called.
On the other hand, all the nodes are calling send function of UdpClient
Can anyone help me to understand why can't I see other nodes installed with the UdpClient Receiving any packet?
I have also attached the udp-client file as well for the reference.