/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/internet-module.h" #include "ns3/point-to-point-module.h" #include "ns3/applications-module.h" using namespace std; using namespace ns3; NS_LOG_COMPONENT_DEFINE ("FirstExercise"); int main (int argc, char *argv[]) { Time::SetResolution (Time::NS); LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO); int clientAmount; cout << "Amount of client: "; cin >> clientAmount; NodeContainer nodes; nodes.Create (clientAmount + 1); // Additional one for the server node. UdpEchoServerHelper echoServer (9); // Node 0 is reserved for the server. ApplicationContainer serverApps = echoServer.Install (nodes.Get (0)); serverApps.Start (Seconds (1.0)); serverApps.Stop (Seconds (10.0)); InternetStackHelper stack; stack.Install (nodes); PointToPointHelper pointToPoint; pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); pointToPoint.SetChannelAttribute ("Delay", StringValue ("4ms")); Ipv4AddressHelper address; address.SetBase ("10.1.1.0", "255.255.255.0"); for (int client = 1; client <= clientAmount; client++) { NetDeviceContainer devices; devices = pointToPoint.Install (nodes.Get (0), nodes.Get (client)); Ipv4InterfaceContainer interfaces; interfaces = address.Assign (devices); // Due to the implementation of PointToPointHelper, // each p2p link should be established on its unique subnet, // in order to make sure that each client can receive the packet // returning from the server. (If receiving is not required, // then we are done here.) // // Otherwise, only the last client registered to the network // will be able to receive the packet back. // // I think it's probably caused by the routing policy in ns-3, // under the situation that multiple interfaces (of the server node, // in this case) are assigned into the same subnet, that // may raise routing problem of which interface should be used, // to send echo packet back to the client. // // For a simple example, consider the situtation of 2 clients. // The network topology is as follows: // // Subnet: 10.1.1.0/30 // // p2p link 1 10.1.1.1 (link 1) 10.1.1.4 // n1 -------------- n0 -------------- n2 // 10.1.1.2 10.1.1.3 (link 2) p2p link 2 // // We assume that link 2 is established (assigned IP addresses) // after link 1. // // Now when the server (n0) tries to send echo packet back to n1 // (or n2), it's reasonable to use either the interface on link 1 // (10.1.1.1) or the one on link 2 (10.1.1.3), since all IPs are in // the same subnet (10.1.1.0/30). // // However, n1 will never receive the packet if n0 selects interface // on the link 2 (10.1.1.3). It's similar for n2 if 10.1.1.1 is used. // // It seems more likely, in ns-3, to use the last interface attached, // that is 10.1.1.3 on link 2 in this case. // // Therefore, address.NewNetwork() is called to create a new subnet // for the next p2p link. address.NewNetwork (); UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 9); echoClient.SetAttribute ("MaxPackets", UintegerValue (4)); echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); echoClient.SetAttribute ("PacketSize", UintegerValue (4096)); ApplicationContainer clientApps = echoClient.Install (nodes.Get (client)); clientApps.Start (Seconds (2.0)); clientApps.Stop (Seconds (10.0)); } Simulator::Run (); Simulator::Destroy (); return 0; }