First.cc 예제 파일 설명

First example scenario

첫번째 시나리오는 2개의 컴퓨터를 point-to-point 채널로 바로 연결하는 간단한 시나리오입니다. 일반적인 네트워크는 두개의 node 사이에 라우터나 스위치, 방화벽등 다양한 네트워크 장비를 거쳐 통신을 하게 되는데 이번 시나리오는 그런 네트워크 장비 없이 바로 두개의 node가 통신하게 됩니다.

스크린샷 2018-12-26 오후 1.00.57

위 그림은 첫번째 시나리오의 네트워크를 그림으로 나타낸 것입니다. 2개의 노드가 point-to-point 링크를 이용하여 바로 연결되었다는 것을 볼 수 있습니다.

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
 */

/*
  시나리오를 돌리기 위해 필요한 해더 파일
  아래 헤더파일들은 전부 ns-3.29/src 폴더에 포함되어 있다.
*/
#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 ns3;

// 시뮬레이션 중 로그를 출력하기 위한 코드
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

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

  // 이 시나리오에서 호스트가 실행하는 에플리케이션은 각각 UdpEchoClientApplication 과 UdpEchoServerApplication이다.
  // 각각의 에플리케이션에 대해 어느 레벨로 로그를 출력할 것인지를 설정하는 코드이다.
  Time::SetResolution (Time::NS);
  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);

  // 2개의 노드를 만든다.
  NodeContainer nodes;
  nodes.Create (2);

  /*
   2개의 노드를 연결해줄 PointToPoint 링크를 만든다.
   이때 링크의 DataRate와 delay를 설정해줄 수 있다.
  */
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

  /*
   Netdevice는 NIC와 같은 역할을 한다.
  */
  NetDeviceContainer devices;
  devices = pointToPoint.Install (nodes);

  /*
  InternetStack 이란 TCP/IP 레이어와 같은 역할을 한다.
  */
  InternetStackHelper stack;
  stack.Install (nodes);

  /*
  전에 만든 point-to-point 링크를 노드에 연결하면 노드의 NIC가 반환된다.
  이렇게 반환된 NIC에 ip address를 설정해줄 수 있다.
  address.SetBase는 subnet id와 subnet mask를 주면 자동으로 NIC에 아이피를 할당해준다.
  */
  Ipv4AddressHelper address;
  address.SetBase ("10.1.1.0", "255.255.255.0");

  Ipv4InterfaceContainer interfaces = address.Assign (devices);

  /*
  노드에 설치할 서버 에플리케이션을 설정해준다.
  서버의 포트 번호는 9번을 사용한다.
  */
  UdpEchoServerHelper echoServer (9);

  ApplicationContainer serverApps = echoServer.Install (nodes.Get (1)); // 앞서 만든 2개의 노드중 2번째 노드에 설치한다.
  serverApps.Start (Seconds (1.0)); // 서버 에플리케이션은 1초에 시작하여
  serverApps.Stop (Seconds (10.0)); // 10초에 종료한다.

  /*
  노드에 설치할 클라이언트 에플리케이션을 설정해준다.
  이때 서버의 ip 주소와 포트 번호를 넘겨준다.
  */
  UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); // ip 주소를 NIC에 할당할 때 interface 객체가 생기고 이 객체는 할당된 아이피 주소의 정보를 가지고 있다. 이 객체를 이용하여 서버의 ip 주소를 얻을 수 있다.
  echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); // 서버에 보내는 패킷의 개수는 1로 한다.
  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0))); // 서버에 패킷을 보내는 간격은 1초로 한다.
  echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); // 서버로 보내지는 패킷의 크기는 1024 Byte로 한다.

  /*
  이렇게 만들어진 클라이언트 에플리케이션은 첫번째 노드에 설치한다.
  클라이언트 에플리케이션은 2초부터 시작하여 10초에 종료한다.
  */
  ApplicationContainer clientApps = echoClient.Install (nodes.Get (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

실행결과를 보시면 코드를 분석하며 파악한데로 2초에 클라이언트가 서버에 1024 byte 크기의 패킷을 전송했다는 것을 알 수 있습니다. 서버는 2.00369초에 1024 byte 크기의 패킷을 받았다는 것을 알수 있습니다. 서버는 패킷을 받고 난뒤 클라이언트에게 1024 byte 크기의 패킷을 전송하고 클라이언트는 2.00737초에 서버가 전송한 패킷을 수신한 것을 확인 할 수 있었습니다. 시나리오의 소스코드를 변경하면 다른 결과를 얻을 수 있습니다. 이번에는 클라이언트가 서버로 전송하는 패킷의 수를 1개가 아니라 7개로 늘려보도록 하겠습니다.

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

At time 3s client sent 1024 bytes to 10.1.1.2 port 9
At time 3.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 3.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 3.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 4s client sent 1024 bytes to 10.1.1.2 port 9
At time 4.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 4.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 4.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 5s client sent 1024 bytes to 10.1.1.2 port 9
At time 5.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 5.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 5.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 6s client sent 1024 bytes to 10.1.1.2 port 9
At time 6.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 6.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 6.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 7s client sent 1024 bytes to 10.1.1.2 port 9
At time 7.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 7.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 7.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 8s client sent 1024 bytes to 10.1.1.2 port 9
At time 8.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 8.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 8.00737s client received 1024 bytes from 10.1.1.2 port 9

전송되는 패킷의 수를 7로 늘렸더니 위의 과정이 7번 반복된 것을 확인할 수 있습니다. 또한 패킷 전송 간격을 1초로 설정했기 때문에 client가 sever로 패킷을 보낸다음 다시 패킷을 보낼 때까지 1초의 시간이 있는 것을 확인할 수 있습니다. 따라서 이번에는 패킷 전송 간격을 0.5초로 변경시켜보도록 하겠습니다.

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

At time 2.5s client sent 1024 bytes to 10.1.1.2 port 9
At time 2.50369s server received 1024 bytes from 10.1.1.1 port 49153
At time 2.50369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 2.50737s client received 1024 bytes from 10.1.1.2 port 9

At time 3s client sent 1024 bytes to 10.1.1.2 port 9
At time 3.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 3.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 3.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 3.5s client sent 1024 bytes to 10.1.1.2 port 9
At time 3.50369s server received 1024 bytes from 10.1.1.1 port 49153
At time 3.50369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 3.50737s client received 1024 bytes from 10.1.1.2 port 9

At time 4s client sent 1024 bytes to 10.1.1.2 port 9
At time 4.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 4.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 4.00737s client received 1024 bytes from 10.1.1.2 port 9

At time 4.5s client sent 1024 bytes to 10.1.1.2 port 9
At time 4.50369s server received 1024 bytes from 10.1.1.1 port 49153
At time 4.50369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 4.50737s client received 1024 bytes from 10.1.1.2 port 9

At time 5s client sent 1024 bytes to 10.1.1.2 port 9
At time 5.00369s server received 1024 bytes from 10.1.1.1 port 49153
At time 5.00369s server sent 1024 bytes to 10.1.1.1 port 49153
At time 5.00737s client received 1024 bytes from 10.1.1.2 port 9

패킷 전송 간격을 0.5초로 변경시키니 클라이언트가 서버에게 패킷을 전송하는 간격이 0.5초로 변경된 것을 볼 수 있습니다. 패킷 크기 역시 패킷 크기의 파라미터 값을 변경함으로써 쉽게 바꿀수 있습니다.

이번 포스트에서는 첫번째 예제 시나리오를 분석해 보았습니다. 소스코드에서 아직 자세히 설명하지 않은게 많은데 이는 다음 시나리오를 설명드리며 차차 설명해 드리도록 하겠습니다. 다음에는 두번째 시나리오 파일 설명을 갖고 오도록 하겠습니다.

카테고리:

업데이트:

댓글남기기