NS-3을 성공적으로 설치했으니, 이제 기본적인 NS-3에서의 코드 동작을 알아보도록 하겠다.
우선 지난시간에 성공적으로 컴파일한 examples/tutorial/first.cc파일을 확인해보자.
first.cc 한눈에 보기
~/ns-allinone-3.40/ns-3.40/ns-3-dev/examples/tutorial/first.cc
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-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(__FILE__);
cmd.Parse(argc, argv);
Time::SetResolution(Time::NS);
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
NodeContainer nodes;
nodes.Create(2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));
NetDeviceContainer devices;
devices = pointToPoint.Install(nodes);
InternetStackHelper stack;
stack.Install(nodes);
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign(devices);
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(nodes.Get(1));
serverApps.Start(Seconds(1.0));
serverApps.Stop(Seconds(10.0));
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));
Simulator::Run();
Simulator::Destroy();
return 0;
}
정체모를 객체들과 메서드들이 무수하게 사용되고있다.
이럴 땐 대개 코드의 내용을 해석하기전에, 코드 실행의 결과물부터 보면 이해가 편하다.

실행 결과를 보니, 프로세스 시작 - 클라이언트 전송 - 서버 수신 - 서버 전송 - 클라이언트 수신 - 프로세스 종료의 과정이 드러난다.
first, 즉 튜토리얼의 처음 코드이기때문에 전송 - 수신 - 전송 -수신의 꽤나 단순한 토폴로지를 구현한 듯하다.
코드 해석 준비 (주석 읽기)
// Default Network Topology
//
// 10.1.1.0
// n0 -------------- n1
// point-to-point
//
헤더보다 먼저 눈에 들어오는 이 주석 부분은, first.cc가 구현하고있는 토폴로지를 그림으로 나타낸 것이다.
앞으로는 계속 이 주석부터 읽고 코드의 동작을 유추할 것이다.
그림으로 알아낼 수 있는 사실은 다음과 같다.
1. 10.1.1.0 네트워크에서의 통신이다.
2. n0과 n1 두 노드 간의 통신이다.
3. p2p(point-to-point) 프로토콜을 사용한 통신이다.
위 내용을 염두하고, 지금부터는 이 내용들이 어떻게 코드로 표현되는지 살펴보면 되겠다.
코드 해체 분석 - 매크로 및 전역 scope
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
헤더 매크로 부분이다. 통신에 basic하게 필요해보이는 모듈들이 많다.
모듈을 벌써부터 전부 이해하려면 너무 어지러우니 눈에만 익혀두자.
그 와중에 point-to-point 모듈은 눈에 띈다.
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("FirstScriptExample");
ns3의 네임스페이스 안의 필드명을 사용하고
FirstScriptExample이라는 로그 컴포넌트를 생성? 초기화? 한 듯 하다.
코드 해체 분석 - main문
main문을 보자.
CommandLine cmd(__FILE__);
cmd.Parse(argc, argv);
Time::SetResolution(Time::NS);
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
cmd입력에 대한 내용을 argc, argv로 파싱한다. (exec을 위해)
시뮬레이션의 Time Resolution(시간 해상도) 단위를 나노밀리초로 설정하고,
로그에 UDP 호스트. 서버 응용이라고 기록한다.
따라서 구현하는 토폴로지는 UDP프로토콜일 예정이다.
NodeContainer nodes;
nodes.Create(2);
NodeContainer라는 객체를 불러와서, 노드를 2개 만들었다.
통신의 기본이되는 줄기세포? 쯤 된다고 생각하면 편하다.
이 노드에 무엇을 install하느냐에 따라 host, router, switch, csma.... 등등 다 될 수 있다.
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("Delay", StringValue("2ms"));
P2P 프로토콜 구현을 도와주는 PointToPointHelper 객체를 초기화하고,
P2P 링크의 dataRate와 지연시간을 설정해준다.
NetDeviceContainer devices;
devices = pointToPoint.Install(nodes);
그리고 (가상)네트워크 장치 객체를 생성하여, P2P 링크를 가지는 노드를 장치에 설치한다.
InternetStackHelper stack;
stack.Install(nodes);
노드가 기본적인 네트워크 프로토콜을 사용할 수 있도록, InternetStackHelper 객체를 노드에 설치해준다.
이 stack을 설치하지 않으면, 기본적으로 어떤 프로토콜도 지원되지 않는다.
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign(devices);
우리가 익히 아는 네트워크주소, IPv4주소를 설정한다. 10.1.1.0이므로, 서브넷마스크는 255.255.255.0이다.
이후 네트워크 장치에 주소를 할당한다.
*주의할 점 : IP주소는 사용할 프로토콜이 모두 install된 device에 할당되어야한다.
UdpEchoServerHelper echoServer(9);
처음에 로그에서 우리가 UDP EchoServer를 사용한다는것을 스포일러 당했기 때문에,
놀라지 않고 port 9번의 EchoServer객체를 생성한다(서버를 연다)는 것을 확인할 수 있다.
ApplicationContainer serverApps = echoServer.Install(nodes.Get(1));
serverApps.Start(Seconds(1.0));
serverApps.Stop(Seconds(10.0));
이제 ApplicationContainer객체를 echoServer로 초기화하여 애플리케이션을 만들게되는데,
이때 우리가 만들었던 노드 중 n1을 서버 애플리케이션으로 만든다.
이후 애플리케이션이 1초에 시작, 10초에 종료되도록 설정한다.
UdpEchoClientHelper echoClient(interfaces.GetAddress(1), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue(1));
echoClient.SetAttribute("Interval", TimeValue(Seconds(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));
클라이언트 객체는 설정할 것이 좀 더 많은데,
n1에 대한 ip주소와 포트번호 (9)를 이용하여 초기화하고,
서버에게 보낼 패킷에 대한 설정이 필요하다.
지금 설정해놓은 상태는 아래와 같다.
최대 전송 패킷 갯수 : 1
패킷 간 전송 간격 : 1초
패킷 사이즈 : 1024바이트
ApplicationContainer clientApps = echoClient.Install(nodes.Get(0));
clientApps.Start(Seconds(2.0));
clientApps.Stop(Seconds(10.0));
이후 클라이언트 앱을 n1노드에 설치하고,
클라이언트는 2초에 시작, 10초에 종료하도록 설정한다.
Simulator::Run();
Simulator::Destroy();
return 0;
모든 토폴로지 설정이 완료되었으므로, 시뮬레이터를 실행하고, Destory()한다.
정리하자면,
코드 구현은 TCP/IP 프로토콜의 Layer구조와 비슷하게 진행되는 것을 볼 수 있었다.
1. node를 생성
2. P2P링크 생성 및 설정 (Physical & Data Link Layer)
3. IPv4주소 생성 및 할당 (Network Layer)
4. Port번호 설정 (Transfort Layer)
5. Application 생성 및 실행 (Application Layer)
다시 확인하는 실행 결과

우리가 미리 봤던 실행결과를 이제 다시 한번 곱씹어보자.
1번 라인 : 서버는 1s에 이미 실행되었고, 클라이언트는 2초에 실행되어, 실행되자마자 1024바이트의 패킷을 서버에 전송했다.
2,3번 라인 : 서버는 Time Slice(프로세스 스케쥴링)가 돌아 온 후 패킷을 받고, echo reply를 보낸다.
4번 라인 : 클라이언트가 reply를 받고, 시뮬레이션이 종료된다.
각 함수의 인자값을 변경하며, 그 결과의 차이를 직접 확인해 볼 수 있다.
'개인공부' 카테고리의 다른 글
| [MQTT / Python / IoT] LCFS Queue 구현 (0) | 2025.12.26 |
|---|---|
| [MQTT / Python / IoT] Python으로 구현하는 MQTT (0) | 2025.12.01 |
| [NS-3] 2. second.cc 해체 분석 (0) | 2025.11.24 |
| [NS-3] α. NS-3 디버깅 기능 파헤치기 (0) | 2025.11.21 |
| [NS-3] 0. 시작하기 (0) | 2025.11.19 |