[2] NS-3 Conceptual Overview

최윤하·2023년 2월 3일
0

NS-3 Simulator

목록 보기
2/7
post-thumbnail

주요 용어

  • Node

    - 네트워크에 연결하는 computing device(≒ host, end system)
    - 현실에서 컴퓨터가 유용한 작업을 하도록 application, protocol stack 그리고 NIC와 driver를 설치하는 것과 비슷한 행동을 Node에게 합니다.
  • Application

    - 시뮬레이션 될 활동을 만드는 user program
    - 패킷을 발생시키는 역할
    - 컴퓨터에서 application이 돌아가는 것 처럼, ns-3 Node에서 작동하고 시뮬레이션을 일으킵니다.
  • Channel

    - 네트워크에서 데이터가 흐르는 전송매체
    (이더넷 케이블을 벽에 꽂으면 이더넷 채널에 연결되는 것과 동일)
  • Net Device

    - 현실에서 NIC는 software driver(=net device)와 함께 작동
    - ns-3에서 net device는 software driver와 hardware를 퉁쳐서 추상화 한 개념
    - Node에 설치되어서, Channel을 통해 다른 Node들과 통신을 가능하게 합니다.
    - 하나의 Node는 여러개의 NetDevice를 통해 여러개의 Channel에 연결될 수 있습니다.
  • Topology Helpers

    - 시뮬레이션을 위해서 NetDevice를 Node에 연결하고 NetDevice를 Channel에 연결, IP 주소를 할당하는 등등 많은 작업이 필요합니다. 이런 것들을 가능한 쉽게 도와주는 역할을 합니다.

지금까지 설명한 각각의 개념들은 C++ class로 구현되어 있습니다. 그리고 개발자들이 스스로 specialize 할 수 있습니다. 앞으로 살펴볼 튜토리얼에서는 이미 만들어진 class들을 사용합니다.

예를 들어,
Application은 UdpEchoClientApplication/UdpEchoServerApplication
Channel은 PointToPointChannel
NetDevice는 PointToPointNetDevice
Topology Helper는 PointToPointHelper
과 같이 이미 존재하는 클래스를 쉽게 사용할 수 있습니다.

Data Flow


ns-3의 시뮬레이션은 위 그림과 같은 데이터 흐름을 보입니다.
Node마다 Application(시뮬레이션 시나리오)이 있고 설치된 NetDevice와 Channel을 통해 패킷이 전달됩니다.

시나리오 분석(first.cc)

examples/tutorial 디렉토리에 튜토리얼을 위한 시나리오 파일들이 있습니다.


첫번째 first.cc는 두 node 사이에 point-to-point link를 만들고, 패킷 1개를 echo(주고받는)하는 시나리오입니다.

NS_LOG_COMPONENT_DEFINE("FirstScriptExample");

FirstScriptExample라는 이름의 logging component를 선언해줍니다.
이름을 통해 콘솔 로그 메시지를 활성화/비활성화 할 수 있습니다.

Time::SetResolution (Time::NS);

시간의 최소 단위를 설정해줍니다.
이것은 오직 한 번만 바꿀 수 있습니다.(메모리 문제 때문에)
기본적으로 nanosecond로 설정됩니다.

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); 
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);

두 개의 log component를 Echo Client와 Echo Server application에 각각 활성화 해줍니다.
두번째 인자는 로그 레벨입니다. 여기서는 'INFO'로 설정해주었는데, 자세한 것은 뒤에서 설명하겠습니다.
이렇게 설정해줌으로서, 시뮬레이션이 진행되는 동안 패킷을 보내거나 받으면 application이 로그 메시지를 출력하게 됩니다.

NodeContainer nodes;
nodes.Create (2);

다음으로 시뮬레이션에서 computer를 나타내는 ns-3 Node 객체를 만들어 줍니다.
NodeContainer는 topology helper입니다. 즉, Node를 만들고 관리하는데 편한 방법을 제공해주는 도우미입니다.
도우미(nodes)에게 2개의 Node를 만들라고(.Creat(2)) 시킵니다.
여기서 생성된 node들은 빈 깡통입니다.

이제 node들을 네트워크에 연결시켜야 합니다.
현실에서 NIC(NetDevice)와 network cable(Channel)은 한 쌍입니다.
ns-3에서도 동일합니다. 우리는 point-to-point link를 만들 것이므로 PointToPointNetDevice, PointToPointChannel 그리고 PointToPointHelper를 사용합니다.

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

먼저 point-to-point 도우미를 생성합니다.
그리고 도우미에게 '나중에' PointToPointNetDevice를 만들 때, DataRate을 5Mbps로 설정하라고 말합니다.
동일하게 '이후에' 만들 모든 point-to-point channel의 Delay는 2ms으로 설정하라고 말합니다.

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);

이제 NetDevice와 Channel을 만들 차례입니다.
pointToPoint 도우미에게, 인자로 전달된 node들에 아까 설정한 값(5Mbps, 2ms)으로 device와 channel을 만들라고 시킵니다.
그 결과 각 node에는 PointToPointNetDevice가 만들어집니다.(이것들은 devices에 저장됩니다.)
그리고 PointToPointChannel도 생성되어 두 PointToPointNetDevice를 연결합니다.

InternetStackHelper stack;
stack.Install (nodes);

다음으로 protocol stack을 설치해줍니다.
마찬가지로 InternetStackHelper(도우미)가 인자로 전달된 node들에 TCP, UDP, IP 등을 설치합니다.

Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");

Ipv4InterfaceContainer interfaces = address.Assign (devices);

이제 device들에게 IP 주소를 할당해줍니다.
일단 도우미에게 base IP("10.1.1.0")와 network mask("255.255.255.0")를 알려줍니다.
그러면 나중에 실제 할당을 할 때, 10.1.1.1, 10.1.1.2, ... 순서로 할당해줄 것입니다.

도우미에게 인자로 device들을 넘겨주며 주소를 할당하라고 시킵니다.
그 결과, 맨 처음 생성한 두 node들은 각각 10.1.1.1, 10.1.1.2를 할당 받습니다.
그리고 할당 된 IP들은 나중을 위해 Ipv4InterfaceContainer를 선언해 가지고 있습니다.

지금까지 네트워크 구성이 끝났습니다.
이제 패킷을 만들어 낼 application이 필요합니다.

ns-3에서 제공하는 Udp Echo Application을 사용하기 위해서, UdpEchoServerHelper를 사용하여 server-side를 먼저 구성해줍니다.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

echoServer로 선언한 도우미에게 포트 번호를 9로 설정합니다.(echoServer는 application이 아니라 만드는 걸 도와주는 helper임을 명심!!)

다음으로 echoServer에게 1번째 node(nodes.Get(1))에 server application을 설치하라고 시킵니다.(.Install())
그러면 application을 가진 node의 포인터가 반환되어 serverApps에 저장됩니다.

마지막으로, application에게 패킷 생성을 시작할 시간과 멈출 시간을 설정해줍니다.
그러면 echo server application은 시뮬레이션이 시작되고 1초 후에 Start하고, 10초 뒤에 Stop 할 것 입니다.

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

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

server-side와 비슷하게, client-side도 설정해줍니다. client는 몇가지 설정이 더 필요합니다.
echoClient(도우미)에게 server의 주소(interfaces.GetAddress(1))와 포트 번호(9)를 알려줍니다.
위에서 interfaces(할당된 IP 주소를 저장)를 선언한 이유가 여기 있습니다.
그리고 MaxPackets(최대 패킷 수), Interval(패킷 사이의 간격), PacketSize(패킷 payload 크기)를 알려줍니다.

그리고 실제 application 객체인 clientApps를 선언하고 Install하게 되면, 위의 설정대로 만들어진 application이 0번째 node에 설치됩니다.
그리고 시작, 종료시간도 설정해줍니다.

마지막으로 시뮬레이션을 실행시킵니다.

Simulator::Run();
Simulator::Destroy();

application을 만들 때 설정했던 Start, Stop 시간은 실제로는 시뮬레이터에 scheduled된(예약된) event입니다.
즉, Simulator::Run()이 call되면 시스템은 scheduled event 리스트를 훑어보고 그것들을 차례대로 실행합니다.
(1초에 server app이 실행되고, 2초에는 client가, ... 다른 event들 계속..)

시뮬레이션 실행

시뮬레이션을 할 때는 시나리오 파일(.cc)을 scratch 디렉토리로 옮긴 후에 실시해야 합니다.

$ cd ../..
$ cp examples/tutorial/first.cc scratch/myfirst.cc
$ ./ns3 build
$ ./ns3 run scratch/myfirst

결과

맨 처음에 그림으로 봤던 시나리오가 정확하게 수행되었음을 알 수 있습니다.

❗❗초보자의 수준에서 작성 된 글입니다❗❗
잘못 된 내용이 있으면 피드백 부탁드립니다.

0개의 댓글