ns3 예제
2023.07.03

hello-simulator.cc

source code
  /* -*- 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 "ns3/core-module.h"

  using namespace ns3;

  NS_LOG_COMPONENT_DEFINE ("HelloSimulator");

  int
  main (int argc, char *argv[])
  {
    NS_LOG_UNCOND ("Hello Simulator");
  }
출력
Hello Simulator

first.cc

기본 예제들을 모아놓은 /expample/tutorial 폴더 안에 first.cc 파일이 있다.
first.cc 예제는 2개의 node를 point-to-point로 연결하는 시나리오이다.

source code
  /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  /*********************************
   * 머리말 생략
   * GNU General Public License
  *********************************/

  #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"

  // Default Network Topology
  //
  //       10.1.1.0
  // n0 -------------- n1
  //    point-to-point
  //

  using namespace ns3;

  NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");   // 로그 출력

  int
  main (int argc, char *argv[])
  {
    CommandLine cmd;
    cmd.Parse (argc, argv);

    /*********************************
     * Time resolution 설정
     * Echo Client와 Echo Server 애플리케이션에 내장된 두 개의 로깅 컴포넌트를 활성화
     * 디버그 로깅을 INFO 수준으로 활성화하여 시뮬레이션 중에 패킷이 전송되고 수신될 때 메시지를 출력
    *********************************/
    Time::SetResolution (Time::NS);   // Time resolution을 1ns로 설정 (default)
    LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
    LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

    NodeContainer nodes;
    nodes.Create (2);   // 노드 생성

    /*********************************
     * 채널 생성 및 토폴로지 구성
     * 구조: point-to-point
    *********************************/
    PointToPointHelper pointToPoint;
    pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
    pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

    /*********************************
     * 디바이스 생성, 구성 및 설치
     * NodeContainer에서 각 노드에 대해 디바이스를 생성, 디바이스를 컨테이너에 저장, 채널을 생성 및 디바이스를 연결
    *********************************/
    NetDeviceContainer devices;
    devices = pointToPoint.Install (nodes);   // node와 NetDevice 연결

    /*********************************
     * 각 노드에 인터넷 프로토콜 스택 (TCP, UDP, IP 등) 설치
    *********************************/
    InternetStackHelper stack;
    stack.Install (nodes);

    /*********************************
     * 디바이스에 IP주소(IPv4) 할당
     * base address와 네트워크 mask 설정
     * 기본저으로 할당된 주소는 1부터 시작하여 증가
     * 즉 첫번째 주소는 10.1.1.1, 다음은 10.1.1.2
    *********************************/
    Ipv4AddressHelper address;
    address.SetBase ("10.1.1.0", "255.255.255.0");

    Ipv4InterfaceContainer interfaces = address.Assign (devices);

    /*********************************
     * 생성한 노드 중 하나에 UDP echo server 애플리케이션 설정
    *********************************/
    UdpEchoServerHelper echoServer (9); // 포트 번호 9 설정

    ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); // index 1의 노드에 설치
    serverApps.Start (Seconds (1.0)); // 1초에 시작(활성화)
    serverApps.Stop (Seconds (10.0)); // 10초에 종료(비활성화)

    /*********************************
     * 노드에 설치할 클라이언트 에플리케이션을 설정해준다.
     * 이때 서버의 ip 주소와 포트 번호를 넘겨준다.
    *********************************/
    UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); // 1번 노드의 주소와 9번 포트에 에코 클라이언트 생성
    echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); // 최대 패킷 수를 1로 설정
    echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); // 패킷 전송 간격을 1초로 설정
    echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); // 패킷 크기를 1024바이트로 설정

    ApplicationContainer clientApps = echoClient.Install (nodes.Get (0)); // index 0의 노드에 설치
    clientApps.Start (Seconds (2.0));
    clientApps.Stop (Seconds (10.0));

    /*********************************
     * 시뮬레이션 실행 및 종료
    *********************************/
    Simulator::Run ();
    Simulator::Destroy ();
    return 0;
  }
출력
At time +2s client sent 1024 bytes to 10.1.1.2 port 9
At time +2.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time +2.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time +2.00737s client received 1024 bytes from 10.1.1.2 port 9

second.cc

second.cc는 여러개의 노드로 이루어진 네트워크 중 하나의 노드와 다른 노드가 p2p로 연결되어 있는 구조이다. ‘node #0’이 ‘node #2~4’에는 직접 연결되어 있지 않지만 ‘node #1’을 통해 통신이 가능하다. 이 때 발생할 수 있는 collision도 이번 시나리오에 포함되어있다.

source code
  /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  /*********************************
   * 머리말 생략
   * GNU General Public License
  *********************************/

  #include "ns3/core-module.h"
  #include "ns3/network-module.h"
  #include "ns3/csma-module.h"
  #include "ns3/internet-module.h"
  #include "ns3/point-to-point-module.h"
  #include "ns3/applications-module.h"
  #include "ns3/ipv4-global-routing-helper.h"

  // Default Network Topology
  //
  //       10.1.1.0
  // n0 -------------- n1   n2   n3   n4
  //    point-to-point  |    |    |    |
  //                    ================
  //                      LAN 10.1.2.0


  using namespace ns3;

  NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");

  int
  main (int argc, char *argv[])
  {
    bool verbose = true;
    uint32_t nCsma = 3; // LAN 내부 노드 개수

    /*********************************
     * CommandLine는 커맨더에서 파라미터를 변경할 수 있게 해준다.
     * 예를들어 `./waf --run "second -verbose=false"`로 실행하면, verbose 값을 false로 변경할 수 있고, UdpEcho 애플리케이션의 로그가 나타나지 않게 된다.
    *********************************/
    CommandLine cmd;
    cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
    cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);

    cmd.Parse (argc,argv);

    if (verbose)
      {
        LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
        LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
      }

    nCsma = nCsma == 0 ? 1 : nCsma; // nCsma가 1개 이상이 되도록 설정

    /*********************************
     * 총 2개의 NodeContainer를 생성한다(p2pNodes, csmaNodes).
     *
    *********************************/
    NodeContainer p2pNodes;
    p2pNodes.Create (2);

    NodeContainer csmaNodes;
    csmaNodes.Add (p2pNodes.Get (1));
    csmaNodes.Create (nCsma);

    /*********************************
    *********************************/
    PointToPointHelper pointToPoint;
    pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
    pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

    NetDeviceContainer p2pDevices;
    p2pDevices = pointToPoint.Install (p2pNodes);

    /*********************************
    *********************************/
    CsmaHelper csma;
    csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
    csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

    NetDeviceContainer csmaDevices;
    csmaDevices = csma.Install (csmaNodes);

    InternetStackHelper stack;
    stack.Install (p2pNodes.Get (0));
    stack.Install (csmaNodes);

    Ipv4AddressHelper address;
    address.SetBase ("10.1.1.0", "255.255.255.0");
    Ipv4InterfaceContainer p2pInterfaces;
    p2pInterfaces = address.Assign (p2pDevices);

    address.SetBase ("10.1.2.0", "255.255.255.0");
    Ipv4InterfaceContainer csmaInterfaces;
    csmaInterfaces = address.Assign (csmaDevices);

    UdpEchoServerHelper echoServer (9);

    ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
    serverApps.Start (Seconds (1.0));
    serverApps.Stop (Seconds (10.0));

    UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
    echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
    echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
    echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

    ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
    clientApps.Start (Seconds (2.0));
    clientApps.Stop (Seconds (10.0));

    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

    pointToPoint.EnablePcapAll ("second");
    csma.EnablePcap ("second", csmaDevices.Get (1), true);

    Simulator::Run ();
    Simulator::Destroy ();
    return 0;
  }

출력
At time +2s client sent 1024 bytes to 10.1.2.4 port 9
At time +2.0078s server received 1024 bytes from 10.1.1.1 port 49153
At time +2.0078s server sent 1024 bytes to 10.1.1.1 port 49153
At time +2.01761s client received 1024 bytes from 10.1.2.4 port 9

Reference

  1. ns-3.33 Documentation
  2. ‘numeric_limits’ is not a member of ‘std’, stackoverflow.
ns3 설치
ns3 Logging, CommandLine