네트워크 시뮬레이터 NS-2

강신각* 최선완** 오행석***

인터넷 프로토콜이 전 세계를 연결하는 글로벌 네트워킹 프로토콜로써 확고한 자리를 차지함에 따라 인터넷 프로토콜의 성능 개선 및 새로운 프로토콜 개발을 위한 노력이 활발하게 추진되고 있다. 본 고에서는 다양한 인터넷 프로토콜에 대한 시뮬레이션 기능을 제공하여 현재 전 세계적으로 널리 사용되고 있는 네트워크 시뮬레이터인 ns-2의 주요 기능과 네트워크 시뮬레이션에의 적용방법 등을 살펴본다. ▒

I. 서 언

콜롬비아 대학에 의해 개발된 시뮬레이션 테스트베드인 NEST[1]를 기반으로 UC Berkeley에서는 1988년 REAL이라는 네트워크 시뮬레이터를 개발하였다[2]. 그리고 1989년에 LBNL(Lawrence Berkeley National Laboratory)의 네트워크 연구그룹은 이 REAL을 기반으로 연구를 시작하여 ns-1(network simulator)라고 부르는 시뮬레이션 도구를 개발하였다[3]. LBNL에 의해 개발된 ns-1은 확장 tcl(Tool Command Language)을 시뮬레이션 기술 언어로 사용하며, 수행하고자 하는 시뮬레이션은 tcl 프로그램으로써 정의되게 된다. 이 tcl 대신에 MIT에 의해 개발된 otcl(Object tcl)을 사용하여 새로운 구조를 갖도록 ns-1을 개선한 것이 ns-2이다[3,4]. ns-2는 기존 ns-1과 완전한 역방향 호환성을 갖도록 설계되었다. ns는 TCP, 라우팅 프로토콜, 멀티캐스트 프로토콜, RTP(Real Time Protocol), SRM(Scalable Reliable Multicast) 등 다양한 인터넷 프로토콜에 대한 시뮬레이션을 수행하기에 적절한 여러 환경을 제공하고 있어 현재 널리 사용되고 있는 네트워크 시뮬레이션 도구이다.

ns-1은 SYN/FIN 패킷을 포함하지 않는 단방향 TCP(Tahoe, Reno, Vegas, SACK), SYN/FIN 패킷과 양방향 데이터 흐름을 지원하는 양방향 Reno TCP, CBQ(Class-based Queing), 동적 라우팅, 덴스-모드 멀티캐스트 라우팅, 흐름 관리자, Telnet 소스 등을 제공하고 있다. ns-2는 ns-1에서 제공되지 않던 많은 기능들이 추가 되었는데, ns-2에 추가된 기능들로는 멀티-패스 라우팅, RTP(Real Time Protocol), SRM, 집중형 멀티캐스트, 이동 호스트 지원, 스케쥴링 알고리즘으로 SFQ(Stochastic Fair Queing)와 FQ(Fair Queing), 그리고 DRR (Deficit Round Robin) 알고리즘이 추가되었다. ns-2는 현재 계속해서 기능 추가 및 성능 개선작업이 이루어지고 있으며[5], 누구나 무상으로 네트워크 상에서 다운로드 받아 사용이 가능하므로 현재 가장 널리 사용되고 있는 네트워크 시뮬레이션 도구이다.

본 고에서는 ns의 주요 기능과 시뮬레이터 실행 방법, 시뮬레이터 스크립트 언어인 tcl과 otcl, 이벤트 스케쥴러의 생성, 네트워크 시뮬레이션 요소, 에이전트와 노드의 접속 및 연결설정, 데이터 전송, 에러 모듈의 생성 및 삽입, 시뮬레이션 결과 추적 및 표시, 시뮬레이션 스크립트 작성 예 등에 대해 기술하였다.

II. 시뮬레이터 실행 방법

ns를 사용하여 시뮬레이션을 실행하는 방법에는 두 가지 방법이 있다. 첫번째 방법은 명령을 보내면 즉각적으로 그에 대한 응답을 보내 오는 대화(Interactive) 모드이고, 두 번째 방법은 일련의 명령어를 파일로 저장해서 ns를 실행하는 수동(Passive) 모드가 있다.

1. 대화 모드(Interactive Mode)

대화 모드는 쉘 프롬프트 상에서 ns 명령어로 시작한다. 각 명령 라인 당 즉각적으로 대응되는 값을 응답하게 되며 명령상의 에러 유무를 판단할 수 있지만 파일로 저장할 수는 없다. 다음 <예시 1>은 대화 모드의 한 실행 예 이다.

<예시 1> 대화 모드 실행 예

라인 1: [Shell Prompt] ns

라인 2: % set ns [new Simulator]

라인 3: _o4

라인 4: % $ns at 1 "puts Hello World!"

라인 5: 1

라인 6: % $ns at 1.5 "exit"

라인 7: 2

라인 8: % $ns run

라인 9: Hello World!

라인10: [Shell Prompt]

<예시 1>의 라인1은 ns를 실행시키는 것을 의미하며, 라인2는 ns가 지원하는 set 명령어를 사용해서 new Simulator를 ns로 대치했으며, 라인4는 puts 명령을 사용해서 ns 실행 1초 후에 Hello world! 스트링을 화면에 출력하라는 명령이며, 라인6은 ns 실행 1.5초 후에 종료하라는 명령이며, 라인8은 run명령어를 사용해서 ns를 실행하는 것이고, 라인 9는 ns 실행 결과로 화면에 문자 스트링이 출력되는 것을 보여 주고 있다. 라인3, 5, 7은 해당 명령에 대한 오브젝트 코드를 의미한다. ns명령어와 스크립트 언어인 tcl에 대한 보다 자세한 사항은 뒤에 다시 다룬다.

2. 수동 모드(Passive Mode)

수동 모드는 대화 모드와 아주 대조적인 방법으로써, 먼저 스크립트 파일을 만든 후 이를 이용하여 시뮬레이션을 수행하는 방법이다. 스크립트 파일을 만드는 방법은 해당 운영체계 환경에서 지원하는 각종 에디터를 사용해서 ns 명령어, tcl 명령어, 그 밖의 쉘 명령어를 이용한 스크립트 파일을 작성한 후 파일을 filename.tcl로 저장한다. 다음 단계로, 쉘 프롬프트에서 ns filename.tcl 명령어를 실행하면 스크립트 파일에 저장된 명령어 순서 대로 시뮬레이션이 실행되어 원하는 결과를 얻을 수 있다. 다음 <예시 2>는 수동 모드의 한 실행 예 이다.

<예시 2> 수동 모드 실행 예

라인 1: [Shell Prompt] vi hello.tcl

라인 2: set ns [new Simulator]

라인 3: $ns at 1 "puts Hello World!"

라인 4: $ns at 1.5 "exit"

라인 5: $ns run

라인 6: ns hello.tcl

라인 7: Hello World!

라인 8: [Shell Prompt]

<예시 2>의 라인 1에서 라인 5까지는 먼저 vi 에디터를 사용해서 hello.tcl 이라는 파일을 만드는 과정을 보이고 있다. 즉, set 명령어로 변수 ns를 new Simulator로 사용하고 puts 명령어로 Hello World! 문자 스트링을 화면에 출력하는 예를 보인다. 라인 6과 라인 7은 스크립트 파일의 실행 및 그 결과를 보여주고 있다. 만약에 코딩이 잘못되었을 경우 대화 모드에서는 한 줄의 명령어를 보내면 즉각적으로 에러 발생 유무를 알 수 있지만, 수동 모드에서는 마치 C언어를 컴파일 할 때와 같은 형태로 에러 메시지를 보여준다.

III. 시뮬레이터 스크립트 언어

1. tcl(Tool Command Language)

tcl은 버클리 대학에 의해 개발된 스크립트 언어로, 반복되는 비슷한 어플리케이션의 문제를 해결하기 위해 고안되었다. tcl은 어플리케이션의 확장과 제어를 편리하게 해주는 간단한 스크립트 언어로, 변수 및 제어구조와 같은 프로그래밍을 위한 도구가 되는 동시에 C 라이브러리 인터페이스를 통한 언어의 확장이 매우 편리하다는 장점이 있다.

tcl의 가장 대표적인 확장 어플리케이션은 tk로, tk는 X-Window의 툴킷으로써 C를 통한 복잡한 과정을 거치지 않고도 사용자 인터페이스 환경을 쉽게 구축할 수 있다는 장점을 가지고 있다. 다음은 tcl을 이용한 간단한 스크립트 파일의 작성 예를 보인다.

<예시 3> tcl 스크립트 예제

라인 1: proc test {} {

라인 2: set a 43

라인 3: set b 27

라인 4: set c [expr $a + $b]

라인 5: set d [expr [expr $a - $b] * $c]

라인 6: for {set k 0} {$k < 10} {incr k} {

라인 7: if {$k < 5} {

라인 8: puts "k < 5, pow= [expr pow($d, $k)]"

라인 9: } else {

라인10-: puts "k >= 5, mod= [expr $d % $k]"

라인11: }

라인12: }

라인13: }

라인14: test

<예시 3>은 test라는 이름의 프로시저를 만드는 예를 보여주고 있는데, 이 프로시저가 호출됐을 때 수행할 명령어들이 라인 2부터 라인 12까지 정의되어 있다. 라인 2, 3에서는 set 명령어를 사용하여 변수 a와 b에 각각 43과 27이라는 값을 넣었으며, 라인 4에서는 수학적인 계산을 의미하는 명령어 expr을 사용해서 변수 a와 b의 연산 값을 변수 c에 넣는 과정을 보이고 있고, 라인 5도 같은 방법으로 계산된 값을 변수 d에 넣는 과정을 보인다. 라인 6의 for문에서는 k를 초기값 0, 조건식 k 값이 10보다 작을 때 k의 값을 1씩 증가 시키며 조건에 맞는 if 문장 또는 else 문장을 수행하도록 하고 있다.

이 스크립트 파일을 test.tcl라는 이름의 파일로 저장하여 이를 실행시키면 k 값이 0에서부터 9까지 증가하는 경우에 대해 아래 <예시 4>와 같이 변수 pow의 값이 화면에 출력되게 된다.

<예시 4> test.tcl 스크립트 파일의 실행 결과

라인 1: k < 5, pow = 1.0

라인 2: k < 5, pow = 1120.0

라인 3: k < 5, pow = 1254400.0

라인 4: k < 5, pow = 1404928000.0

라인 5: k < 5, pow = 1573519360000.0

라인 6: k >= 5, mod = 0

라인 7: k >= 5, mod = 4

라인 8: k >= 5, mod = 0

라인 9: k >= 5, mod = 0

라인10: k >= 5, mod = 4

2. otcl (Object Tool Command Language)

otcl은 MIT에서 구현한 Object tcl을 말하는 것으로 Tcl/Tk(X-Window Toolkit)를 오브젝트 기반 프로그래밍을 위해 확장한 것이다. otcl 구조의 특징은 tcl과 같이 철저하게 동적으로 확장할 수 있도록 설계되었으며, 다른 언어를 포함하기 보다는 tcl 문법과 개념을 바탕으로 개발된 것으로써 강력한 오브젝트 프로그래밍 시스템에 비해 간결하고 이식이 가능한 구조를 갖고 있다. otcl과 C++은 몇 가지 차이점을 보이고 있는데 그 대표적인 차이점은 다음과 같다.

가. 클래스 정의

C++에서는 하나의 단일 클래스를 선언하는 반면 otcl에서는 여러 개의 클래스를 정의할 수 있으며, 각 메소드들은 instproc과 함께 선언되어 하나의 클래스에 메소드로서 추가되고 각 인스턴스 변수 정의는 set 또는 instvar을 통해서 메소드 내부에 정의됨으로써 한 오브젝트에 대한 인스턴스 변수를 추가한다.

나. 생성과 소멸

C++에서는 생성자(Constructor)를 사용하지만 otcl에서는 init instproc을 사용한다. C++에서의 소멸자(destructor) 대신 otcl에서는 destroy instproc을 사용한다. 생성자/소멸자와는 달리 otcl의 init과 destroy 메소드들은 기초 클래스들과 자동으로 결합되지 않는다. 따라서 명시적으로 next로 결합하여야 한다.

다. 메소드의 호출

C++과 달리 otcl 메소드들은 항상 오브젝트를 통해 호출된다. self라는 이름은 C++에서 this와 동일하며 메소드 몸체 내부에서 사용된다. C++과 다른 것 중 하나는 otcl 메소드들은 모두가 순수 가상함수라는 것이다.

라. 메소드를 찾기 위한 next

C++에서와 같이 메소드 이름을 통해 숨겨진 메소드들을 호출하는 대신에 otcl은 next와 함께 사용하며 next는 자동으로 숨겨진 메소드를 찾기 위해 상속 그래프를 거슬러 올라가며 검색한다. 이는 이름에 의존하지 않고 메소드들이 결합할 수 있다는 것을 의미한다.

마. 변수 접근/공유를 위한 $class

Static 메소드와 변수 사용을 피하기 위해 이전부터 사용하던 static 문법과 otcl에서 사용하는 문법은 정확히 같지는 않다. 클래스 오브젝트 상의 변수에 대한 접근 및 공유는 $class를 사용하며 메소드를 통해서만 가능하다. 이러한 동작은 상속되며 메타클래스를 포함하는 프로그램과 클래스들에서 상속된 메소드들을 위한 것이다. 만일 상속성이 필요하지 않다면 proc 메소드를 클래스 오브젝트에서 사용한다.

IV. 이벤트 스케쥴러의 생성

ns를 이용한 네트워크 시뮬레이션을 하기 위해서는 우선 시뮬레이터 클래스로부터 인스턴스를 얻어야 하며 클래스들 내의 객체 인스턴스는 new에 의해서 생성되고 delete에 의해서 제거된다. ns를 이용한 시뮬레이션은 스케쥴러 생성, 이벤트의 스케쥴링, 스케쥴러 실행 과정을 거쳐 tcl 스크립트 파일로 저장한 후에 ns filename.tcl 명령을 사용해서 시뮬레이션이 실행된다.

1. 스케쥴러 생성

ns 시뮬레이션을 위해서 시뮬레이터 클래스로부터 객체의 인스턴스를 얻는 명령 형식은 set ns [new Simulator]를 사용한다. 먼저, new를 사용하여 시뮬레이터 클래스를 생성하고 set 명령을 사용하여 생성된 객체의 인스턴스를 ns로 설정하게 된다.

2. 이벤트 스케쥴링

스케쥴러 생성 과정에서 시뮬레이터 객체의 인스턴스를 얻었다면 이제는 그 인스턴스를 이용해서 여러 이벤트를 설정하고 테스트할 수 있다. 이벤트 스케줄링을 하는 기본적인 명령 형식은 $ns at <time> <event>를 사용한다. 이 명령에서 at <time>은 명령을 실행할 시간을 나타내며, <event>는 지정된 시점에 실행될 프로시저를 가리킨다. 프로시저는 ns와 tcl 명령어를 이용하여 구성되게 된다.

3. 스케쥴러 실행

스케쥴러 생성 과정에서 시뮬레이터의 인스턴스를 얻고 이벤트 스케쥴링 과정에서 수행할 명령을 얻었으면, 이제는 ns를 실행하기 위한 명령어 부분을 추가해서 시뮬레이션을 실행할 수 있다. 즉, $ns run 명령 형식을 사용하여 시뮬레이션을 실행하게 된다.

V. 네트워크 시뮬레이션 요소

네트워크 시뮬레이션을 수행하기 위한 가장 핵심적인 부분은 노드(node), 링크(link)와 큐(queue), 그리고 에이전트(agent)로 구성된다.

1. 노드(node)

노드는 자동적으로 각각의 노드에 대해서 유일한 주소를 할당하는 노드 시뮬레이터 메소드에 의해서 만들어진다. 노드를 생성하기 위해서는 앞에서도 언급한 바 있는 시뮬레이터 클래스로부터 인스턴스를 얻어야 한다. 다음은 set 명령을 이용하여 n0, n1, n2 세 개의 노드를 생성하는 것을 보여 주며, 이때 각 노드의 주소는 서로 다른 고유한 주소를 사용한다.

- set n0 [$ns node]

- set n1 [$ns node]

- set n2 [$ns node]

2. 링크(link)와 큐(queue)

가. 단방향 링크(Simplex Link)

단방향 링크는 한쪽 방향으로만 데이터를 보낼 수 있는 링크의 형태로 ns 명령과 옵션에 의해서 대역폭, 전송지연, 링크의 큐 형태가 결정된다. 노드 사이에 임의의 대역폭과 전송지연, 그리고 해당 링크의 큐 형태를 결정하는 ns 명령어는 다음과 같은 형태를 갖는다.

- $ns simplex-link node1 node2 bw delay queue_type

위 명령은 node1과 node2사이에 대역폭 bw, 전송지연 delay, 큐는 queue_type에 의해서 선택되는 큐(queue)의 형태를 갖는 단방향 링크를 생성하도록 한다. Queue_type에 의해 정의될 수 있는 큐 형태로는 Drop-Tail, RED, CBQ, WFQ, SFQ등이 있으며, 앞의 큐 형태에서 변화된 큐도 사용된다. 일반적으로 ns 시뮬레이터에는 각 옵션에 대한 디폴트 값이 정해져 있다. 대역폭의 디폴트 값은 1.5Mbits/sec로 정의되어 있고 시간지연의 디폴트 값은 100ms로 정해져 있지만, 이러한 옵션은 사용자가 원하는 값으로 변화시켜 사용할 수 있다. (그림 1)은 노드 n0와 노드 n1 사이에 대역폭이 8Mbps, 전송지연이 0.1ms, 그리고 drop-tail 큐 형태를 갖는 단방향 링크를 설정하는 예를 보여주고 있다.

나. 양방향 링크(Duplex Link)

한쪽 방향으로만 데이터를 보낼 수 있는 단방향 링크와는 달리 양쪽 방향으로 데이터를 전송할 수 있는 링크를 양방향 링크라고 정의한다. 링크 특성을 정의하기 위해 사용되는 옵션은 단방향 링크에서와 같다. 양방향 링크를 정의하기 위해 사용되는 명령어는 다음과 같다.

- $ns duplex-link node1 node2 bw delay queue_type

위 명령은 node1과 node2사이에 대역폭 bw, 전송지연 delay, 큐는 queue_type에 의해서 선택되는 큐 형태를 갖는 양방향 링크를 생성하도록 한다. 각 옵션에 대한 디폴트 값과 큐 형태는 단방향 링크의 경우와 동일하다. (그림 2)는 노드 r0와 노드 r1 사이에 대역폭이 800Kbps, 전송지연이 100ms, 그리고 drop-tail 큐 형태를 갖는 양방향 링크를 설정하는 예를 보여주고 있다.

3. 에이전트(Agent)

에이전트는 시뮬레이션에서 행동을 이끌어 낼 수 있는 객체를 말한다. 종단에 물려있는 단말이나 라우터로 간주되는 노드에서 이동할 수 있는 실체이며, 그 실체에 특성을 어떻게 부여하는가에 따라 에이전트의 행동이 달라진다. ns-2 시뮬레이터에서는 기본적인 에이전트 타입을 제공하고 있다. 에이전트는 new Agent/type 명령 형식을 사용하여 생성된다. 에이전트의 기능은 type의 정의에 따라 변화된다. <표 1>은 현재 ns-2에 정의되어 있는 Agent type의 종류를 나타낸다.

VI. 에이전트와 노드의 접속 및 연결 설정

노드 메소드에 의해서 생성된 노드는 단지 노드 자체일 뿐 어떤 역할도 할 수 없다. 따라서 노드에 적당한 에이전트를 붙여주어야 노드에서 사용자들이 원하는 기능을 수행할 수 있다. 이 장에서는 앞에서 설명한 방법으로 노드를 생성했다면 이제는 어떻게 노드에서 UDP나 TCP 패킷, 그리고 이들 패킷에 대한 응답 패킷을 송수신하는지 방법을 설명한다.

1. UDP(User Datagram Protocol)

UDP는 한 응용 프로그램에서 다른 응용 프로그램으로 데이터그램을 전송하는 기본적인 메카니즘을 제공한다. 또한, UDP는 한 호스트 안에서 돌아가는 응용 프로그램들을 구분하는데 쓰이는 프로토콜 포트를 제공한다. 이는 한 호스트 안의 응용 프로그램이 다른 호스트 안의 특정 응용 프로그램에 데이터를 전송할 수 있도록 해 준다. UDP는 신뢰성이 보장되지 않는 비연결형 데이터그램 전송 서비스를 제공한다. 따라서, UDP 메시지는 손실될 수 있고, 중복될 수도 있으며, 순서가 뒤바뀌어 도착할 수도 있다. 그리고 패킷들이 수신자가 처리할 수 있는 양보다 더 빨리 도착할 수도 있다.

UDP 에이전트는 Agent/UDP와 Agent/NULL을 쌍으로 설정해야만 한다. 일반적으로 UDP 패킷을 생성하는 곳을 근원지라 하며 NULL 패킷을 생성하는 곳을 목적지라 한다. <예시 5>의 라인1은 UDP 패킷을 생성할 수 있는 객체를 생성하는 방법으로, 키워드 new를 사용해서 UDP 에이전트를 생성하고 set 명령어를 이용해서 새로 생성된 객체를 변수 udp로 지정한다. 라인2에서는 UDP 패킷을 받아들일 수 있는 객체를 생성하는 방법을 보이고 있다. 마찬가지로 에이전트의 새로운 객체를 생성하기 위해 new 명령을 사용해서 NULL 에이전트를 생성한 후에 set 명령어로 생성된 객체를 변수 null로 지정한다.

이와 같이 UDP와 NULL 에이전트를 생성했다면 이제는 원하는 근원지 노드와 목적지 노드에 이들 에이전트를 접속 시켜야 한다. 노드와 에이전트를 접속 시키고자 할 때는 $ns attach-agent node agent 명령어 형식을 사용한다. 이 명령 형식은 이미 정의된 agent 변수를 node 변수에 접속시키는 것을 의미한다. <예시 5>의 라인3은 이미 생성된 노드 n0와 UDP 에이전트를, 그리고 라인 4는 노드 n1과 NULL 에이전트를 접속시키는 것을 보여 주고 있다.

각 에이전트를 노드에 접속시켰으면 다음 단계는 에이전트 간에 연결을 설정하는 절차가 필요하다. 근원지 에이전트와 목적지 에이전트 간을 연결 시키고자 할 때는 $ns connect src dst 명령어 형식을 사용한다. 이 명령 형식은 이미 노드에 접속된 에이전트 들을 상호 연결시켜 에이전트 간 데이터 전송이 가능하게 한다. <예시 5>의 라인 5는 근원지 에이전트인 UDP 에이전트와 목적지 에이전트인 NULL 에이전트 간에 연결을 설정하는 것을 보여주고 있다.

<예시 5> UDP Agent의 생성, 접속 및 연결설정

라인 1: set udp [new Agent/UDP]

라인 2: set null [new Agent/NULL]

라인 3: $ns attach-agent $n0 $udp

라인 4: $ns attach-agent $n1 $null

라인 5: $ns connect $udp $null

2. TCP(Transmission Control Protocol)

TCP는 인터넷 호스트 간에 신뢰성이 보장되는 데이터 전송서비스를 제공하는 종단간 전송 프로토콜이다. ns-2에서 TCP 전송 시뮬레이션을 하기 위해서는 Agent/TCP와 Agent/ TCPSink를 쌍으로 설정해야 한다. 일반적으로 TCP 패킷을 생성하는 에이전트를 근원지라 하며 TCP 패킷을 수신하는 에이전트를 목적지라 한다. 목적지 TCP 에이전트로 사용되는 TCPSink 에이전트는 근원지 TCP 에이전트에서 전송되는 TCP 패킷에 대한 확인 응답인 ACK 패킷을 생성해 보내는 기능을 제공한다. TCP 에이전트를 생성하는 방법과, 생성된 에이전트를 노드에 접속시키는 방법, 그리고 에이전트 간에 연결을 설정하는 방법은 앞서 설명한 UDP의 경우와 동일하다.

TCP 에이전트는 TCP에 대한 Agent/Type에 따라 Tahoe TCP, Reno TCP, Vegas TCP등을 지정하여 사용할 수 있으며, type을 TCP로 지정하면 일반적으로 사용되고 있는 Tahoe TCP가 선택된다. <예시 6>은 TCP 에이전트의 생성, 노드와 에이전트의 접속, 그리고 TCP 에이전트간에 연결을 설정하는 예를 보여주고 있다. 라인 1에서는 TCP 패킷을 생성할 근원지 에이전트로써Tahoe TCP 에이전트를 생성하여 변수 tcp로 지정하고, 라인 2에서는 TCP 패킷을 수신할 목적지 에이전트를 생성하여 변수 tcpsink로 지정하고 있다. 라인 3과 4에서는 이미 설정된 노드 n0에 근원지 TCP 에이전트를, 그리고 노드 n1에 목적지 TCP 에이전트를 접속시키는 것을 보여주고 있다. 그리고 라인 5에서는 근원지 TCP 에이전트와 목적지 TCP 에이전트간에 연결을 설정하는 것을 보여주고 있다.

<예시 6> TCP Agent의 생성, 접속 및 연결설정

라인 1: set tcp [new Agent/TCP]

라인 2: set tcpsink [new Agent/TCPSink]

라인 3: $ns attach-agent $n0 $tcp

라인 4: $ns attach-agent $n1 $tcpsink

라인 5: $ns connect $tcp $tcpsink

VII. 데이터 전송(Transport)

앞에서 노드와 UDP 및 TCP 에이전트를 생성하고, 각 에이전트를 노드에 접속시킨 다음, 근원지와 목적지 에이전트 간에 연결을 설정하는 과정을 설명하였다. 여기서는 인터넷 응용 프로토콜인 FTP와 Telnet 에이전트를 생성하여 이들을 UDP 및 TCP 에이전트와 접속시켜 응용 에이전트 간에 데이터 전송을 가능하게 하는 방법을 설명한다.

<예시 7>은 인터넷 파일전송 프로토콜인 FTP 응용을 이미 생성된 TCP 에이전트에 접속시켜 FTP 응용이 TCP 에이전트를 통해 연결이 설정된 다른 목적지 TCP 에이전트로 데이터 전송이 가능하게 하는 예를 보여주고 있다. <예시 8>은 인터넷 Telnet 응용을 이미 생성된 TCP 에이전트에 접속시켜 Telnet 응용이 TCP 에이전트를 통해 데이터 전송이 가능하게 하는 예를 보여주고 있다.

<예시 7> FTP 데이터 전송

라인 1: set ftp [new Application/FTP]

라인 2: $ftp attach-agent $tcp

<예시 8> Telnet 데이터 전송

라인 1: set telnet [new Application/Telnet]

라인 2: $telnet attach-agent $tcp

VIII. 에러 모듈의 생성 및 삽입

ns-2는 데이터 패킷을 전송할 때 임의적으로 에러를 생성할 수 있도록 하는 기능을 제공한다. 에러 모듈은 두 개의 otcl 메소드에 의해서 제공되며, 이 메소드들은 ns/tcl/lib/ns-lib.tcl에 정의 되어있다.

에러 모듈은 <예시 9>와 같이 생성될 수 있다. 라인 1에서는 에러에 대한 객체를 생성해서 이를 변수 loss_module로 지정한다. 라인 2, 3, 4는 생성된 에러에 대한 특성을 부여하는 방법을 기술한다. 즉, 라인2에서는 에러율을 0.01로 지정했는데 이는 1 퍼센트의 패킷 에러를 발생시킴을 의미한다. 라인3은 에러 단위를 패킷으로 나타내는데 이는 에러 단위를 표시하는 디폴트 값이다. 라인 4는 Uniform 분포 특성을 갖는 에러 생성을 지정하는 것을 보여주고 있다.

<예시 9> 에러 모듈의 생성

라인 1: set loss_module [new ErrorModel]

라인 2: $loss_module set rate 0.01

라인 3: $loss_module unit pkt

라인 4: $loss_module ranvar [new Random Variable/Uniform]

생성된 에러 모듈은 $ns lossmodel em src dst 명령 형식을 사용하여 원하는 노드 사이에 삽입시킬 수 있다. 즉, 근원지 노드 src와 목적지 노드 dst 사이에 전송되는 패킷에 대해 에러 모듈 생성 과정을 거쳐 생성된 에러모듈 em을 삽입하도록 한다. 아래 명령 형식은 에러 모듈의 삽입 예를 보여주고 있다. 이 명령은 위에서 생성된 에러 모듈인 loss_module을 노드 n0와 노드 n1 사이에 삽입하도록 하고 있다.

- $ns lossmodel $loss_module $n0 $n1

IX. 시뮬레이션 결과 추적 및 표시

1. 추적파일 생성

ns-2는 네트워크 시뮬레이션을 수행하는 동안에 노드간을 연결하고 있는 모든 링크들의 상태를 조사해서 링크상의 패킷 움직임을 시간에 대해 순차적으로 파일에 기록하는 기능을 제공한다. <예시 10>은 스크립트 언어를 이용하여 구성된 네트워크 시뮬레이션 모델의 실행 결과를 out.tr이라는 이름으로 추적 파일을 만들고, 이 파일에 모든 링크를 따라 이동하는 패킷의 흐름을 기록하게 하는 예를 보여주고 있다. <예시 10>의 라인1에서는 파일 이름을 지정하였고, 라인2에서는 ns 명령어인 trace-all을 사용하여 시뮬레이션을 실행하는 동안에 패킷이 한 노드에서 어떤 링크를 따라 다른 노드로 향하고있는지를 기록하도록 하고 있다.

<예시 10> 모든 링크상의 패킷흐름 추적

라인 1: set f [open out.tr w]

라인 2: $ns trace-all $f

일반적으로 추적 파일에는 네트워크 시뮬레이션의 시작부터 종료 시까지 시뮬레이션 중 일어나는 패킷의 움직임이 모두 기록되기 때문에 상당히 많은 양의 정보가 기록되게 된다. 아래 <표 2>는 한 예로써 out.tr 추적파일에 기록된 내용의 일부를 보여 주고 있다. 이 표에서 event에 표시되어 있는 +는 들어오는 패킷, -는 나가는 패킷을 의미하고, r은 패킷이 다른 노드에 도착했다는 의미로 사용되고 있다. 드롭된 패킷에 대해서는 이 표에는 표시되어 있지 않지만 드롭은 d로 표시되며 이는 잃어버린 패킷을 의미한다. time은 패킷의 이동시간을 표시하고 from/to 는 패킷의 이동 경로를 나타낸다. pkt는 현재 이동하는 패킷 종류가 TCP, UDP, CBR등인지를 표시하며, size는 한 패킷의 크기를 나타낸다. 라인 1은 노드 2에 목적지가 노드 3인 1000바이트 크기를 갖는 패킷이 도착했음을 나타내고 있다. 라인 2는 노드 2를 떠나 노드 3으로 향하는 패킷 상태에 대해 설명하고 있고, 라인 3은 노드 2를 떠난 패킷이 노드 3에 도달했음을 나타낸다. 라인 1과 라인 2는 노드 2 내부에서 수행되는 과정이므로 이 두 이벤트의 실행 시간이 차이가 없게 되었으나, 라인 2와 라인 3의 경우에는 패킷이 노드2에서 노드3으로 전달되는 경우 이므로 이 두 이벤트 사이의 실행 시간이 차이가 남을 알 수 있다.

2. 시뮬레이션 결과의 시각적 표현

시뮬레이터 수행 결과 생성되는 추적 파일을 분석해 보면 이벤트의 발생과 패킷 흐름 정보 등을 알 수 있지만 이러한 추적 파일 분석을 통해 시뮬레이션 결과를 이해하는 것은 상당히 불편한 일이다. 따라서 시뮬레이션 결과를 자동으로 분석하여 그 결과를 시각적으로 화면에 표현하는 도구가 개발되어 제공되고 있는데, ns-2와 함께 사용되는 대표적인 도구에는 nam(Network Animator)과 xgraph가 있다[5].

nam은 네트워크 시뮬레이션 도중 발생하는 사건들을 시간 축에 대해 기록해 놓은 파일 정보를 분석하여 그 결과를 화면 상에 에니메이션 형태로 표현하는 비쥬얼 시뮬레이션 도구이다. 즉, ns를 사용하여 시뮬레이션을 수행한 결과를 filename.nam 추적 파일에 기록하게 한 후, 이 추적 파일 내용을 오프라인 형태로 분석하여 그 결과를 에니메이션 방식으로 화면에 시각적으로 표현하는 기능을 제공한다. nam을 사용하면 네트워크를 구성하는 노드와 링크에서의 순차적 시간 변화에 따른 패킷 전송과 ACK등의 응답 패킷의 움직임을 시각적으로 볼 수 있게 된다. <예시 11>은 노드와 링크를 통과하는 모든 패킷에 대한 흐름 정보를 nam 분석도구를 이용하여 결과값을 표현하고자 할 때 네트워크 시뮬레이터를 설정하는 방법을 보여주고 있다.

<예시 11> nam 형식으로 모든 링크상의 패킷 흐름을 추적하도록 지정

라인 1: $ns f1 [open test.nam w]

라인 2: $ns namtrace-all $f1

(그림 3) nam을 이용한 시뮬레이션 결과 표현 예 

라인 1에서는 test.nam이라는 이름으로 시뮬레이션 결과 추적 파일을 생성하고, ns를 이용한 시뮬레이션 도중에 발생하는 모든 이벤트를 nam 도구를 이용하여 분석 가능하도록 추적 파일을 만드는 예를 보여 주고 있다. (그림 3)은 nam을 이용하여 시뮬레이션 결과를 화면 상에 에니메이션 형태로 표현한 예를 보여 주고 있다. 이 그림은 노드 2, 3, 5로부터 노드 0을 거쳐 노드 1으로 패킷 흐름이 발생하는 것과, 전송된 패킷에 대한 ACK 패킷이 노드 1으로부터 노드 0을 거쳐 노드 2, 3, 5로 전송되는 것을 에니메이션 형태로 보여 주고 있다.

ns를 이용한 시뮬레이션 결과를 자동으로 분석하여 그 결과를 시각적으로 화면에 표현하는 도구로써 널리 사용되고 있는 다른 도구로 Xgraph가 있다. Xgraph는 점이나 선, 막대그래프 등의 형태로 네트워크 시뮬레이션 결과를 표현하며, 원하는 위치의 부분확대 기능도 지원한다. Xgraph가 제공하는 옵션을 사용하면 다양한 점과 선의 모양으로 시뮬레이션 결과를 표시할 수 있으며, 시뮬레이션 과정에서 만들어진 추적 파일로부터 원하는 노드 사이의 패킷 흐름을 선택하여 그래프로 표현하는 것이 가능하다. (그림 4)는 Xgraph를 이용하여 시뮬레이션 결과를 그래프의 형태로 표현한 예를 보여주고 있다. 이 그림에서 X축은 시간, Y축은 전송되는 패킷의 수를 나타낸다. 그래프의 앞쪽 점은 근원지에서 목적지로 이동하는 패킷을 표시하고, 뒤쪽 점은 전송되는 패킷에 대한 응답으로 ACK 패킷의 흐름을 나타낸다.

X. 시뮬레이션 스크립트 작성 예

<예시 12>는 ns를 이용하여 네트워크 시뮬레이션을 수행하기 위해 작성한 스크립트 파일의 한 예이다. 이 예에서 사용된 시뮬레이션 시나리오는 먼저 노드간의 대역폭을 1.5Mbps, 시간지연을 10ms, 링크의 큐 형태를 drop-tail 방식으로 설정하고, ftp 응용을 이용하여 두 노드 간에 tcp 패킷을 전송하는 과정을 보이고 있다. 패킷 전송은 시뮬레이션이 실행되고 나서 0.2초 후부터 ftp 응용을 이용한 패킷 전송이 시작되고, 1.2초 후에 패킷 전송이 종료 되도록 설정한 tcl 스크립트 이다. 라인 1에서 라인 10까지는 에디터를 사용하여 파일로 작성되게 되고, 라인 11에서는 작성된 스크립트 파일을 실행시키는 명령이다.

<예시 12> 시뮬레이션을 위한 스크립트 작성 예

라인 1: set ns [new Simulator]

라인 2: set n0 [$ns node]

라인 3: set n1 [$ns node]

라인 4: $ns namtrace-all [open ex.nam w]

라인 5: $ns duplex-link $n0 $n1 1.5Mb 10ms DropTail

라인 6: set tcp [$ns create-connection TCP $n0 TCPSink $n1 0]

라인 7: set ftp [new Application/FTP]

라인 8: $ftp attach-agent $tcp

라인 9: $ns at 0.2 "$ftp start

라인10: $ns at 1.2 "exit

라인11: $ns run

라인 1에서는 시뮬레이터로부터 새로운 객체를 생성하였고, 라인 2, 3에서 노드 n0, n1을 생성하였으며, 라인 4에서는 시뮬레이션 분석도구인 nam을 이용하여 시뮬레이션 결과를 분석하기 위해 추적파일 ex.nam을 생성하였다. 라인 5에서는 노드 n0와 노드 n1 간에 링크 형태, 대역폭, 시간지연, 큐 형태를 지정하고 있다. 라인 6에서는 근원지 에이전트인 노드 n0의 TCP 에이전트와 목적지 에이전트인 노드 n1의 TCPSink 에이전트 사이에 연결을 설정하고는 set 명령어를 사용해서 이를 변수 tcp로 호출할 수 있도록 했다. 라인 7, 8에서는 ftp 응용 에이전트를 생성하여 이를 tcp 연결에 접속시키는 과정을 보여 주고 있다. 라인 9에서는 시뮬레이션이 시작된 0.2초 후에 ftp 응용을 이용한 파일 전송을 시작했고, 라인 10에서는 시뮬레이션이 수행되고 나서 1.2초 후에 시뮬레이션의 실행을 종료하도록 스크립트를 작성하였다.

(그림 4) Xgraph를 이용한 시뮬레이션 결과 표현 예

XI. 맺음말

본 고에서는 ns-2의 주요 기능과 네트워크 시뮬레이션에의 적용 및 활용 방법에 대해 기술하였다. 특별히 ns-2는 인터넷 기반의 다양한 네트워크 프로토콜에 대한 시뮬레이션 환경을 제공하고 있으며, 누구나 사용할 수 있도록 공개되어 있고, 사용자 그룹을 조직하여 현재 계속적인 기능 추가 및 성능개선 작업이 이루어지고 있어 광범위하게 사용되고 있는 네트워크 시뮬레이션 도구이다.

ns-2 개선 작업은 현재 VINT(Virtual InterNetwork Testbed)라는 프로젝트를 통하여 계속적인 연구개발 작업이 추진되고 있다[6]. VINT는 기존 네트워크 프로토콜 및 미래의 네트워크 프로토콜에 대한 연구개발을 도울 수 있는 새로운 네트워크 시뮬레이터를 개발하는 것을 목표로 하고 있으며, 이 프로젝트에는 USC/ISI, Xerox PARC, LBNL, UC Berkeley가 참여하고 있다. VINT 프로젝트의 수행 결과로 최근 기존 nam의 성능을 개선한 newnam이 개발되었으나 newnam은 현재 VINT 프로젝트 참가자에게만 공개되고 있고 아직 일반에게는 공개되지 않고 있다. 그러나 조만간 newnam도 일반에게 공개될 것으로 예상되며, VINT 프로젝트와 ns-2 사용자 그룹 활동 등을 통해 ns-2는 향후 가장 기능이 풍부한 인터넷 프로토콜 시뮬레이션 도구로 자리잡을 것으로 예상된다.

<참 고 문 헌>

  1. NEST, ftp://ftp.cs.columbia.edu/nest/
  2. S. Keshav, REAL 5.0 Overview, http://www.cs.cornell.edu/skeshav/real/overview.html/
  3. LBNL, LBNL Network Simulator-ns version 1, http://www-nrg.ee.lbl.gov/ns/
  4. UCB/LBNL/VINT Network Simulator - ns (version 2), http://www-Mash.CS.Berkeley.EDU/ns/
  5. NAM: Network Animator(NAM), http://www-mash.cs.berkeley.edu/nam/nam.html/
  6. Virtual InterNetwork Testbed(VINT), http://netweb.usc.edu/vint/