Second.cc 예제 파일 설명

Second example scenario

두번째 시나리오는 many-to-one 네트워크입니다. 첫번째 예제 시나리오의 경우 2개의 host가 직접 연결되었다면 이번에는 여러개의 노드로 이루어진 네트워크가 있고 그중 1개의 노드가 다른 노드와 point-to-point 링크를 이용하여 연결되어있는 구조입니다. 이번에도 역시 그림으로 나타내보도록 하겠습니다.

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

한눈에 보기에도 이전 시나리오에 비해 네트워크가 복잡해졌음을 알수 있습니다. node #1 부터 node #4 까지가 point-to-point 링크를 통해 하나의 네트워크를 이루고 있고 node #0node #1 이 point-to-point 링크로 연결되어 있는 것을 볼 수 있습니다. 따라서 node #0node #2, node #3, node #4와 직접 연결되어 있지는 않지만 node #1을 통해서 통신이 가능하다는 것을 알 수 있습니다. 또한 이전 시나리오에서는 고려하지 않아도 되었던 문제도 고려해줘야 합니다. 바로 collision 문제인데요 이전 시나리오에서는 2개의 노드만 존재했기 때문에 collision이 발생하지 않았습니다. 그러나 이번 시나리오에서는 1개의 point-to-point 링크에 4개의 노드가 존재하기 때문에 만약 2개 이상의 노드가 동시에 데이터를 전송하려고 하면 collision이 발생할 수 있습니다. 따라서 이번에는 collision 까지 고려된 시나리오를 살펴보도록 하겠습니다.

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

  /*
  CommandLine 객체를 이용하여 커맨드라인에서 파라미터를 받아올 수 있다.
  아래 코드는 커맨드라인을 이용하여 1개의 네트워크 안에 몇개의 노드가 들어갈 것인지 입력한다. (기본값은 3)
  로그를 출력할지 말것인지도 커맨드라인을 통해 입력하다.
  */
  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);
    }

  // 네트워크안에 1개의 노드는 있어야 point-to-point 링크를 사용하여 다른 노드와 연결할 수 있으므로 nCsma의 값이 1개 이상이 되도록 해준다.
  nCsma = nCsma == 0 ? 1 : nCsma;

  // 우선적으로 2개의 노드를 만든다. 이 노드 그룹을 p2pGroup라고 부르도록 하겠다.
  NodeContainer p2pNodes;
  p2pNodes.Create (2);

  /*
  앞서 만든 2개의 노드중 2번째 노드를 포함하고 nCsma 만큼의 새로운 노드를 만든다. 이 노드 그룹을 csmaGroup라고 부르도록 하겠다.
  */
  NodeContainer csmaNodes;
  csmaNodes.Add (p2pNodes.Get (1));
  csmaNodes.Create (nCsma);

  /*
  p2pGroup에 포함된 2개의 노드는 point-to-point 링크로 연결된다.
  point-to-point 링크는 5Mbps의 DataRate, 2ms의 Delay를 가진다.
  */
  PointToPointHelper pointToPoint;
  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

  // point-to-point 링크를 이용하여 p2pGroup에 속한 노드를 연결한다.
  NetDeviceContainer p2pDevices;
  p2pDevices = pointToPoint.Install (p2pNodes);

  /*
   CsmaHelper는 point-to-point 링크처럼 노드를 연결하는 링크로 point-to-point와의 차이점은 CSMA를 지원한다는 점이다.
   CsmaHelper는 100Mbps DataRate, 6560 nano second의 Delay를 가진다.
   */
  CsmaHelper csma;
  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

  // csmaHelper 링크를 이용하여 csmaGroup에 속한 노드를 연결한다.
  NetDeviceContainer csmaDevices;
  csmaDevices = csma.Install (csmaNodes);

  // TCP/IP layer 역할을 하는 stack을 설치한다.
  InternetStackHelper stack;
  stack.Install (p2pNodes.Get (0));
  stack.Install (csmaNodes);

  // p2pGroup의 노드들은 10.1.1.0의 서브넷 아이디와 255.255.255.0 서브넷 마스크를 갖는다.
  Ipv4AddressHelper address;
  address.SetBase ("10.1.1.0", "255.255.255.0");
  Ipv4InterfaceContainer p2pInterfaces;
  p2pInterfaces = address.Assign (p2pDevices);

  // csmaGroup의 노드들은 10.1.2.0의 서브넷 아이디와 255.255.255.0 서브넷 마스크를 갖는다.
  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)); // csmaGroup중 가장 마지막 노드에 서버 어플리케이션을 설치한다.
  serverApps.Start (Seconds (1.0)); // 서버 어플리케이션은 1초에 시작되고
  serverApps.Stop (Seconds (10.0)); // 10초에 종료된다.

  // 시나리오에서 사용할 클라이언트 어플리케이션을 만든다.
  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));  // 클라이언트 어플리케이션은 최대 1개의 패킷을 서버로 전송한다
  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));  // 클라이언트 어플리케이션이 서버로 패킷을 전송하는 간격은 1초이다.
  echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); // 클라이언트 어플리케이션이 전송하는 패킷의 크기는 1024Byte 이다.

  ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));  // p2pGroup의 첫번째 노드에 클라이언트 어플리케이션을 설치한다.
  clientApps.Start (Seconds (2.0)); // 클라이언트 어플리케이션은 2초에 시작하여
  clientApps.Stop (Seconds (10.0)); // 10초에 종료된다.

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();  // p2pGroup과 csmaGroup에 공통으로 속한 노드가 패킷을 받은 경우 어느 노드로 패킷을 전달해야하는지 알려준다.

  // 시나리오가 진행되는 동한 이동하는 패킷의 정보를 pcap의 형태로 남겨준다.
  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

위 실행결과를 보면 이전 실행결과와 매우 비슷하다는 것을 알수 있습니다. 그 이유는 시나리오 자체가 이전 시나리오와 매우 유사하고 차이는 오직 csmaHelper를 이용해 여러 노드로 구성된 네트워크가 추가되었고 라우팅이 필요해짐에 따라 라우팅 코드를 작성하였습니다.

자세히 살펴보면 서버의 서브넷 아이디와 클라이언트의 서브넷 아이디가 다르다는 것을 알수 있습니다. 서버의 서브넷 아이디는 10.1.2.0인데 비해 클라이언트의 서브넷 아이디는 10.1.1.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

첫번째 시나리오에서는 서버와 클라이언트가 같은 네트워크에 있었기 때문에 서버와 클라이언트가 10.1.1.0이라는 같은 서브넷 아이디를 갖게 됩니다. 그러나 이번 시나리오에서는 서버와 클라이언트가 다른 네트워크에 있기 때문에 서로 다른 서브넷 아이디를 갖게 되는 것입니다. 또한 서버 어플리케이션을 csmaGroup의 가장 마지막 노드에 설치하였기 때문에 ip의 host id는 csmaGroup에 포함된 노드의 개수에 따라서 달라지게 됩니다. csmaGroup에 들어있는 노드의 개수는 기본적으로 4개 입니다. 따라서 가장 마지막인 4번째 노드에 서버 어플리케이션이 설치되기 때문에 host id가 4가 되는 것을 알 수 있습니다. 이번에는 커맨드라인을 이용하여 csmaGroup에 들어있는 노드의 개수를 변경해보고 그에 따른 host id의 변화를 살펴보도록 하겠습니다.

./waf --run "second --nCsma=8" 명령어를 이용하여 csmaGroup안에 포함된 노드의 개수를 9개로 변경해보았습니다. nCsma 값이 8인데 csmaGroup 안에 포함된 노드의 개수가 9개인 이유는 p2pGroup에 포함된 노드 1개가 추가로 들어오고 새로운 노드를 nCsma 값만큼 만들기 때문입니다. 이제 csmaGroup에 포함된 노드의 개수가 9개가 되었으므로 host id도 9가 될 것입니다.

At time 2s client sent 1024 bytes to 10.1.2.9 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.01861s client received 1024 bytes from 10.1.2.9 port 9

실행결과를 보면 시나리오를 돌리기 전 저희가 예상한 대로 host id가 9가 된 것을 확인할 수 있습니다. 이번 포스트에서는 여러개의 노드로 구성된 네트워크와 노드를 point-to-point 링크로 연결하는 시나리오를 살펴보았습니다. 현재 시나리오에 라우터, ISP 장비 등이 포함되면 실제 공유기를 쓰고 있는 가정집과 비슷한 네트워크가 구성됩니다. p2pGroup과 csmaGroup에 공통으로 포함된 노드를 NAT 역할을 하는 공유기라고 생각하고 csmaGroup의 나머지 노드들을 스마트폰, 노트북, 데스크탑이라고 생각하면 되기 때문이죠. 물론 시나리오 결과와 실제 네트워크는 크게 차이가 날것입니다. 현재 시나리오에서는 라우터나 ISP장비에 의한 영향이 전혀 고려되어 있지 않기 때문이죠. 하지만 지난번 포스팅에서 다룬 첫번째 시나리오에 비해서는 조금더 저희가 쓰는 네트워크에 비슷해졌다는 것을 알수 있습니다. 아마 다음 시나리오들을 계속해서 다루면 좀더 현실성있는 시뮬레이션을 할 수 있을 것이라고 생각합니다. 다음 포스팅에서는 WiFi를 이용한 네트워크와 point-to-point를 이용한 네트워크를 point-to-point로 연결하는 내용을 다뤄보도록 하겠습니다.

카테고리:

업데이트:

댓글남기기