이것은 Ubuntu Online, Fedora Online, Windows 온라인 에뮬레이터 또는 MAC OS 온라인 에뮬레이터와 같은 여러 무료 온라인 워크스테이션 중 하나를 사용하여 OnWorks 무료 호스팅 공급자에서 실행할 수 있는 ns-3-tutorial 명령입니다.
프로그램:
이름
ns-3-tutorial - ns-3 튜토리얼
이것은 NS-3 튜토리얼. ns-3 프로젝트에 대한 기본 문서는 XNUMX가지 형식으로 제공됩니다.
형태 :
· NS-3 독소: 시뮬레이터의 공개 API 문서
· 튜토리얼 (이 문서), 매뉴얼 및 모델 라이브러리 최근 공개 and
개발 나무
· NS-3 위키
이 문서는 reStructuredText for 스핑크스 그리고 에서 유지됩니다
문서/튜토리얼 ns-3의 소스 코드 디렉토리.
소개
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 시뮬레이터는 주로 연구를 목표로 하는 이산 이벤트 네트워크 시뮬레이터입니다.
및 교육용. 그만큼 NS-3 프로젝트는 2006년에 시작된 오픈 소스 프로젝트입니다.
개발 NS-3.
이 튜토리얼의 목적은 새로운 기능을 소개하는 것입니다. NS-3 구조화된 시스템에서 사용자
방법. 신규 사용자가 자세한 정보에서 필수 정보를 수집하는 것이 때때로 어려울 수 있습니다.
매뉴얼을 작성하고 이 정보를 작업 시뮬레이션으로 변환합니다. 이 튜토리얼에서 우리는
주요 개념을 소개하고 설명하는 몇 가지 예제 시뮬레이션을 구축하고
기능을 제공합니다.
튜토리얼이 진행됨에 따라 전체 내용을 소개합니다. NS-3 문서화 및 제공
작업에 대해 더 깊이 파고들고자 하는 사람들을 위한 소스 코드에 대한 포인터
시스템.
몇 가지 핵심 사항은 처음부터 주목할 가치가 있습니다.
· NS-3 오픈 소스이며 프로젝트는 오픈 환경을 유지하기 위해 노력합니다.
소프트웨어를 기여하고 공유할 수 있습니다.
· NS-3 이전 버전과 호환되는 확장이 아닙니다. NS-2; 그것은 새로운 시뮬레이터입니다. 둘
시뮬레이터는 둘 다 C++로 작성되었지만 NS-3 지원하지 않는 새로운 시뮬레이터입니다.
NS-2 아피스. 의 일부 모델 NS-2 에서 이미 포팅되었습니다. NS-2 에 NS-3. 그만큼
프로젝트는 계속 유지됩니다 NS-2 동안 NS-3 건설 중이며 연구 할 것입니다.
전환 및 통합 메커니즘.
소개 NS-3
NS-3 개방적이고 확장 가능한 네트워크 시뮬레이션 플랫폼을 제공하기 위해 개발되었습니다.
네트워킹 연구 및 교육. 간단히 말해서, NS-3 패킷 데이터의 모델을 제공합니다.
네트워크가 작동하고 수행하며 사용자가 수행할 수 있는 시뮬레이션 엔진을 제공합니다.
시뮬레이션 실험. 사용하는 몇 가지 이유 NS-3 수행하는 연구를 포함합니다.
시스템 동작을 연구하기 위해 실제 시스템에서 수행하는 것이 더 어렵거나 불가능합니다.
고도로 제어되고 재현 가능한 환경에서 네트워크 작동 방식에 대해 학습합니다.
사용자는 사용 가능한 모델이 NS-3 인터넷이 어떻게 작동하는지 모델링하는 데 중점을 둡니다.
프로토콜과 네트워크는 작동하지만 NS-3 인터넷 시스템에 국한되지 않습니다. 여러 사용자
사용하고 있습니다 NS-3 인터넷 기반이 아닌 시스템을 모델링합니다.
네트워크 시뮬레이션 연구를 위한 많은 시뮬레이션 도구가 있습니다. 아래는 몇 가지
의 구별되는 특징 NS-3 다른 도구와 달리.
· NS-3 함께 결합할 수 있고 다른 라이브러리와도 결합할 수 있는 라이브러리 세트로 설계되었습니다.
외부 소프트웨어 라이브러리. 일부 시뮬레이션 플랫폼은 사용자에게
모든 작업이 수행되는 단일 통합 그래픽 사용자 인터페이스 환경
ven, NS-3 이와 관련하여 더 모듈화되어 있습니다. 여러 외부 애니메이터 및 데이터 분석
및 시각화 도구를 함께 사용할 수 있습니다. NS-3. 그러나 사용자는
명령줄과 C++ 및/또는 Python 소프트웨어 개발 도구를 사용합니다.
· NS-3 FreeBSD, Cygwin에 대한 지원이 있지만 주로 Linux 시스템에서 사용됩니다.
(Windows의 경우) 기본 Windows Visual Studio 지원은 현재 진행 중입니다.
개발했다.
· NS-3 공식적으로 지원되는 회사의 소프트웨어 제품이 아닙니다. 을지 지하다 NS-3
ns-3-users 메일링 리스트에서 최선을 다해 수행됩니다.
럭셔리 NS-2 사용자
익숙한 사람들을 위해 NS-2 (이전의 인기 있는 도구 NS-3), 가장 눈에 띄는 외부
이사할 때 변경 NS-3 스크립트 언어의 선택입니다. 프로그램 NS-2 are
OTcl에서 스크립팅되고 시뮬레이션 결과는 Network Animator를 사용하여 시각화할 수 있습니다.
남. 에서 시뮬레이션을 실행할 수 없습니다. NS-2 순전히 C++에서(즉, main()
OTcl이 없는 프로그램). 게다가 일부 구성요소는 NS-2 C++로 작성되었으며
OTcl의 다른 사람들. ~ 안에 NS-3, 시뮬레이터는 선택적 Python과 함께 C++로 완전히 작성됩니다.
바인딩. 따라서 시뮬레이션 스크립트는 C++ 또는 Python으로 작성할 수 있습니다. 새로운 애니메이터
시각화 도구를 사용할 수 있으며 현재 개발 중입니다. 부터 NS-3 pcap 생성
패킷 추적 파일, 다른 유틸리티를 사용하여 추적도 분석할 수 있습니다. 이에
자습서에서는 먼저 C++에서 직접 스크립팅하고 결과를 해석하는 데 집중합니다.
추적 파일을 통해.
그러나 유사점도 있습니다(예를 들어 둘 다 C++ 개체를 기반으로 하며 일부
코드 NS-2 로 이미 포팅되었습니다 NS-3). 우리는 차이점을 강조하려고 노력할 것입니다
사이에 NS-2 and NS-3 이 자습서를 진행하면서.
우리가 자주 듣는 질문은 "계속 사용해야 합니까? NS-2 또는 이동 NS-3?" 이에
작성자의 의견, 사용자가 어떻게든 귀속되지 않는 한 NS-2 (기존 기준으로
개인적인 편안함과 지식 NS-2, 또는 특정 시뮬레이션 모델을 기반으로
에서만 사용할 수 있습니다. NS-2), 사용자는 다음을 통해 생산성을 높일 수 있습니다. NS-3 다음을 위해
원인:
· NS-3 활동적이고 반응이 빠른 사용자 메일링 리스트로 적극적으로 유지 관리되는 반면 NS-2 is
가볍게 유지 관리되며 기본 코드 트리에서 중요한 개발을 보지 못했습니다.
10 년 이상.
· NS-3 에서 사용할 수 없는 기능을 제공합니다. NS-2, 구현 코드 실행과 같은
환경(사용자가 시뮬레이터에서 실제 구현 코드를 실행할 수 있도록 함)
· NS-3 에 비해 낮은 기본 수준의 추상화를 제공합니다. NS-2, 정렬할 수 있도록
실제 시스템이 결합되는 방식이 더 좋습니다. 에서 발견된 몇 가지 제한 사항 NS-2 (예 :
노드에서 여러 유형의 인터페이스를 올바르게 지원)가 해결되었습니다. NS-3.
NS-2 보다 다양한 기여 모듈 세트를 보유하고 있습니다. NS-3, 그것의 긴 때문에
역사. 하지만, NS-3 여러 인기 있는 연구 분야에서 더 자세한 모델을 가지고 있습니다.
(고급 LTE 및 WiFi 모델 포함) 및 구현 코드 지원
매우 광범위한 고 충실도 모델을 인정합니다. 사용자가 알면 놀랄 수 있습니다.
전체 Linux 네트워킹 스택을 캡슐화할 수 있습니다. NS-3 노드, 직접 사용
코드 실행(DCE) 프레임워크. NS-2 때때로 모델을 포팅할 수 있습니다. NS-3, 특히
C++로 구현된 경우.
의심스러운 경우 좋은 지침은 두 시뮬레이터(및 기타
시뮬레이터), 특히 연구에 사용할 수 있는 모델이지만 명심하십시오.
적극적으로 개발 중인 도구를 사용하면 더 나은 경험을 할 수 있으며
유지 (NS-3).
기여
NS-3 연구 커뮤니티에 의한, 연구 커뮤니티를 위한 연구 및 교육 시뮬레이터입니다. 그것은
커뮤니티의 지속적인 기여에 의존하여 새 모델을 개발하거나 디버그하거나
기존 항목을 유지하고 결과를 공유합니다. 우리가 희망하는 몇 가지 정책이 있습니다.
사람들이 기여하도록 격려 NS-3 그들이 가지고 있는 것처럼 NS-2:
· GNU GPLv2 호환성을 기반으로 하는 오픈 소스 라이선스
· 위키
· 기여 암호 페이지, 유사 NS-2의 인기 기여 코드 페이지
· 열다 버그 트래커
이 문서를 읽고 있다면 프로젝트에 다시 기여하는 것이
아마도 이 시점에서 귀하의 가장 큰 관심사는 아닐 것입니다. 그러나 우리는 귀하가
기여하는 것은 프로젝트의 정신에 있으며 우리에게 메모를 남기는 행위조차도
귀하의 초기 경험에 대해 NS-3 (예: "이 튜토리얼 섹션은 명확하지 않았습니다..."),
부실한 문서 등에 대한 보고는 대단히 감사합니다.
튜토리얼 회사조직
자습서에서는 새 사용자가 처음에 다음과 같은 경로를 따를 수 있다고 가정합니다.
· 사본을 다운로드하고 빌드해 보십시오.
· 몇 가지 샘플 프로그램을 실행해 보십시오.
· 시뮬레이션 출력을 보고 조정해 보십시오.
결과적으로 우리는 위의 광범위한 순서에 따라 튜토리얼을 구성하려고 노력했습니다.
이벤트.
리소스
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 Web
몇 가지 중요한 리소스가 있습니다. NS-3 사용자가 숙지해야 합니다. 메인 웹
사이트 위치 http://www.nsnam.org 에 대한 기본 정보에 대한 액세스를 제공합니다.
NS-3 체계. 자세한 문서는 기본 웹 사이트에서 제공됩니다.
http://www.nsnam.org/documentation/. 시스템과 관련된 문서도 찾을 수 있습니다.
이 페이지의 아키텍처.
메인을 보완하는 위키가 있습니다. NS-3 당신이 찾을 웹 사이트
http://www.nsnam.org/wiki/. 거기에서 사용자 및 개발자 FAQ를 찾을 수 있을 뿐만 아니라
문제 해결 가이드, 타사 제공 코드, 문서 등
소스 코드는 다음에서 찾아 볼 수 있습니다. http://code.nsnam.org/. 거기 당신은 찾을 것입니다
이름이 지정된 저장소의 현재 개발 트리 ns-3-dev. 지난 릴리스 및
핵심 개발자의 실험적 저장소도 여기에서 찾을 수 있습니다.
수은제
복잡한 소프트웨어 시스템에는 조직과 변경 사항을 관리할 수 있는 방법이 필요합니다.
기본 코드 및 문서. 이 위업을 수행하는 방법에는 여러 가지가 있으며
현재 이를 수행하는 데 사용되는 일부 시스템에 대해 들었습니다. 동시
버전 시스템(CVS)이 가장 잘 알려져 있습니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 프로젝트는 Mercurial을 소스 코드 관리 시스템으로 사용합니다. 당신은하지 않지만
이 튜토리얼을 완료하려면 Mercurial에 대해 많이 알아야 합니다.
Mercurial에 익숙해지고 Mercurial을 사용하여 소스 코드에 액세스합니다. 머큐리얼은
웹 사이트 http://www.selenic.com/mercurial/, 바이너리 또는 소스를 얻을 수 있습니다.
이 소프트웨어 구성 관리(SCM) 시스템의 릴리스입니다. Selenic(개발자
of Mercurial)에서 튜토리얼도 제공합니다.
http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/및 QuickStart 가이드는
http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/.
또한 Mercurial 및 NS-3 메인에 NS-3 웹
사이트.
와프
로컬 시스템에 소스 코드를 다운로드했으면 컴파일해야 합니다.
사용 가능한 프로그램을 생성하는 소스. 소스코드 관리의 경우와 마찬가지로
이 기능을 수행하는 데 사용할 수 있는 많은 도구가 있습니다. 아마 이 중 가장 잘 알려진
도구는 확인. 가장 잘 알려져 있을 뿐만 아니라, 확인 아마도 가장 어려운
매우 크고 고도로 구성 가능한 시스템에서 사용합니다. 이 때문에 많은 대안
개발되었습니다. 최근에 이러한 시스템은 Python을 사용하여 개발되었습니다.
언어.
빌드 시스템 Waf는 NS-3 프로젝트. 그것은 새로운 세대의 하나입니다
Python 기반 빌드 시스템. 빌드하기 위해 Python을 이해할 필요가 없습니다.
현존하는 NS-3 시스템.
Waf의 피투성이 세부 사항에 관심이 있는 사용자는 기본 웹 사이트에서 찾을 수 있습니다.
http://code.google.com/p/waf/.
개발 환경
위에서 언급했듯이 스크립팅은 NS-3 C++ 또는 Python에서 수행됩니다. 대부분의 NS-3 API는
Python에서 사용할 수 있지만 모델은 두 경우 모두 C++로 작성됩니다. 일하는
이 문서에서는 C++ 및 객체 지향 개념에 대한 지식이 있다고 가정합니다. 우리는 걸릴 것입니다
일부 고급 개념이나 생소한 언어를 검토할 시간
기능, 관용구 및 디자인 패턴이 나타나는 대로. 우리는 이 튜토리얼이
그러나 C++ 튜토리얼로 넘어가므로 언어의 기본 명령을 기대합니다.
거의 상상할 수 없을 정도로 많은 C++ 정보 소스가 있습니다.
웹 또는 인쇄물.
C++를 처음 사용하는 경우 자습서 또는 요리책 기반 책이나 웹 사이트를 찾을 수 있습니다.
진행하기 전에 적어도 언어의 기본 기능을 통해 작업하십시오. 을 위한
예, 이 지도 시간.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 시스템은 개발을 위해 GNU "도구 체인"의 여러 구성 요소를 사용합니다. ㅏ
소프트웨어 툴체인은 주어진 환경에서 사용할 수 있는 프로그래밍 도구 세트입니다. 을 위한
GNU 도구 체인에 포함된 내용에 대한 빠른 검토는 다음을 참조하십시오.
http://en.wikipedia.org/wiki/GNU_toolchain. NS-3 gcc, GNU binutils 및 gdb를 사용합니다.
그러나 우리는 GNU 빌드 시스템 도구나 make나 autotools를 사용하지 않습니다. 우리는 와프를 사용합니다
이러한 기능을 위해.
일반적으로 NS-3 작성자는 Linux 또는 Linux와 유사한 환경에서 작업합니다. 그런 분들을 위해
Windows에서 실행되는 Linux 환경을 시뮬레이트하는 환경이 존재합니다.
다양한 정도. 그만큼 NS-3 프로젝트가 과거에(현재는 아님) 지원됨
이러한 사용자를 위해 Cygwin 환경에서 개발합니다. 보다 http://www.cygwin.com/ for
다운로드에 대한 자세한 내용을 확인하고 NS-3 Cygwin 및
NS-3. MinGW는 현재 공식적으로 지원되지 않습니다. Cygwin의 또 다른 대안은
VMware 서버와 같은 가상 머신 환경을 설치하고 Linux 가상을 설치하십시오.
기계.
소켓 프로그램 작성
이 예제에서 사용된 예제에서는 Berkeley Sockets API가 있는 기본 기능을 가정합니다.
지도 시간. 소켓을 처음 사용하는 경우 API 및 일반적인 사용법을 검토하는 것이 좋습니다.
사례. TCP/IP 소켓 프로그래밍에 대한 좋은 개요를 보려면 다음을 권장합니다. TCP / IP 소켓 in
C, 도나후 and 칼 버트.
이 책의 예제에 대한 소스를 포함하는 관련 웹 사이트가 있습니다.
다음에서 찾을 수 있습니다. http://cs.baylor.edu/~donahoo/practical/CSockets/.
책의 처음 네 챕터를 이해했다면(또는 접근 권한이 없는 사람들을 위해)
책의 사본, 위의 웹사이트에 표시된 에코 클라이언트 및 서버에)
튜토리얼을 이해하기에 좋은 상태여야 합니다. Multicast에 비슷한 책이 있습니다.
소켓, 멀티 캐스트 소켓, 마코프스케 and 알메로스. 필요한 자료를 다룹니다.
배포판의 멀티캐스트 예를 보면 이해할 수 있습니다.
시작하기 시작하십시오
이 섹션은 다음과 같은 시스템으로 시작하여 사용자를 작업 상태로 만드는 것을 목표로 합니다.
한 번도 없었을 수도 있습니다 NS-3 설치. 지원되는 플랫폼, 전제 조건, 방법을 다룹니다.
획득 NS-3, 구축 방법 NS-3, 빌드를 확인하고 간단한 프로그램을 실행하는 방법.
살펴보기
NS-3 함께 작동하는 소프트웨어 라이브러리 시스템으로 구축되었습니다. 사용자 프로그램은 다음과 같을 수 있습니다.
이러한 라이브러리와 연결(또는 가져오기)하도록 작성되었습니다. 사용자 프로그램은
C++ 또는 Python 프로그래밍 언어.
NS-3 소스 코드로 배포됩니다. 즉, 대상 시스템에
먼저 라이브러리를 구축한 다음 사용자를 구축하는 소프트웨어 개발 환경
프로그램) NS-3 원칙적으로 선택한 사용자를 위해 사전 구축된 라이브러리로 배포할 수 있습니다.
미래에는 그런 식으로 배포될 수 있지만 현재 많은 사용자가
실제로 편집을 통해 작업을 수행합니다. NS-3 따라서 소스 코드를 다시 빌드해야 합니다.
라이브러리가 유용합니다. 누군가 사전 제작 작업을 수행하려는 경우
운영 체제용 라이브러리 및 패키지는 ns-developers 메일링에 문의하십시오.
명부.
다음에서는 다운로드 및 빌드의 두 가지 방법을 살펴보겠습니다. NS-3. 첫 번째는
기본 웹 사이트에서 공식 릴리스를 다운로드하고 빌드합니다. 두 번째는 가져오기
의 개발 사본을 구축합니다. NS-3. 도구 이후 두 가지 예를 살펴보겠습니다.
관여도가 약간 다릅니다.
다운로드 NS-3
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 전체적으로 시스템은 상당히 복잡한 시스템이며 다음에 대한 많은 종속성이 있습니다.
다른 구성 요소. 매일 처리하게 될 시스템과 함께(
GNU 도구 체인, Mercurial, 텍스트 편집기) 여러 가지를 확인해야 합니다.
계속하기 전에 시스템에 추가 라이브러리가 있습니다. NS-3 위키 제공
유용한 힌트와 팁이 많은 페이지가 포함된 페이지입니다. 그러한 페이지 중 하나는
"설치" 페이지, http://www.nsnam.org/wiki/Installation.
이 wiki 페이지의 "전제 조건" 섹션에서는 다음을 수행하는 데 필요한 패키지에 대해 설명합니다.
일반 지원 NS-3 옵션을 설치하는 데 사용되는 명령도 제공합니다.
일반적인 Linux 변종. Cygwin 사용자는 Cygwin 설치 프로그램을 사용해야 합니다(귀하가
Cygwin 사용자는 Cygwin을 설치하는 데 사용했습니다).
이 기회에 NS-3 정말 있기 때문에 조금 위키
거기에 풍부한 정보.
이 시점부터 리더가 Linux 또는
Linux 에뮬레이션 환경(Linux, Cygwin 등) 및 GNU 툴체인 설치 및
위에서 언급한 전제 조건과 함께 확인되었습니다. 우리는 또한
대상 시스템에 Mercurial 및 Waf가 설치되어 실행 중입니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 코드는 서버의 Mercurial 리포지토리에서 사용할 수 있습니다. http://code.nsnam.org.
다음 사이트에서 tarball 릴리스를 다운로드할 수도 있습니다. http://www.nsnam.org/release/, 또는 당신은 일할 수 있습니다
Mercurial을 사용하는 리포지토리. 좋은 경우가 아니면 Mercurial을 사용하는 것이 좋습니다.
하지 않는 이유. tarball을 얻는 방법에 대한 지침은 이 섹션의 끝 부분을 참조하십시오.
놓습니다.
Mercurial 리포지토리 사용을 시작하는 가장 간단한 방법은 다음을 사용하는 것입니다. ns-3-알리논
환경. 다운로드 및 빌드를 관리하는 스크립트 세트입니다.
의 다양한 서브시스템 NS-3 당신을 위한. 시작하는 것이 좋습니다. NS-3 이것에서 일하다
환경을 제공합니다.
한 가지 방법은 다음과 같은 디렉토리를 만드는 것입니다. 작업 공간 자신의 홈 디렉토리에서
로컬 Mercurial 리포지토리를 유지할 수 있습니다. 모든 디렉토리 이름이 가능하지만
그 작업 공간 여기에서 사용됩니다(참고: repos 일부 문서에서는 다음과 같이 사용될 수도 있습니다.
예 디렉토리 이름).
다운로드 NS-3 사용 a 타르볼
tarball은 여러 파일이 묶인 소프트웨어 아카이브의 특정 형식입니다.
함께 아카이브가 압축될 수 있습니다. NS-3 소프트웨어 릴리스는
다운로드 가능한 타르볼. 다운로드 프로세스 NS-3 tarball을 통한 방법은 간단합니다. 방금
릴리스를 선택하고 다운로드하고 압축을 풀어야 합니다.
당신이 사용자로서 NS-3 라는 로컬 디렉토리에서
작업 공간. 당신이 채택하는 경우 작업 공간 디렉토리 접근 방식을 사용하면 릴리스 사본을 얻을 수 있습니다.
Linux 쉘에 다음을 입력하여(적절한 버전 번호로 대체,
물론):
$ cd
$ mkdir 작업 공간
$ cd 작업 공간
$ wget http://www.nsnam.org/release/ns-allinone-3.22.tar.bz2
$ tar xjf ns-allinone-3.22.tar.bz2
디렉토리로 변경하면 ns-알리논-3.22 여러 파일이 표시됩니다.
$ls
상수를 굽습니다.py ns-3.22 README
build.py netanim-3.105 pybindgen-0.16.0.886 util.py
이제 기반을 구축할 준비가 되었습니다. NS-3 유통.
다운로드 NS-3 사용 빵 굽기
Bake는 분산 통합 및 구축을 위한 도구로, 다음을 위해 개발되었습니다. NS-3 프로젝트.
Bake는 다음의 개발 버전을 가져오는 데 사용할 수 있습니다. NS-3 소프트웨어 및 다운로드 및
베이스 확장 빌드 NS-3 직접 코드 실행과 같은 배포
환경, 네트워크 시뮬레이션 크래들, 새로운 Python 바인딩 생성 기능 등.
최근 NS-3 릴리스, Bake는 릴리스 tarball에 포함되었습니다. 구성
릴리스된 버전에 포함된 파일을 사용하면 이전에 있던 모든 소프트웨어를 다운로드할 수 있습니다.
출시 당시 현재. 예를 들어 Bake의 버전은 다음과 같습니다.
와 함께 배포 NS-3.21 릴리스는 해당 구성 요소를 가져오는 데 사용할 수 있습니다. NS-3 공개
또는 이전 버전이지만 이후 릴리스를 위해 구성 요소를 가져오는 데 사용할 수 없습니다(
bakingconf.xml 파일이 업데이트됩니다).
최신 사본을 얻을 수도 있습니다. 굽다 Linux에 다음을 입력하여
쉘(Mercurial을 설치했다고 가정):
$ cd
$ mkdir 작업 공간
$ cd 작업 공간
$ hg 클론 http://code.nsnam.org/bake
hg(Mercurial) 명령이 실행되면 다음과 같은 내용이 표시됩니다.
표시,
...
대상 디렉토리: 베이크
모든 변경 요청
변경 세트 추가
매니페스트 추가
파일 변경 사항 추가
339개 파일에 796개 변경 사항이 포함된 63개 변경 세트 추가
분기 기본값으로 업데이트
45개의 파일이 업데이트됨, 0개의 파일이 병합됨, 0개의 파일이 제거됨, 0개의 파일이 해결되지 않음
복제 명령이 완료되면 다음이라는 디렉토리가 있어야 합니다. 굽다, 내용
다음과 같아야 합니다.
$ls
bake bakeconf.xml 문서 generate-binary.py TODO
bake.py 예제 테스트
일부 Python 스크립트와 Python 모듈을 다운로드했습니다.
굽다. 다음 단계는 해당 스크립트를 사용하여 NS-3
당신의 선택의 분배.
사용 가능한 몇 가지 구성 대상이 있습니다.
1. NS-3.22: 릴리스에 해당하는 모듈; 유사한 구성 요소를 다운로드합니다
릴리스 타르볼에.
2. ns-3-dev: 유사한 모듈이지만 개발 코드 트리를 사용함
3. ns-알리논-3.22: 클릭과 같은 기타 선택적 기능을 포함하는 모듈
라우팅, 오픈플로우 NS-3및 네트워크 시뮬레이션 크래들
4. ns-3-알리논: 알리원 모듈의 출시 버전과 유사하지만,
개발 코드.
의 현재 개발 스냅샷(미공개) NS-3 에서 찾을 수 있습니다
http://code.nsnam.org/ns-3-dev/. 개발자는 이러한 저장소를
일관되고 작동하는 상태이지만 릴리스되지 않은 코드가 있는 개발 영역에 있습니다.
필요하지 않은 경우 공식 릴리스를 유지하는 것이 좋습니다.
새로 도입된 기능.
리포지토리 목록을 검사하여 최신 버전의 코드를 찾을 수 있습니다.
또는 "ns-3 릴리스" 웹 페이지에서 최신 릴리스 링크를 클릭합니다.
이 자습서 예제에서는 다음을 사용하여 진행합니다. NS-3.22.
이제 굽기 도구를 사용하여 다양한 조각을 끌어내릴 것입니다. NS-3 당신은 될 것입니다
사용. 먼저 베이크 실행에 대해 한마디 하겠습니다.
베이크는 소스 패키지를 소스 디렉토리에 다운로드하고 설치하는 방식으로 작동합니다.
라이브러리를 빌드 디렉토리에 추가합니다. 베이크는 바이너리를 참조하여 실행할 수 있지만
다운로드한 디렉토리 외부에서 베이크를 실행하도록 선택합니다.
다음과 같이 베이크를 경로에 넣습니다(Linux bash 셸 예). 첫째, 변화
'bake' 디렉토리로 이동한 후 다음 환경 변수를 설정합니다.
$ 내보내기 BAKE_HOME=`pwd`
$ 내보내기 경로=$PATH:$BAKE_HOME:$BAKE_HOME/빌드/빈
$ 내보내기 PYTHONPATH=$PYTHONPATH:$BAKE_HOME:$BAKE_HOME/빌드/lib
그러면 bake.py 프로그램이 셸의 경로에 들어가고 다른 프로그램이
bake로 생성된 실행 파일 및 라이브러리를 찾습니다. 몇몇 베이크 사용 사례는 그렇지 않지만
위와 같이 PATH 및 PYTHONPATH를 설정해야 합니다. ns-3-allinone의 전체 빌드(
선택적 패키지) 일반적으로 수행합니다.
작업 공간 디렉토리로 이동하여 쉘에 다음을 입력하십시오.
$ ./bake.py 구성 -e ns-3.22
다음으로 다양한 구성 요소를 다운로드할 수 있는 도구가 충분한지 확인하기 위해 bake를 요청합니다.
유형:
$ ./bake.py 확인
다음과 같은 내용이 표시되어야 합니다.
> 파이썬 - 확인
> GNU C++ 컴파일러 - 확인
> 머큐리얼 - OK
> CVS-확인
> 지트 - 확인
> 바자 - OK
> 타르 도구 - OK
> 압축 해제 도구 - 확인
> Unrar 도구 - 누락됨
> 7z 데이터 압축 유틸리티 - 확인
> XZ 데이터 압축 유틸리티 - OK
> 확인 - 확인
> cMake - 확인
> 패치 도구 - OK
> autoreconf 도구 - 확인
> 도구 검색 경로: /usr/lib64/qt-3.3/bin /usr/lib64/ccache
/ usr / local / bin /큰 상자 / usr / bin / usr / local / sbin / usr / sbin / sbin
/home/tomh/빈 빈
특히, Mercurial, CVS, GIT, Bazaar 등의 다운로드 툴을 기본으로 하고 있습니다.
코드를 가져올 수 있기 때문에 이 시점에서 문제가 됩니다. 누락된 것을 설치하십시오
이 단계에서 시스템에 대한 일반적인 방법(가능한 경우)으로 도구를 사용하거나
이러한 도구를 설치하려면 필요에 따라 시스템 관리자에게 문의하십시오.
다음으로 소프트웨어 다운로드를 시도합니다.
$ ./bake.py 다운로드
다음과 같은 결과가 나와야 합니다.
>> 시스템 종속성 pygoocanvas 검색 - OK
>> 시스템 종속성 검색 python-dev - OK
>> 시스템 종속성 검색 pygraphviz - OK
>> pybindgen-0.16.0.886 다운로드 - 확인
>> 시스템 종속성 검색 중 g++ - 확인
>> 시스템 종속성 qt4 검색 중 - 확인
>> netanim-3.105 다운로드 - 확인
>> ns-3.22 다운로드 - 확인
위의 세 가지 소스가 다운로드되었음을 나타냅니다. 을 체크 해봐 예배 규칙서
지금 입력 ls; 다음을 확인해야 합니다.
$ls
netanim-3.105 ns-3.22 pybindgen-0.16.0.886
이제 빌드할 준비가 되었습니다. NS-3 유통.
건물 NS-3
건물 과 build.py
릴리스된 tarball에서 작업할 때 처음 빌드할 때 NS-3 할 수 있는 프로젝트
에 있는 편의 프로그램을 사용하여 빌드 allinone 예배 규칙서. 이 프로그램은
build.py. 이 프로그램은 가장 일반적으로 사용자를 위해 구성된 프로젝트를 가져옵니다.
유용한 방법. 그러나 고급 구성 및 작업에 유의하십시오. NS-3 의지
일반적으로 네이티브 NS-3 나중에 소개할 빌드 시스템 Waf
튜토리얼.
tarball을 사용하여 다운로드한 경우 다음과 같은 디렉토리가 있어야 합니다.
ns-알리논-3.22 아래에 당신의 ~/작업 공간 예배 규칙서. 다음을 입력합니다.
$ ./build.py --enable-examples --enable-tests
이 튜토리얼에서 예제와 테스트로 작업하고 있기 때문에
기본적으로 내장 NS-3, build.py에 대한 인수는 우리를 위해 빌드하도록 지시합니다. 그만큼
프로그램은 또한 기본적으로 사용 가능한 모든 모듈을 빌드합니다. 나중에 빌드할 수 있습니다. NS-3
예제와 테스트 없이 작업하거나 작업에 필요하지 않은 모듈을 제거하거나,
당신이 원하는 경우.
빌드 스크립트 빌드로 표시되는 많은 일반적인 컴파일러 출력 메시지를 볼 수 있습니다.
당신이 다운로드한 다양한 조각. 결국 다음을 볼 수 있습니다.
Waf: `/path/to/workspace/ns-allinone-3.22/ns-3.22/build' 디렉토리에서 나가기
'build'가 성공적으로 완료되었습니다(6m25.032s).
빌드된 모듈:
안테나 aodv 애플리케이션
교량 건물 구성 저장소
코어 csma csma-레이아웃
dsdv dsr 에너지
fd-net-장치 흐름 모니터 인터넷
lr-wpan lte 메쉬
이동성 mpi netanim(Python 없음)
네트워크 nix-벡터-라우팅 olsr
점대점 점대점 레이아웃 전파
Sixlowpan 스펙트럼 통계
탭 브리지 테스트(Python 없음) topology-read
uan virtual-net-device 웨이브
와이파이 와이맥스
빌드되지 않은 모듈(설명은 ns-3 자습서 참조):
브라이트클릭 오픈플로우
비주얼 라이저
`./ns-3.22' 디렉토리를 떠납니다.
빌드되지 않은 모듈에 대한 부분:
빌드되지 않은 모듈(설명은 ns-3 자습서 참조):
브라이트클릭 오픈플로우
비주얼 라이저
이것은 단지 일부 NS-3 외부 라이브러리에 대한 종속성이 있는 모듈은 그렇지 않을 수 있습니다.
빌드되었거나 구성에서 특별히 빌드하지 않도록 요청했습니다. 그렇습니다
시뮬레이터가 성공적으로 빌드되지 않았거나 잘못된 정보를 제공한다는 의미는 아닙니다.
빌드 중인 것으로 나열된 모듈에 대한 결과입니다.
건물 과 굽다
위의 베이킹을 사용하여 프로젝트 리포지토리에서 소스 코드를 가져온 경우 계속해서
구축에 사용 NS-3. 유형
$ ./bake.py 빌드
다음과 같이 표시되어야 합니다.
>> pybindgen-0.16.0.886 빌드 - 확인
>> netanim-3.105 구축 - 확인
>> ns-3.22 빌드 - 확인
힌트: 의견을 듣고 싶습니다. 또한 수행 두 단계, 다운로드 and 빌드 by 부름 'bake.py 전개'.
오류가 발생하면 다음 명령이 무엇을 말하는지 살펴보십시오.
너; 누락된 종속성에 대한 힌트를 제공할 수 있습니다.
$ ./bake.py 쇼
빌드하려는 패키지의 다양한 종속성이 나열됩니다.
건물 과 와프
지금까지 우리는 다음 중 하나를 사용했습니다. build.py 스크립트 또는 굽다 도구, 얻기
짓는 것부터 시작했다 NS-3. 이러한 도구는 구축에 유용합니다. NS-3 및 지원
라이브러리에서 호출합니다. NS-3 Waf 빌드 도구를 호출하여
실제 건물. 대부분의 사용자는 Waf를 직접 사용하여 구성 및
빌드 NS-3. 계속 진행하려면 작업 디렉토리를 다음으로 변경하십시오. NS-3 예배 규칙서
당신이 처음에 만든.
이 시점에서 꼭 필요한 것은 아니지만 약간 우회하는 것이 중요합니다.
프로젝트 구성을 변경하는 방법을 살펴보십시오. 아마도 가장
유용한 구성 변경은 다음의 최적화된 버전을 빌드하는 것입니다.
암호. 기본적으로 디버그 버전을 빌드하도록 프로젝트를 구성했습니다. 말하자
최적화된 빌드를 만드는 프로젝트. 최적화해야 한다고 Waf에 설명하기 위해
예제와 테스트가 포함된 빌드를 실행하려면 다음을 실행해야 합니다.
명령 :
$ ./waf 청소
$ ./waf --build-profile=optimized --enable-examples --enable-tests 구성
이렇게 하면 로컬 디렉터리에서 Waf가 실행됩니다(편의를 위해 제공됨).
이전 빌드를 정리하는 첫 번째 명령은 일반적으로 반드시 필요한 것은 아니지만
좋은 습관입니다(하지만 짓다 프로필, 아래에); 이전에 빌드된 것을 제거합니다.
디렉토리에 있는 라이브러리 및 개체 파일 짓다/. 프로젝트가 재구성되는 경우
빌드 시스템이 다양한 종속성을 확인하면 다음과 같은 출력이 표시되어야 합니다.
다음과 유사합니다.
상단 설정: .
출발: 빌드
'gcc' 확인 중(c 컴파일러): /usr/bin/gcc
cc 버전 확인 중 : 4.2.1
'g++' 확인 중(C++ 컴파일러): /usr/bin/g++
확인 부스트 포함: 1_46_1
부스트 라이브러리 확인 중 : 확인
부스트 연동 확인 중 : ok
클릭 위치 확인 중 : 찾을 수 없음
pkg-config 프로그램 확인 중: /sw/bin/pkg-config
'gtk+-2.0' >= 2.12 확인 중: 예
'libxml-2.0' >= 2.7 확인 중: 예
uint128_t 유형 확인 중: 찾을 수 없음
__uint128_t 유형 확인 중: 예
고정밀 구현 확인 : 128비트 정수(기본값)
헤더 stdint.h 확인 중 : 예
헤더 inttypes.h 확인 중 : 예
헤더 sys/inttypes.h 확인 중: 찾을 수 없음
헤더 sys/types.h 확인 중: 예
헤더 sys/stat.h 확인 중: 예
헤더 dirent.h 확인 중 : 예
헤더 stdlib.h 확인 중 : 예
헤더 signal.h 확인 중 : 예
헤더 pthread.h 확인 중 : 예
헤더 stdint.h 확인 중 : 예
헤더 inttypes.h 확인 중 : 예
헤더 sys/inttypes.h 확인 중: 찾을 수 없음
라이브러리 rt 확인 중: 찾을 수 없음
헤더 netpacket/packet.h 확인 중: 찾을 수 없음
헤더 sys/ioctl.h 확인 중: 예
헤더 net/if.h 확인 중 : 찾을 수 없음
헤더 net/ethernet.h 확인 중: 예
linux/if_tun.h 헤더 확인 중: 찾을 수 없음
헤더 netpacket/packet.h 확인 중: 찾을 수 없음
NSC 위치 확인 중 : 찾을 수 없음
'mpic++' 확인 중: 예
'sqlite3' 확인 중: 예
linux/if_tun.h 헤더 확인 중: 찾을 수 없음
프로그램 확인 중 sudo : /usr/빈/sudo
프로그램 valgrind 확인 중: /sw/bin/valgrind
'gsl' 확인 중: 예
컴파일 플래그 확인 중 -Wno-error=deprecated-d... 지원: 확인
컴파일 플래그 확인 중 -Wno-error=deprecated-d... 지원: 확인
컴파일 플래그 확인 중 -fstrict-aliasing... 지원: ok
컴파일 플래그 확인 중 -fstrict-aliasing... 지원: ok
컴파일 플래그 확인 중 -Wstrict-aliasing... 지원: ok
컴파일 플래그 확인 중 -Wstrict-aliasing... 지원: ok
프로그램 doxygen 확인 중: /usr/local/bin/doxygen
---- NS-3 옵션 기능 요약:
빌드 프로필: 디버그
빌드 디렉토리 : build
Python 바인딩: 사용
BRITE 통합: 활성화되지 않음(BRITE 활성화되지 않음(--with-brite 옵션 참조))
NS-3 클릭 통합: 활성화되지 않음(nsclick 활성화되지 않음(--with-nsclick 옵션 참조))
GtkConfigStore : 활성화
XmlIo : 활성화
스레딩 프리미티브: 사용
실시간 시뮬레이터: 활성화됨(librt는 사용할 수 없음)
에뮬레이트된 네트 장치: 활성화( 감지되지 않음 포함)
파일 설명자 NetDevice: 사용
FdNetDevice 탭: 활성화되지 않음(linux/if_tun.h 필요)
에뮬레이션 FdNetDevice: 활성화되지 않음(netpacket/packet.h 필요)
PlanetLab FdNetDevice: 활성화되지 않음(PlanetLab 운영 체제가 감지되지 않음(--force-planetlab 옵션 참조))
네트워크 시뮬레이션 크래들: 활성화되지 않음(NSC를 찾을 수 없음(--with-nsc 옵션 참조))
MPI 지원: 사용
NS-3 OpenFlow 통합: 활성화되지 않음(필수 부스트 라이브러리를 찾을 수 없음, 누락: 시스템, 신호, 파일 시스템)
SQlite 통계 데이터 출력: 사용
탭 브리지: 활성화되지 않음( 감지되지 않음 포함)
PyViz 시각화 도우미: 사용
sudo를 사용하여 suid 비트 설정: 활성화되지 않음(--enable-sudo 옵션이 선택되지 않음)
빌드 테스트: 사용
빌드 예제: 사용
GNU 과학 라이브러리(GSL): 사용
'구성'이 성공적으로 완료되었습니다(1.944초).
위 출력의 마지막 부분에 유의하십시오. 일부 NS-3 옵션은 기본적으로 활성화되어 있지 않거나
제대로 작동하려면 기본 시스템의 지원이 필요합니다. 예를 들어 활성화하려면
XmlTo, 라이브러리 libxml-2.0이 시스템에서 발견되어야 합니다. 이 라이브러리가 아니었다면
발견, 해당 NS-3 기능이 활성화되지 않고 메시지가 표시됩니다.
표시됩니다. 프로그램을 사용하는 기능이 있다는 점에 유의하십시오. sudo는 suid를 설정하기 위해
특정 프로그램의 비트. 이것은 기본적으로 활성화되어 있지 않으므로 이 기능이 보고됩니다.
"활성화되지 않음"으로.
이제 예제와 테스트가 포함된 디버그 빌드로 다시 전환하십시오.
$ ./waf 청소
$ ./waf --build-profile=debug --enable-examples --enable-tests 구성
이제 빌드 시스템이 구성되었으며 다음의 디버그 버전을 빌드할 수 있습니다. NS-3
단순히 입력하여 프로그램
$ ./와프
좋아요, 죄송합니다. NS-3 시스템의 일부를 두 번 사용했지만 이제 방법을 알고 있습니다.
구성을 변경하고 최적화된 코드를 빌드합니다.
위에서 논의한 build.py 스크립트는 --활성화 예제 and 활성화 테스트
인수이지만 일반적으로 다른 waf 옵션을 직접 지원하지 않습니다. 예를 들어, 이
작동 안 할 것이다:
$ ./build.py --비활성화-파이썬
결과적으로
build.py: 오류: 해당 옵션 없음: --disable-python
그러나 특수 연산자 -- waf에 추가 옵션을 전달하는 데 사용할 수 있으므로
위의 대신 다음이 작동합니다.
$ ./build.py -- --disable-python
기본 명령을 생성하므로 ./와프 구성 --비활성화-파이썬.
다음은 Waf에 대한 몇 가지 입문 팁입니다.
구성 대 짓다
일부 Waf 명령은 구성 단계에서만 의미가 있으며 일부 명령은
빌드 단계에서 유효합니다. 예를 들어, 다음의 에뮬레이션 기능을 사용하려는 경우
NS-3, 위에서 설명한 대로 sudo를 사용하여 suid 비트 설정을 활성화할 수 있습니다. 이것
구성 시간 명령으로 판명되었으므로 다음을 사용하여 재구성할 수 있습니다.
예제와 테스트도 포함하는 다음 명령입니다.
$ ./waf 구성 --enable-sudo --enable-examples --enable-tests
이렇게 하면 Waf는 sudo를 실행하여 소켓 생성기 프로그램을 변경합니다.
루트로 실행할 에뮬레이션 코드.
Waf에서 사용할 수 있는 다른 많은 구성 및 빌드 시간 옵션이 있습니다. 이것들을 탐구하기 위해
옵션에서 다음을 입력합니다.
$ ./waf --도움말
다음 섹션에서 일부 테스트 관련 명령을 사용합니다.
짓다 프로필
우리는 이미 Waf를 구성하는 방법을 보았습니다. 디버그 or 최적화 빌드:
$ ./waf --빌드-프로필=디버그
중간 빌드 프로필도 있습니다. 공개. -d 의 동의어입니다
--빌드 프로필.
기본적으로 Waf는 빌드 아티팩트를 빌드 예배 규칙서. 다음을 지정할 수 있습니다.
다른 출력 디렉토리 --밖 옵션, 예
$ ./waf 구성 --out=foo
이를 빌드 프로필과 결합하면 다른 컴파일 옵션 간에 전환할 수 있습니다.
깨끗한 방법으로:
$ ./waf 구성 --빌드-프로필=디버그 --out=빌드/디버그
$ ./waf 빌드
...
$ ./waf 구성 --build-profile=optimized --out=build/optimized
$ ./waf 빌드
...
이렇게 하면 항상 마지막 빌드를 덮어쓰지 않고 여러 빌드로 작업할 수 있습니다.
짓다. 전환하면 Waf는 다시 컴파일하는 대신 필요한 항목만 컴파일합니다.
다.
이와 같이 빌드 프로필을 전환할 때 동일한 변경 사항을 제공하도록 주의해야 합니다.
매번 구성 매개변수. 일부 환경을 정의하는 것이 편리할 수 있습니다.
실수를 방지하는 데 도움이 되는 변수:
$ export NS3CONFIG="--enable-examples --enable-tests"
$ export NS3DEBUG="--빌드-프로필=디버그 --out=빌드/디버그"
$ export NS3OPT=="--build-profile=optimized --out=build/optimized"
$ ./waf 구성 $NS3CONFIG $NS3DEBUG
$ ./waf 빌드
...
$ ./waf 구성 $NS3CONFIG $NS3OPT
$ ./waf 빌드
컴파일러
위의 예에서 Waf는 GCC C++ 컴파일러를 사용합니다. g ++, 건축용 NS-3. 그러나,
다음을 정의하여 Waf에서 사용하는 C++ 컴파일러를 변경할 수 있습니다. 씨엑스 환경
변하기 쉬운. 예를 들어 Clang C++ 컴파일러를 사용하려면 클랭++,
$ CXX="clang++" ./waf 구성
$ ./waf 빌드
분산 컴파일을 수행하도록 Waf를 설정할 수도 있습니다. distcc 비슷한 방식으로:
$ CXX="distcc g++" ./waf 구성
$ ./waf 빌드
더 많은 정보 distcc 분산 컴파일은 다음에서 찾을 수 있습니다. 프로젝트 페이지 아래에
설명서 섹션.
설치
Waf는 시스템의 다양한 위치에 라이브러리를 설치하는 데 사용될 수 있습니다. 기본값
라이브러리 및 실행 파일이 빌드되는 위치는 빌드 디렉토리, 그리고 때문에
Waf는 이러한 라이브러리 및 실행 파일의 위치를 알고 있으므로 설치할 필요가 없습니다.
다른 곳의 도서관.
사용자가 빌드 디렉토리 외부에 설치하기로 선택한 경우 사용자는 다음을 발행할 수 있습니다.
./와프 설치 명령. 기본적으로 설치 접두사는 다음과 같습니다. / usr / local그래서 ./와프
설치 에 프로그램을 설치합니다 / usr / local / bin, 라이브러리를 / usr / local / lib및
에 헤더 /usr/로컬/포함. 수퍼유저 권한은 일반적으로 설치에 필요합니다.
기본 접두사이므로 일반적인 명령은 다음과 같습니다. sudo는 ./와프 설치. 실행할 때
Waf를 사용하는 프로그램, Waf는 먼저 빌드 디렉토리에서 공유 라이브러리를 사용하는 것을 선호합니다.
그런 다음 로컬 환경에 구성된 라이브러리 경로에서 라이브러리를 찾습니다. 그래서
라이브러리를 시스템에 설치할 때 의도한 대로 확인하는 것이 좋습니다.
라이브러리가 사용되고 있습니다.
사용자는 다음을 전달하여 다른 접두사에 설치하도록 선택할 수 있습니다. --접두사 옵션
다음과 같이 시간을 구성합니다.
./waf 구성 --prefix=/opt/local
나중에 빌드 후 사용자가 ./와프 설치 명령, 접두사 /선택/로컬
사용하게 될 것이다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 ./와프 황어 무리 Waf가 구성될 경우 프로젝트를 재구성하기 전에 명령을 사용해야 합니다.
다른 접두사에 물건을 설치하는 데 사용됩니다.
요약하자면 전화할 필요가 없습니다. ./와프 설치 사용 NS-3. 대부분의 사용자는
Waf가 현재 라이브러리를 선택하기 때문에 이 명령이 필요합니다. 빌드 예배 규칙서,
그러나 일부 사용자는 사용 사례가 외부 프로그램 작업과 관련된 경우 유용할 수 있습니다.
의 NS-3 디렉토리.
한 와프
Waf 스크립트는 최상위 수준에 하나만 있습니다. NS-3 소스 트리. 당신이 일하면서, 당신은
에서 많은 시간을 보내는 자신을 발견할 수 있습니다. 할퀴다/, 또는 깊은 소스/..., 그리고 필요
Waf를 호출합니다. 현재 위치를 기억하고 다음과 같이 Waf를 호출할 수 있습니다.
$ ../../../와프 ...
하지만 그 작업은 지루하고 오류가 발생하기 쉬우며 더 나은 솔루션이 있습니다.
가득 차 있다면 NS-3 저장소 이 작은 보석은 시작입니다.
$ cd $(hg 루트) && ./waf ...
이것을 쉘 함수로 정의하는 것이 더 좋습니다.
$ 기능 waff { cd $(hg 루트) && ./waf $* ; }
$ 와프 빌드
tarball만 있는 경우 환경 변수가 도움이 될 수 있습니다.
$ 내보내기 NS3DIR="$PWD"
$ 기능 waff { cd $NS3DIR && ./waf $* ; }
$ CD 스크래치
$ 와프 빌드
모듈 디렉토리에서 사소한 것을 추가하고 싶을 수도 있습니다. waf 라인을 따라 스크립트
임원 ../../와프. 하지 마세요. 새로 온 사람들에게 혼란스럽고 제대로 수행되지 않으면
미묘한 빌드 오류가 발생합니다. 위의 솔루션은 갈 길입니다.
지원 NS-3
의 단위 테스트를 실행할 수 있습니다. NS-3 실행하여 배포 ./test.py -c core
스크립트:
$ ./test.py -c 코어
이러한 테스트는 Waf에서 병렬로 실행됩니다. 결국 다음과 같은 보고서가 표시됩니다.
92개 테스트 중 92개 통과(92개 통과, 0개 실패, 0개 충돌, 0 valgrind 오류)
이것이 중요한 메시지입니다.
또한 Waf의 요약 출력과 각 테스트를 실행하는 테스트 러너를 볼 수 있습니다.
실제로 다음과 같이 표시됩니다.
Waf: `/path/to/workspace/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/path/to/workspace/ns-3-allinone/ns-3-dev/build' 디렉토리에서 나가기
'빌드'가 성공적으로 완료되었습니다(1.799초).
빌드된 모듈:
aodv 애플리케이션 브리지
config-store 코어를 클릭하십시오.
csma csma-레이아웃 dsdv
emu 에너지 흐름 모니터
인터넷 lte 메쉬
모빌리티 mpi 네타님
네트워크 nix-벡터-라우팅 ns3tcp
ns3wifi olsr 오픈플로
점대점 점대점 레이아웃 전파
스펙트럼 통계 탭 브리지
템플릿 테스트 도구
토폴로지 읽기 uan virtual-net-device
시각화 와이파이 wimax
통과: TestSuite ns3-wifi-interference
통과: TestSuite 히스토그램
...
패스: TestSuite 객체
통과: TestSuite 난수 생성기
92개 테스트 중 92개 통과(92개 통과, 0개 실패, 0개 충돌, 0 valgrind 오류)
이 명령은 일반적으로 사용자가 실행하여 NS-3 유통은
올바르게 구축되었습니다. (순서는 참고 통과하다: ... 라인은 다를 수 있지만 괜찮습니다. 뭐야
중요한 것은 마지막 보고서의 요약 라인이 모든 테스트가 통과했음을 보고한다는 것입니다. 아무도 실패하지 않았거나
추락했다.)
달리는 a 스크립트
우리는 일반적으로 Waf의 제어하에 스크립트를 실행합니다. 이를 통해 빌드 시스템은
공유 라이브러리 경로가 올바르게 설정되어 있고 라이브러리를 다음 위치에서 사용할 수 있는지 확인합니다.
실행 시간. 프로그램을 실행하려면 단순히 --운영 Waf의 옵션. 실행하자 NS-3
다음을 입력하여 유비쿼터스 Hello World 프로그램과 동일합니다.
$ ./waf --안녕하세요 시뮬레이터 실행
Waf는 먼저 프로그램이 올바르게 빌드되었는지 확인하고 다음과 같은 경우 빌드를 실행합니다.
필수의. 그런 다음 Waf는 다음 출력을 생성하는 프로그램을 실행합니다.
안녕하세요 시뮬레이터
축하해요! 이제 ns-3 사용자입니다!
뭐 do I do if I 하지 참조 전에, 산출?
빌드가 성공적으로 완료되었음을 나타내는 Waf 메시지가 표시되지만
"Hello Simulator" 출력을 보면 빌드 모드를 다음으로 전환했을 가능성이 있습니다.
최적화 인간을 건물 과 와프 섹션으로 돌아갔지만 변경 사항을 놓쳤습니다. 디버그 방법.
이 튜토리얼에서 사용되는 모든 콘솔 출력은 특별한 NS-3 로깅 구성 요소
사용자 메시지를 콘솔에 인쇄하는 데 유용합니다. 이 구성 요소의 출력은
최적화된 코드를 컴파일하면 자동으로 비활성화됩니다. "최적화됩니다." 만약 너라면
"Hello Simulator" 출력이 표시되지 않으면 다음을 입력합니다.
$ ./waf 구성 --build-profile=debug --enable-examples --enable-tests
Waf에게 디버그 버전을 빌드하도록 지시합니다. NS-3 예제를 포함하는 프로그램
그리고 테스트. 여전히 다음을 입력하여 코드의 실제 디버그 버전을 빌드해야 합니다.
$ ./와프
이제 실행하면 안녕하세요 시뮬레이터 프로그램을 실행하면 예상되는 출력이 표시되어야 합니다.
프로그램 인수
명령줄 인수를 NS-3 프로그램은 다음 패턴을 사용합니다.
$ ./waf --실행 --명령 템플릿="%s "
프로그램 이름을 다음으로 대체하십시오. 에 대한 인수 . 그만큼
--명령 템플릿 Waf에 대한 인수는 기본적으로 실제
명령줄 Waf는 프로그램을 실행하는 데 사용해야 합니다. Waf는 빌드가 다음과 같은지 확인합니다.
완료하고 공유 라이브러리 경로를 설정한 다음 제공된
명령줄 템플릿, 프로그램 이름 삽입 %s 자리 표시자 (이건 인정합니다
조금 어색하지만 그게 방법입니다. 패치 환영!)
특히 유용한 또 다른 예는 자체적으로 테스트 도구 모음을 실행하는 것입니다. 가정하자
가장 최근의 테스트 스위트가 존재합니다(없습니다). 위에서 우리는 ./test.py 전체를 실행하는 스크립트
실제 테스트 프로그램을 반복적으로 호출하여 많은 테스트를 병렬로 수행합니다. 테스트 러너.
호출하려면 테스트 러너 단일 테스트를 위해 직접:
$ ./waf --run test-runner --command-template="%s --suite=mytest --verbose"
이것은 인수를 테스트 러너 프로그램. 부터 가장 최근의 존재하지 않는,
오류 메시지가 생성됩니다. 사용 가능한 인쇄하려면 테스트 러너 옵션 :
$ ./waf --run test-runner --command-template="%s --help"
디버깅
실행하려면 NS-3 디버거(예 gdb)
또는 메모리 검사기(예 Valgrind), 당신은 비슷한 --명령-템플릿="..." 양식.
예를 들어, NS-3 프로그램 안녕하세요 시뮬레이터 인수와 함께 아래
gdb 디버거:
$ ./waf --run=hello-simulator --command-template="gdb %s --args "
있음을 주목하라 NS-3 프로그램 이름은 --운영 인수 및 제어 유틸리티
(여기 gdb)는 첫 번째 토큰입니다. --명령 템플릿 논의. 그만큼 --인수 말하다 gdb
명령줄의 나머지 부분은 "열등한" 프로그램에 속합니다. (일부 gdb's
이해하지 못한다 --인수 특징. 이 경우 프로그램 인수를 생략하십시오.
--명령 템플릿, 그리고 gdb 명령 세트 인수.)
이 레시피와 이전 레시피를 결합하여 디버거에서 테스트를 실행할 수 있습니다.
$ ./waf --run test-runner --command-template="gdb %s --args --suite=mytest --verbose"
일 명부 담당
Waf는 맨 위에 있는 위치에서 실행해야 합니다. NS-3 나무. 이것이 작업이 됩니다
출력 파일이 기록될 디렉토리. 그러나 당신이 그것들을 유지하고 싶다면 어떻게 해야 할까요?
전에, NS-3 소스 트리? 사용 --cwd 논의:
$ ./waf --cwd=...
출력을 원하는 작업 디렉토리에서 시작하는 것이 더 편리할 수 있습니다.
이 경우 약간의 간접 참조가 도움이 될 수 있습니다.
$ 함수 와프 {
CWD="$PWD"
cd $NS3DIR >/dev/null
./waf --cwd="$CWD" $*
cd ->/dev/null
}
이전 버전의 이 장식은 현재 작업 디렉토리를 저장합니다. cd~까지
그런 다음 Waf에 작업 디렉터리를 변경하도록 지시합니다. 뒤로 저장된
프로그램을 실행하기 전에 현재 작업 디렉토리.
개념적 개요
실제로 보거나 쓰기 시작하기 전에 먼저 해야 할 일 NS-3 코드는
시스템의 몇 가지 핵심 개념과 추상화를 설명합니다. 이 많이 나타날 수 있습니다.
일부에게는 명백하지만 시간을 내어 이 내용을 자세히 읽어 보시기 바랍니다.
확고한 기초 위에서 시작하고 있는지 확인하기 위한 섹션입니다.
키 추상화
이 섹션에서는 네트워킹에서 일반적으로 사용되는 몇 가지 용어를 검토하지만
구체적인 의미 NS-3.
노드
인터넷 전문 용어로 네트워크에 연결되는 컴퓨팅 장치를 컴퓨터라고 합니다. 주인 or
때로는 end 체계. 때문에 NS-3 하는 네트워크 시뮬레이터, 구체적으로
인터넷 시뮬레이터와 밀접하게 관련되어 있으므로 의도적으로 호스트라는 용어를 사용하지 않습니다.
인터넷 및 해당 프로토콜과 관련이 있습니다. 대신 더 일반적인 용어를 사용합니다.
그래프 이론에서 비롯된 다른 시뮬레이터에서 사용 --- 노드.
In NS-3 기본 컴퓨팅 장치 추상화를 노드라고 합니다. 이 추상화는
C++에서 클래스로 표현 노드. 그만큼 노드 클래스는
시뮬레이션에서 컴퓨팅 장치의 표현.
당신은 생각해야 노드 기능을 추가할 컴퓨터로. 하나는 추가
애플리케이션, 프로토콜 스택 및 관련 주변 장치 카드와 같은 것
컴퓨터가 유용한 작업을 수행할 수 있도록 하는 드라이버입니다. 우리는 동일한 기본 모델을 사용합니다. NS-3.
어플리케이션
일반적으로 컴퓨터 소프트웨어는 크게 두 부류로 나뉩니다. 소프트웨어 조직
메모리, 프로세서 주기, 디스크, 네트워크 등과 같은 다양한 컴퓨터 리소스,
일부 컴퓨팅 모델에 따르면. 시스템 소프트웨어는 일반적으로 이러한 리소스를 사용하지 않습니다.
사용자에게 직접적인 혜택을 주는 작업을 완료하기 위해. 사용자는 일반적으로 신청
일부를 달성하기 위해 시스템 소프트웨어에 의해 제어되는 리소스를 획득하고 사용하는
골.
종종 시스템과 애플리케이션 소프트웨어 사이의 분리 라인은
운영 체제 트랩에서 발생하는 권한 수준 변경. ~ 안에 NS-3 진짜가 없다
운영 체제의 개념, 특히 권한 수준이나 시스템 호출의 개념이 없습니다.
그러나 우리는 응용 프로그램에 대한 아이디어를 가지고 있습니다. 소프트웨어 응용 프로그램이 실행되는 것처럼
"실제 세계"에서 작업을 수행하는 컴퓨터, NS-3 애플리케이션 실행 NS-3 노드 에
시뮬레이션 세계에서 시뮬레이션을 운전하십시오.
In NS-3 일부 활동을 생성하는 사용자 프로그램의 기본 추상화
시뮬레이션은 응용 프로그램입니다. 이 추상화는 C++에서 클래스로 표현됩니다.
어플리케이션. 그만큼 어플리케이션 클래스는 표현을 관리하기 위한 메서드를 제공합니다.
시뮬레이션의 사용자 수준 응용 프로그램 버전. 개발자는 다음을 수행할 것으로 예상됩니다.
전문화하다 어플리케이션 객체 지향 프로그래밍 감각의 클래스는 새로운 것을 생성합니다.
응용 프로그램. 이 자습서에서는 클래스의 특수화를 사용합니다. 어플리케이션 라는
UdpEchoClient응용 프로그램 and UdpEchoServer응용 프로그램. 예상할 수 있듯이 이러한
애플리케이션은 시뮬레이션을 생성하고 반향하는 데 사용되는 클라이언트/서버 애플리케이션 세트를 구성합니다.
네트워크 패킷
채널
현실 세계에서는 컴퓨터를 네트워크에 연결할 수 있습니다. 종종 다루는 미디어
이러한 네트워크의 데이터 흐름을 호출합니다. 채널. 이더넷 케이블을 연결하면
벽의 플러그, 당신은 이더넷 통신에 컴퓨터를 연결하고 있습니다
채널. 시뮬레이션 세계에서 NS-3, 하나는 노드 나타내는 객체에
커뮤니케이션 채널. 여기서 기본적인 통신 서브네트워크 추상화는
채널이며 C++에서 클래스로 표시됩니다. 채널.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 채널 클래스는 통신 서브네트워크 객체를 관리하기 위한 메서드를 제공하고
그들에 노드를 연결합니다. 채널 개체의 개발자가 전문화할 수도 있습니다.
지향 프로그래밍 감각. ㅏ 채널 전문화는 다음과 같이 단순한 것을 모델링할 수 있습니다.
철사. 전문 채널 대규모 이더넷처럼 복잡한 것을 모델링할 수도 있습니다.
스위치, 또는 무선 네트워크의 경우 장애물로 가득 찬 XNUMX차원 공간.
우리는 특수 버전을 사용할 것입니다. 채널 라는 Csma채널, 포인트투포인트채널
and 와이파이 채널 이 튜토리얼에서. 그만큼 Csma채널, 예를 들어,
구현하는 통신 서브네트워크 반송파 감각 여러 ACCESS 통신
중간. 이것은 우리에게 이더넷과 같은 기능을 제공합니다.
그물 장치
예전에는 컴퓨터를 네트워크에 연결하려면
특정 종류의 네트워크 케이블과 (PC 용어로)
주위의 카드 컴퓨터에 설치해야 했습니다. 주변 카드의 경우
일부 네트워킹 기능을 구현했으며 이를 네트워크 인터페이스 카드라고 불렀습니다. NIC.
오늘날 대부분의 컴퓨터에는 네트워크 인터페이스 하드웨어가 내장되어 있으며 사용자는
이 빌딩 블록.
NIC는 하드웨어를 제어하는 소프트웨어 드라이버가 없으면 작동하지 않습니다. 유닉스에서 (또는
Linux), 주변 하드웨어의 일부는 다음과 같이 분류됩니다. 장치. 장치가 제어됨
사용 장치 드라이버, 네트워크 장치(NIC)는 다음을 사용하여 제어됩니다. 네트워크 장치
드라이버 총칭하여 그물 장치. Unix 및 Linux에서는 이러한 네트워크를 참조합니다.
다음과 같은 이름으로 장치 eth0.
In NS-3 전에, 그물 장치 추상화는 소프트웨어 드라이버와 시뮬레이션을 모두 포함합니다.
하드웨어. 네트 장치는 노드 활성화하기 위해 노드 에
다른 사람과 의사 소통 노드 통해 시뮬레이션에서 채널. 실제 컴퓨터에서처럼,
a 노드 하나 이상에 연결될 수 있습니다. 채널 다중을 통해 NetDevices.
순 장치 추상화는 C++에서 클래스로 표현됩니다. NetDevice. 그만큼 NetDevice
클래스는 다음에 대한 연결을 관리하는 방법을 제공합니다. 노드 and 채널 사물; 그리고 될 수 있습니다
객체 지향 프로그래밍 감각의 개발자에 의해 전문화됩니다. 우리는
여러 특수 버전의 NetDevice 라는 CsmaNet장치, PointToPointNet장치,
and WifiNet장치 이 튜토리얼에서. 이더넷 NIC가 다음과 함께 작동하도록 설계된 것처럼
이더넷 네트워크, CsmaNet장치 와 함께 작동하도록 설계되었습니다. Csma채널;
PointToPointNet장치 와 함께 작동하도록 설계되었습니다. 포인트투포인트채널 및 WifiNet장치
와 함께 작동하도록 설계되었습니다. 와이파이 채널.
토폴로지 도우미
실제 네트워크에서는 NIC가 추가(또는 내장)된 호스트 컴퓨터를 찾을 수 있습니다. ~ 안에 NS-3 we
당신이 찾을 것이라고 말할 것입니다 노드 첨부 된 NetDevices. 대규모 시뮬레이션 네트워크에서
사이에 많은 연결을 조정해야 합니다. 노드, NetDevices and 채널.
연결 이후 NetDevices 에 노드, NetDevices 에 채널, IP 주소 할당,
등의 일반적인 작업입니다. NS-3, 우리는 우리가 부르는 것을 제공합니다 토폴로지 도우미 이것을 만들기 위해
가능한 한 쉽게. 예를 들어, 많은 개별 항목이 필요할 수 있습니다. NS-3 핵심 작업
NetDevice를 생성하고, MAC 주소를 추가하고, 해당 네트워크 장치를 노드, 구성
노드의 프로토콜 스택을 연결한 다음 NetDevice 에 채널. 더 많은 작업
멀티포인트 채널에 여러 장치를 연결한 다음 연결해야 합니다.
개별 네트워크를 인터네트워크로 통합합니다. 우리는 토폴로지 도우미 개체를 제공합니다.
이러한 많은 고유한 작업을 사용자의 편의를 위해 사용하기 쉬운 모델로 결합합니다.
A 먼저, NS-3 스크립트
위에서 제안한 대로 시스템을 다운로드했다면 NS-3 에
전화 번호부 repos 홈 디렉토리 아래. 해당 릴리스 디렉토리로 변경하고
다음과 같은 디렉토리 구조를 찾아야 합니다.
작성자 예제 스크래치 유틸리티 waf.bat*
바인딩 라이센스 src utils.py waf-tools
빌드 ns3 test.py* utils.pyc wscript
CHANGES.html README testpy 출력 버전 wutils.py
문서 RELEASE_NOTES testpy.supp waf* wutils.pyc
로 변경 예제/튜토리얼 예배 규칙서. 이름이 지정된 파일이 표시되어야 합니다. 첫 번째.cc 위치한
거기. 이것은 두 노드 사이에 간단한 지점 간 링크를 만드는 스크립트입니다.
노드 간에 단일 패킷을 에코합니다. 스크립트 라인을 살펴보겠습니다.
선, 그러니 계속해서 열어 첫 번째.cc 좋아하는 편집기에서.
보일러 플레이트
파일의 첫 번째 줄은 emacs 모드 줄입니다. 이것은 포맷에 대해 emacs에 알려줍니다.
소스 코드에서 사용하는 규칙(코딩 스타일).
/* -*- 모드:C++; c-파일 스타일:"gnu"; 들여쓰기 탭 모드:nil; -*- */
이것은 항상 다소 논쟁의 여지가 있는 주제이므로 우리는 그것을 방해하지 않는 편이 낫습니다.
바로. 그만큼 NS-3 프로젝트는 대부분의 대규모 프로젝트와 마찬가지로 다음을 위해 코딩 스타일을 채택했습니다.
기여한 모든 코드가 준수해야 합니다. 귀하의 코드를
결국 프로젝트를 준수해야 합니다. NS-3 에 설명된 코딩 표준
파일 문서/codingstd.txt 또는 프로젝트 웹 페이지에 표시 LINK.
의 모양과 느낌에 익숙해지는 것이 좋습니다. NS-3 코딩 및 채택
우리 코드로 작업할 때마다 이 표준입니다. 개발팀 모두와
기고자들은 다양한 양의 불평으로 그렇게했습니다. 위의 emacs 모드 행
emacs 편집기를 사용하면 올바른 형식을 쉽게 얻을 수 있습니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 시뮬레이터는 GNU General Public License를 사용하여 라이센스가 부여됩니다. 당신은 볼 수 있습니다
모든 파일의 헤드에 있는 적절한 GNU 법률 용어 NS-3 분포. 종종 당신은
관련된 기관 중 하나에 대한 저작권 표시가 표시됩니다. NS-3 위의 프로젝트
아래에 나열된 GPL 텍스트 및 작성자.
/*
* 이 프로그램은 무료 소프트웨어입니다. 재배포 및/또는 수정할 수 있습니다.
* 다음과 같이 GNU General Public License 버전 2의 조건에 따릅니다.
* 자유 소프트웨어 재단에서 발행;
*
* 이 프로그램은 유용하게 사용되길 바라는 마음에서 배포되며,
* 그러나 어떠한 보증도 제공하지 않습니다. 묵시적 보증도 없이
* 상품성 또는 특정 목적에의 적합성. 참조
* 자세한 내용은 GNU General Public License를 참조하십시오.
*
* GNU General Public License 사본을 받았어야 합니다.
* 이 프로그램과 함께; 그렇지 않은 경우 자유 소프트웨어에 쓰기
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
모듈 포함 사항
적절한 코드는 여러 include 문으로 시작합니다.
#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"
우리의 높은 수준의 스크립트 사용자가
시스템은 상대적으로 큰 모듈에 따라 그룹화합니다. 우리는 단일 제공
각 모듈에서 사용되는 모든 포함 파일을 재귀적으로 로드하는 포함 파일.
필요한 헤더를 정확히 찾아보고
종속성의 수에 따라 파일 그룹을 대규모로 로드할 수 있는 기능을 제공합니다.
세분성. 이것은 가장 효율적인 접근 방식은 아니지만 확실히 글쓰기를
스크립트가 훨씬 쉬워졌습니다.
의 각 NS-3 포함 파일은 다음 디렉토리에 있습니다. ns3 (빌드 아래
포함 파일 이름 충돌을 방지하는 데 도움이 되도록 빌드 프로세스 중에 그만큼
ns3/core-module.h 파일은 디렉토리에서 찾을 ns-3 모듈에 해당합니다.
소스/코어 다운로드한 릴리스 배포판에서. 이 디렉토리를 나열하면
많은 수의 헤더 파일을 찾으십시오. 빌드를 할 때 Waf는 공개 헤더를 배치합니다.
의 파일 ns3 해당 디렉토리 아래 빌드/디버그 or 빌드/최적화 예배 규칙서
구성에 따라. Waf는 자동으로 모듈 포함을 생성합니다.
파일을 사용하여 모든 공개 헤더 파일을 로드합니다.
물론 이 튜토리얼을 종교적으로 따르고 있기 때문에 이미 완료했을 것입니다.
a
$ ./waf -d 디버그 --enable-examples --enable-tests 구성
예제 및 테스트를 포함하는 디버그 빌드를 수행하도록 프로젝트를 구성하기 위해.
당신은 또한
$ ./와프
프로젝트를 빌드합니다. 이제 디렉토리를 보면 ../../빌드/디버그/ns3 당신 것입니다
위에 표시된 XNUMX개의 모듈 포함 파일을 찾습니다. 의 내용을 살펴볼 수 있습니다.
이러한 파일은 모든 공개 포함 파일을
각 모듈.
NS3 네임 스페이스
의 다음 줄 첫 번째.cc script는 네임스페이스 선언입니다.
네임스페이스 ns3 사용;
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 프로젝트는 C++ 네임스페이스에서 구현됩니다. ns3. 이 그룹은 모두
NS-3-글로벌 네임스페이스 외부 범위의 관련 선언, 도움이 되길 바랍니다.
다른 코드와의 통합. C++ 사용 성명서는 NS-3 네임 스페이스
현재(전역) 선언적 영역으로. 이것은 나중에 말하는 멋진 방법입니다.
이 선언은 입력할 필요가 없습니다. ns3:: 모든 범위 이전의 범위 결정 연산자
전에, NS-3 사용하기 위한 코드입니다. 네임스페이스에 익숙하지 않은 경우 문의하십시오.
거의 모든 C++ 튜토리얼과 ns3 여기서 네임스페이스 및 사용법은
표준 네임스페이스와 사용 네임 스페이스 표준; 토론에서 자주 볼 수 있는 진술
of 코우트 그리고 시내.
로깅
스크립트의 다음 줄은 다음과 같습니다.
NS_LOG_COMPONENT_DEFINE("FirstScriptExample");
이 문장을 Doxygen 문서에 대해 이야기할 수 있는 편리한 장소로 사용할 것입니다.
체계. 프로젝트 웹사이트를 보면, NS-3 프로젝트에 대한 링크를 찾을 수 있습니다.
내비게이션 바의 "문서". 이 링크를 선택하면 당사로 이동합니다.
문서 페이지. 다음으로 이동하는 "최신 릴리스" 링크가 있습니다.
의 최신 안정 릴리스에 대한 문서 NS-3. "API"를 선택하면
Documentation' 링크를 클릭하면 다음으로 이동합니다. NS-3 API 설명서 페이지.
왼쪽을 따라 구조의 그래픽 표현을 찾을 수 있습니다.
선적 서류 비치. 시작하기에 좋은 곳은 NS-3 모듈 의 "책" NS-3 항해
나무. 확장하면 모듈 당신은 목록을 볼 수 있습니다 NS-3 모듈 설명서. 그만큼
여기서 모듈의 개념은 위에서 설명한 모듈 포함 파일에 직접 연결됩니다. 그만큼
NS-3 로깅 하위 시스템은 C + + 구성 사용 된 by All 모듈 섹션, 그래서
계속해서 해당 문서 노드를 확장하십시오. 이제 확장 디버깅 예약 후
를 선택합니다 로깅 페이지.
이제 Logging 모듈에 대한 Doxygen 설명서를 살펴봐야 합니다. 에서
목록 #밝히다페이지 상단에 항목이 표시됩니다.
NS_LOG_COMPONENT_DEFINE. 들어가기 전에 검색해보면 좋을 것 같아요
전체 작업에 대한 느낌을 얻기 위한 로깅 모듈의 "자세한 설명". 너
아래로 스크롤하거나 협업 다이어그램 아래의 "자세히..." 링크를 선택하여 수행할 수 있습니다.
이.
무슨 일이 일어나고 있는지에 대한 일반적인 아이디어가 있으면 계속해서 구체적인 내용을 살펴보십시오.
NS_LOG_COMPONENT_DEFINE 선적 서류 비치. 여기서 문서를 복제하지는 않겠지만
요약하면 이 줄은 다음과 같은 로깅 구성 요소를 선언합니다. FirstScript예 허락하는
이름을 참조하여 콘솔 메시지 로깅을 활성화 및 비활성화할 수 있습니다.
본관 함수
찾을 스크립트의 다음 줄은 다음과 같습니다.
INT
메인(int argc, char *argv[])
{
이것은 프로그램(스크립트)의 주요 기능에 대한 선언일 뿐입니다. 에서처럼
모든 C++ 프로그램에서 실행되는 첫 번째 함수가 될 기본 함수를 정의해야 합니다.
여기에는 전혀 특별한 것이 없습니다. 당신의 NS-3 스크립트는 C++ 프로그램일 뿐입니다.
다음 줄은 시간 분해능을 XNUMX나노초로 설정하며 이는 기본값입니다.
값 :
시간::SetResolution(시간::NS);
분해능은 표현할 수 있는 가장 작은 시간 값입니다.
두 시간 값 사이의 표현 가능한 차이). 해상도를 정확하게 변경할 수 있습니다.
한 번. 이러한 유연성을 가능하게 하는 메커니즘은 다소 메모리가 부족하므로 일단
해상도가 명시적으로 설정되면 메모리를 해제하여 추가 업데이트를 방지합니다.
(해상도를 명시적으로 설정하지 않으면 기본적으로 XNUMX나노초로 설정되며
시뮬레이션이 시작되면 메모리가 해제됩니다.)
스크립트의 다음 두 줄은 빌드된 두 개의 로깅 구성 요소를 활성화하는 데 사용됩니다.
Echo 클라이언트 및 Echo 서버 애플리케이션에:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
Logging 구성요소 설명서를 읽어 본 적이 있다면
각 구성 요소에서 활성화할 수 있는 여러 수준의 로깅 세부 정보/세부 사항입니다.
이 두 줄의 코드는 에코 클라이언트 및
서버. 그러면 패킷이 전송될 때 응용 프로그램에서 메시지를 인쇄하게 됩니다.
시뮬레이션 중에 수신되었습니다.
이제 우리는 토폴로지를 생성하고 시뮬레이션을 실행하는 비즈니스로 직접 이동합니다.
이 작업을 가능한 한 쉽게 만들기 위해 토폴로지 도우미 개체를 사용합니다.
토폴로지 도우미
노드컨테이너
스크립트의 다음 두 줄 코드는 실제로 NS-3 노드 개체
시뮬레이션에서 컴퓨터를 나타냅니다.
NodeContainer 노드;
노드.만들기(2);
에 대한 문서를 찾아봅시다. 노드컨테이너 수업을 계속하기 전에. 또 다른 방법
주어진 클래스에 대한 문서에 들어가는 것은 클래스 Doxygen의 탭
페이지. 여전히 Doxygen이 편리한 경우 페이지 상단으로 스크롤하여
를 선택합니다 클래스 탭. 새로운 탭 세트가 표시되어야 하며 그 중 하나는 클래스
명부. 해당 탭 아래에 모든 목록이 표시됩니다. NS-3 클래스. 아래로 스크롤,
찾고 ns3::노드컨테이너. 수업을 찾으면 계속해서 선택하여 다음으로 이동합니다.
수업에 대한 문서.
우리의 핵심 추상화 중 하나가 노드. 이것은 컴퓨터를 나타냅니다.
프로토콜 스택, 응용 프로그램 및 주변 장치와 같은 것을 추가할 것입니다.
카드. 그만큼 노드컨테이너 토폴로지 도우미는 생성, 관리 및
액세스 노드 시뮬레이션을 실행하기 위해 생성하는 개체입니다. 위의 첫 번째 줄
우리가 호출하는 NodeContainer를 선언합니다. 노드. 두 번째 줄은 다음을 호출합니다. 만들기
방법에 노드 개체를 만들고 컨테이너에 두 개의 노드를 생성하도록 요청합니다. 에 설명된 바와 같이
Doxygen, 컨테이너는 NS-3 두 개를 만드는 데 적합한 시스템 노드
개체에 대한 포인터를 내부에 저장합니다.
스크립트에 있는 노드는 아무 작업도 수행하지 않습니다. 구축의 다음 단계
토폴로지는 노드를 네트워크로 연결하는 것입니다. 가장 단순한 형태의 네트워크
지원은 두 노드 사이의 단일 지점 간 링크입니다. 우리는 그 중 하나를 만들 것입니다
여기 링크.
포인트투포인트도우미
우리는 점대점 링크를 구성하고 있으며, 꽤 될 패턴으로
당신에게 친숙하지만, 우리는 토폴로지 도우미 객체를 사용하여 배치하는 데 필요한 저수준 작업을 수행합니다.
함께 링크. 핵심 추상화 중 두 가지가 NetDevice 그리고
채널. 현실 세계에서 이러한 용어는 대략 주변 장치 카드 및
네트워크 케이블. 일반적으로 이 두 가지는 밀접하게 연결되어 있으며 하나는
예를 들어 이더넷 장치와 무선 채널을 교환할 것으로 예상됩니다. 우리의 토폴로지
도우미는 이 친밀한 결합을 따르므로 단일 도구를 사용합니다.
포인트투포인트도우미 구성 및 연결 NS-3 PointToPointNet장치 and
포인트투포인트채널 이 스크립트의 객체.
스크립트의 다음 세 줄은 다음과 같습니다.
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("지연", StringValue("2ms"));
첫 번째 줄,
PointToPointHelper pointToPoint;
인스턴스화 포인트투포인트도우미 스택의 객체. 높은 수준의 관점에서 보면
다음 줄,
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
그에게 말하다. 포인트투포인트도우미 값 "5Mbps"(초당 XNUMX메가비트)를 다음과 같이 사용하는 개체
생성할 때 "DataRate" PointToPointNet장치 목적.
보다 자세한 관점에서 문자열 "DataRate"는 우리가 호출하는 것에 해당합니다.
속성 의 PointToPointNet장치. Doxygen for class를 보면
ns3::PointToPointNetDevice 에 대한 설명서를 찾으십시오. 유형 ID 가져오기 방법, 당신은
목록을 찾아 Attributes 장치에 대해 정의됩니다. 이 중 "DataRate"가 있습니다.
속성. 사용자가 가장 많이 볼 수 있는 NS-3 객체는 유사한 목록을 가지고 있습니다. Attributes. 우리는 이것을 사용합니다
다시 컴파일하지 않고 시뮬레이션을 쉽게 구성할 수 있는 메커니즘
다음 섹션.
의 "DataRate"와 유사 PointToPointNet장치 당신은 "지연"을 찾을 수 있습니다 속성
관련 포인트투포인트채널. 마지막 줄,
pointToPoint.SetChannelAttribute("지연", StringValue("2ms"));
그에게 말하다. 포인트투포인트도우미 "2ms"(XNUMX밀리초) 값을
이후 생성되는 모든 포인트 투 포인트 채널의 전송 지연.
NetDevice컨테이너
스크립트의 이 시점에서 우리는 노드컨테이너 두 개의 노드가 포함되어 있습니다. 우리는
포인트투포인트도우미 그것은 프라이밍되고 만들 준비가 PointToPointNet장치 및 와이어
포인트투포인트채널 그들 사이의 개체. 우리가 사용한 것처럼 노드컨테이너 토폴로지
헬퍼 객체를 생성하기 위한 노드 시뮬레이션을 위해 포인트투포인트도우미
우리를 위해 장치를 생성, 구성 및 설치하는 것과 관련된 작업을 수행합니다. 우리
생성된 모든 NetDevice 개체 목록이 필요하므로
NodeContainer를 사용하여 우리가 노드를 보유하는 것처럼 NetDeviceContainer가 이들을 보유합니다.
만들어진. 다음 두 줄의 코드는
NetDeviceContainer 장치;
장치 = pointToPoint.Install(노드);
장치 및 채널 구성을 완료합니다. 첫 번째 줄은 장치를 선언합니다.
위에서 언급한 컨테이너와 두 번째 컨테이너가 무거운 작업을 수행합니다. 그만큼 설치 의 방법
전에, 포인트투포인트도우미 소요 노드컨테이너 매개변수로. 내부적으로
NetDevice컨테이너 생성됩니다. 각 노드에 대해 노드컨테이너 (정확히 있어야
점대점 링크의 경우 XNUMX개) a PointToPointNet장치 생성되어 장치에 저장됩니다.
컨테이너. ㅏ 포인트투포인트채널 생성되고 두 PointToPointNet장치 are
첨부된. 에 의해 객체가 생성될 때 포인트투포인트도우미Walk Through California 프로그램, Attributes 이전에
헬퍼에 설정된 값은 해당 초기화에 사용됩니다. Attributes 생성된
사물.
실행 후 pointToPoint.설치 (노드) 우리는 두 개의 노드를 갖게 될 것입니다.
설치된 점대점 네트 장치와 이들 사이의 단일 점대점 채널.
두 장치 모두 초당 XNUMX메가비트로 데이터를 전송하도록 구성됩니다.
전송 지연이 XNUMX밀리초인 채널.
인터넷스택헬퍼
이제 노드와 장치가 구성되었지만 프로토콜 스택이 설치되어 있지 않습니다.
우리 노드에서. 다음 두 줄의 코드가 이를 처리합니다.
InternetStackHelper 스택;
stack.Install(노드);
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 인터넷스택헬퍼 인터넷 스택에 있는 토폴로지 도우미입니다.
포인트투포인트도우미 점대점 네트 장치에 대한 것입니다. 그만큼 설치 방법은
노드컨테이너 매개변수로. 실행되면 인터넷 스택을 설치합니다.
(TCP, UDP, IP 등) 노드 컨테이너의 각 노드에서.
IPv4AddressHelper
다음으로 노드의 장치를 IP 주소와 연결해야 합니다. 우리는
IP 주소 할당을 관리하는 토폴로지 헬퍼. 사용자가 볼 수 있는 유일한 API는
실제 주소를 수행할 때 사용할 기본 IP 주소 및 네트워크 마스크 설정
할당(도우미 내부의 하위 수준에서 수행됨).
예제 스크립트에서 다음 두 줄의 코드는 첫 번째.cc,
Ipv4AddressHelper 주소;
address.SetBase("10.1.1.0", "255.255.255.0");
주소 도우미 개체를 선언하고 IP 주소 할당을 시작해야 한다고 알려줍니다.
네트워크 10.1.1.0에서 마스크 255.255.255.0을 사용하여 할당 가능한 비트를 정의합니다. 에 의해
기본적으로 할당된 주소는 XNUMX에서 시작하여 단조롭게 증가하므로 첫 번째
이 베이스에서 할당된 주소는 10.1.1.1, 10.1.1.2 등이 됩니다.
수평 NS-3 시스템은 실제로 할당된 모든 IP 주소를 기억하고
실수로 동일한 주소를 두 번 생성하면 치명적인 오류가 발생합니다(즉,
그런데 오류를 디버깅하기가 매우 어렵습니다.)
코드의 다음 줄,
Ipv4InterfaceContainer 인터페이스 = address.Assign(장치);
실제 주소 할당을 수행합니다. ~ 안에 NS-3 우리는 IP 사이의 연결을 만듭니다
주소 및 장치를 사용하는 IPv4인터페이스 물체. 때때로 목록이 필요한 것처럼
나중에 참조할 수 있도록 도우미가 만든 네트 장치 목록이 필요할 때가 있습니다.
IPv4인터페이스 사물. 그만큼 IPv4인터페이스 컨테이너 이 기능을 제공합니다.
이제 스택이 설치되고 IP 주소가 있는 지점 간 네트워크가 구축되었습니다.
할당된. 이 시점에서 우리에게 필요한 것은 트래픽을 생성하는 애플리케이션입니다.
어플리케이션
ns-3 시스템의 핵심 추상화 중 또 다른 하나는 어플리케이션. 이번에
우리는 핵심의 두 가지 전문화를 사용하는 스크립트 NS-3 수업 어플리케이션 라는
UdpEchoServer응용 프로그램 and UdpEchoClient응용 프로그램. 우리가 이전에 그랬던 것처럼
기본 개체를 구성하고 관리하는 데 도움이 되는 도우미 개체를 사용합니다.
여기서 우리가 사용하는 UdpEchoServer도우미 and UdpEchoClient도우미 우리의 삶을 편하게 해주는 물건들.
UdpEchoServer도우미
예제 스크립트의 다음 코드 줄은 첫 번째.cc, UDP 에코를 설정하는 데 사용됩니다.
이전에 생성한 노드 중 하나에 있는 서버 응용 프로그램입니다.
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(nodes.Get(1));
serverApps.Start(초(1.0));
serverApps.Stop(초(10.0));
위 스니펫의 첫 번째 코드 줄은 다음을 선언합니다. UdpEchoServer도우미. 평소와 같이,
이것은 응용 프로그램 자체가 아니라 실제 응용 프로그램을 만드는 데 도움이 되는 개체입니다.
응용 프로그램. 우리의 관습 중 하나는 필수 Attributes 도우미에서
건설자. 이 경우 도우미는 다음과 같이 제공되지 않는 한 유용한 작업을 수행할 수 없습니다.
클라이언트도 알고 있는 포트 번호. 하나만 고르고 기대하기보다
모두 잘 작동하므로 생성자에 대한 매개변수로 포트 번호가 필요합니다. 그만큼
생성자는 차례로 단순히 속성 설정 전달된 값으로. 당신이 원한다면, 당신은
"포트"를 설정할 수 있습니다. 속성 나중에 다른 값으로 속성 설정.
다른 많은 도우미 개체와 유사하게 UdpEchoServer도우미 객체는 설치
방법. 실제로 기본 에코를 유발하는 것은 이 메서드의 실행입니다.
인스턴스화되고 노드에 연결될 서버 응용 프로그램입니다. 흥미롭게도 설치
방법은 노드컨테이너 다른 것과 마찬가지로 매개변수로 설치 우리가 가지고 있는 방법
본. 이것은 그렇게 보이지 않더라도 실제로 메소드에 전달되는 것입니다.
이 경우. C++이 있습니다. 절대적인 변환 결과를 가져오는 여기 작업에서
노드.가져오기 (1) (노드 개체에 대한 스마트 포인터를 반환합니다 --- Ptr) 그리고 그것을 사용
이름 없는 생성자에서 노드컨테이너 그런 다음 설치. 당신이있는 경우
컴파일하고 실행하는 C++ 코드에서 특정 메서드 시그니처를 찾기 위해 항상 헤매고 있습니다.
좋습니다. 이러한 종류의 암시적 변환을 찾으십시오.
우리는 지금 그것을 본다 echoServer.설치 를 설치할 것입니다 UdpEchoServer응용 프로그램 를 시청하여 이에 대해 더 많은 정보를 얻을 수 있습니다.
인덱스 번호 XNUMX에서 찾은 노드 노드컨테이너 우리는 노드를 관리했습니다. 설치
모든 응용 프로그램에 대한 포인터를 보유하는 컨테이너를 반환합니다(이 경우 하나
우리가 통과 이후 노드컨테이너 하나의 노드 포함) 도우미에 의해 생성됩니다.
애플리케이션은 트래픽 생성을 "시작"하는 데 시간이 필요하며 선택적인 시간이 걸릴 수 있습니다.
"멈추다". 우리는 둘 다 제공합니다. 이 시간은 다음을 사용하여 설정됩니다. 애플리케이션 컨테이너 방법
스타트 and 중지. 이러한 방법은 Time 매개변수. 이 경우, 우리는 명백한 C + +
C++ double 1.0을 가져와서 NS-3 Time 사용하는 개체
a 초 깁스. 변환 규칙은 모델 작성자가 제어할 수 있습니다.
C++에는 고유한 규칙이 있으므로 항상 매개변수가 만족스러울 것이라고 가정할 수는 없습니다.
당신을 위해 변환. 두 줄,
serverApps.Start(초(1.0));
serverApps.Stop(초(10.0));
에코 서버 애플리케이션이 스타트 (활성화) XNUMX초에
시뮬레이션 및 중지 (비활성화) 시뮬레이션 시작 XNUMX초 후. 의 미덕
시뮬레이션 이벤트(응용 프로그램 중지 이벤트)를 다음과 같이 선언했다는 사실
XNUMX초에 실행되면 시뮬레이션이 지속됩니다. at 가장 작은 XNUMX 초
UdpEchoClient도우미
에코 클라이언트 응용 프로그램은 거의 유사한 방법으로 설정됩니다.
섬기는 사람. 기본이 있습니다 UdpEchoClient응용 프로그램 에 의해 관리되는
UdpEchoClient도우미.
UdpEchoClientHelper echoClient(인터페이스.GetAddress(1), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue (1));
echoClient.SetAttribute("간격", TimeValue(초(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));
ApplicationContainer clientApps = echoClient.Install(nodes.Get(0));
clientApps.Start(초(2.0));
clientApps.Stop(초(10.0));
그러나 에코 클라이언트의 경우 XNUMX가지를 서로 다르게 설정해야 합니다. Attributes. 처음 두
Attributes 건설 중에 설정됩니다. UdpEchoClient도우미. 매개변수를 전달합니다.
"RemoteAddress" 및 "RemotePort"를 설정하기 위해 (도우미 내부적으로) 사용되는
Attributes 우리의 협약에 따라 필수 Attributes 매개 변수
도우미 생성자.
우리가 사용한 것을 기억하십시오 IPv4인터페이스 컨테이너 우리가 IP 주소를 추적하기 위해
우리 장치에 할당되었습니다. XNUMX번째 인터페이스 인터페이스 컨테이너는
에서 XNUMX번째 노드의 IP 주소에 해당합니다. 노드 컨테이너. 첫번째
인터페이스 인터페이스 컨테이너는 첫 번째 노드의 IP 주소에 해당합니다.
전에, 노드 컨테이너. 따라서 코드의 첫 번째 줄(위에서)에서
도우미 및 클라이언트의 원격 주소를 IP 주소로 설정하도록 지시합니다.
서버가 상주하는 노드에 할당됩니다. 우리는 또한 그것을 보내도록 준비하라고 말합니다
포트 XNUMX에 대한 패킷.
"맥스패킷" 속성 클라이언트에게 허용하는 최대 패킷 수를 알려줍니다.
시뮬레이션 중에 보냅니다. "간격" 속성 클라이언트에게 대기 시간을 알려줍니다.
패킷 사이 및 "PacketSize" 속성 클라이언트에게 패킷의 크기를 알려줍니다.
페이로드가 있어야 합니다. 이 특정 조합으로 Attributes, 우리는
클라이언트는 하나의 1024바이트 패킷을 보냅니다.
에코 서버의 경우와 마찬가지로 에코 클라이언트에게 다음과 같이 지시합니다. 스타트 and 중지하지만,
여기서는 서버가 활성화된 후 XNUMX초 후에 클라이언트를 시작합니다.
시뮬레이션).
모의 실험 장치
이 시점에서 해야 할 일은 실제로 시뮬레이션을 실행하는 것입니다. 이것은 다음을 사용하여 수행됩니다.
글로벌 기능 시뮬레이터::실행.
시뮬레이터::실행();
이전에 메소드를 호출했을 때,
serverApps.Start(초(1.0));
serverApps.Stop(초(10.0));
...
clientApps.Start(초(2.0));
clientApps.Stop(초(10.0));
실제로 시뮬레이터에서 이벤트를 1.0초, 2.0초 및 두 개의 이벤트로 예약했습니다.
10.0초. 언제 시뮬레이터::실행 호출되면 시스템은 다음을 통해 보기 시작합니다.
예약된 이벤트 목록 및 실행. 먼저 1.0초에 이벤트를 실행하고,
그러면 에코 서버 응용 프로그램이 활성화됩니다(이 이벤트는 차례로 많은
기타 이벤트). 그런 다음 시작되는 t=2.0초 동안 예약된 이벤트를 실행합니다.
에코 클라이언트 애플리케이션. 다시 말하지만 이 이벤트는 더 많은 이벤트를 예약할 수 있습니다. 시작
에코 클라이언트 응용 프로그램의 이벤트 구현은 다음의 데이터 전송 단계를 시작합니다.
서버에 패킷을 전송하여 시뮬레이션.
패킷을 서버로 보내는 행위는 다음과 같은 일련의 이벤트를 트리거합니다.
장면 뒤에서 자동으로 일정이 잡히고
스크립트에서 설정한 다양한 타이밍 매개변수에 따라 패킷 에코.
결국 우리는 하나의 패킷만 보내기 때문에( 최대 패킷 속성 에 설정되었습니다.
하나) 단일 클라이언트 에코 요청에 의해 트리거된 이벤트 체인이 점점 줄어들고
시뮬레이션이 유휴 상태가 됩니다. 이 일이 발생하면 나머지 이벤트는 다음과 같습니다. 중지
서버와 클라이언트에 대한 이벤트. 이러한 이벤트가 실행될 때
처리할 추가 이벤트 및 시뮬레이터::실행 보고. 그러면 시뮬레이션이 완료됩니다.
남은 것은 청소하는 것뿐입니다. 이는 전역 함수를 호출하여 수행됩니다.
시뮬레이터::파괴. 도우미 기능(또는 저수준 NS-3 코드) 실행, 그들은
모든 개체를 파괴하기 위해 시뮬레이터에 후크가 삽입되도록 배열했습니다.
생성되었습니다. --- 이러한 개체를 직접 추적할 필요가 없었습니다.
당신이해야 할 일은 전화하는 것뿐이었습니다 시뮬레이터::파괴 종료합니다. 그만큼 NS-3 시스템이 처리
당신에게 어려운 부분. 첫 번째의 나머지 줄 NS-3 스크립트, 첫 번째.cc, 그냥
그 :
시뮬레이터::파괴();
0가 돌아;
}
인셀덤 공식 판매점인 전에, 시뮬레이터 의지 중지?
NS-3 불연속 이벤트(DE) 시뮬레이터입니다. 이러한 시뮬레이터에서는 각 이벤트가 연결됩니다.
실행 시간과 함께 시뮬레이션이 진행됩니다.
시뮬레이션 시간의 순서. 이벤트로 인해 향후 이벤트가 예약될 수 있습니다(예:
타이머는 다음 간격에서 만료되도록 자체 일정을 변경할 수 있습니다).
초기 이벤트는 일반적으로 각 개체에 의해 트리거됩니다. 예를 들어 IPv6은 라우터를 예약합니다.
광고, Neighbor Solicitations 등, Application은 첫 번째 패킷을 예약합니다.
보내는 이벤트 등
이벤트가 처리될 때 XNUMX개 또는 하나 이상의 이벤트를 생성할 수 있습니다. 시뮬레이션으로
실행되고 이벤트가 소비되지만 더 많은 이벤트가 생성될 수도 있고 생성되지 않을 수도 있습니다. 그만큼
이벤트 대기열에 더 이상의 이벤트가 없거나 다음과 같은 경우 시뮬레이션이 자동으로 중지됩니다.
특별한 중지 이벤트가 발견되었습니다. Stop 이벤트는 다음을 통해 생성됩니다. 시뮬레이터::정지
(정지시간); 기능.
대표적인 경우가 있는데 시뮬레이터::정지 중단하기 위해 절대적으로 필요하다.
시뮬레이션: 자체적으로 지속되는 이벤트가 있을 때. 자체 유지(또는 반복) 이벤트
항상 일정을 재조정하는 이벤트입니다. 결과적으로 그들은 항상 이벤트를 유지합니다.
대기열이 비어 있지 않습니다.
반복 이벤트를 포함하는 많은 프로토콜과 모듈이 있습니다. 예:
· FlowMonitor - 손실된 패킷을 주기적으로 확인
· RIPng - 라우팅 테이블 업데이트의 주기적인 브로드캐스트
· 등.
이 경우, 시뮬레이터::정지 시뮬레이션을 정상적으로 중지하는 데 필요합니다. ~ 안에
추가로 언제 NS-3 에뮬레이션 모드에 있으며, 실시간 시뮬레이터 유지하는 데 사용됩니다.
기계 시계와 정렬된 시뮬레이션 시계 시뮬레이터::정지 중지하는 데 필요합니다
과정.
자습서의 많은 시뮬레이션 프로그램은 명시적으로 호출하지 않습니다. 시뮬레이터::정지,
이벤트 대기열은 자동으로 이벤트가 부족하기 때문입니다. 그러나 이러한 프로그램은
전화도 받아 시뮬레이터::정지. 예를 들어 다음 추가 문은
첫 번째 예제 프로그램은 11초에 명시적으로 중지하도록 예약합니다.
+ 시뮬레이터::정지(초(11.0));
시뮬레이터::실행();
시뮬레이터::파괴();
0가 돌아;
}
위의 내용은 실제로 이 프로그램의 동작을 변경하지 않습니다.
시뮬레이션은 10초 후에 자연스럽게 종료됩니다. 하지만 정지 시간을 변경하려면
위의 설명을 11초에서 1초로 설정하면 시뮬레이션이
출력이 화면에 인쇄되기 전에 중지합니다(출력은 약 2 시간에 발생하기 때문입니다.
시뮬레이션 시간 초).
전화하는 것이 중요합니다 시뮬레이터::정지 전에 부름 시뮬레이터::실행; 그렇지 않으면,
시뮬레이터::실행 중지를 실행하기 위해 메인 프로그램으로 제어를 반환하지 않을 수 있습니다!
건물 너의 스크립트
우리는 간단한 스크립트를 작성하는 것을 쉽게 만들었습니다. 당신이해야 할 일은 당신을 떨어 뜨리는 것입니다
스크립트를 스크래치 디렉토리에 넣고 Waf를 실행하면 자동으로 빌드됩니다.
해 보자. 복사 예제/튜토리얼/first.cc 로 할퀴다 변경 후 디렉토리
최상위 디렉토리로 돌아갑니다.
$cd ../ ..
$ cp 예/튜토리얼/first.cc 스크래치/myfirst.cc
이제 waf를 사용하여 첫 번째 예제 스크립트를 빌드합니다.
$ ./와프
다음을 보고하는 메시지가 표시되어야 합니다. 내 첫 번째 예제가 성공적으로 빌드되었습니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
[614/708] cxx: 스크래치/myfirst.cc -> 빌드/디버그/scratch/myfirst_3.o
[706/708] cxx_link: 빌드/디버그/스크래치/myfirst_3.o -> 빌드/디버그/스크래치/myfirst
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(2.357초).
이제 예제를 실행할 수 있습니다(스크래치 디렉토리에 프로그램을 빌드하는 경우
스크래치 디렉토리에서 실행해야 함):
$ ./waf --스크래치/myfirst 실행
몇 가지 출력이 표시됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.418초).
1024바이트를 10.1.1.2로 보냈습니다.
1024에서 10.1.1.1바이트 수신됨
1024에서 10.1.1.2바이트 수신됨
여기에서 빌드 시스템이 파일이 빌드되었는지 확인하고
그런 다음 실행합니다. 에코 클라이언트의 로깅 구성 요소가 전송되었음을 나타내는 것을 볼 수 있습니다.
1024의 Echo 서버에 하나의 10.1.1.2바이트 패킷. 로깅 구성 요소도 표시됩니다.
에코 서버에서 1024에서 10.1.1.1바이트를 수신했다고 말합니다. 에코 서버
자동으로 패킷을 반향하고 패킷을 수신한 반향 클라이언트 로그를 볼 수 있습니다.
다시 서버에서.
NS-3 출처 암호
이제 몇 가지를 사용했으므로 NS-3 도우미 중 일부를 살펴보고 싶을 수 있습니다.
해당 기능을 구현하는 소스 코드. 최신 코드는 에서 찾아볼 수 있습니다.
다음 링크의 웹 서버: http://code.nsnam.org/ns-3-dev. 거기, 당신은 볼 수 있습니다
Mercurial 요약 페이지 NS-3 개발 트리.
페이지 상단에 여러 링크가 표시됩니다.
요약 | 쇼트로그 | 변경 로그 | 그래프 | 태그 | 파일
계속해서 다음을 선택하십시오. 파일 링크. 이것이 우리 대부분의 최상위 수준입니다.
저장소 볼 것이다:
drwxr-xr-x [업]
drwxr-xr-x 바인딩 파이썬 파일
drwxr-xr-x 문서 파일
drwxr-xr-x 예제 파일
drwxr-xr-x ns3 파일
drwxr-xr-x 스크래치 파일
drwxr-xr-x src 파일
drwxr-xr-x 유틸리티 파일
-rw-r--r-- 2009-07-01 12:47 +0200 560 .hgignore 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 1886 .hgtags 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 1276 작성자 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 17987 라이센스 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 3742 README 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 16171 RELEASE_NOTES 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 6 버전 파일 | 개정판 | 주석을 달다
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 waf 파일 | 개정판 | 주석을 달다
-rwxr-xr-x 2009-07-01 12:47 +0200 28 waf.bat 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 35395 wscript 파일 | 개정판 | 주석을 달다
-rw-r--r-- 2009-07-01 12:47 +0200 7673 wutils.py 파일 | 개정판 | 주석을 달다
예제 스크립트는 예 예배 규칙서. 클릭하면 예 당신은 볼 수
하위 디렉토리 목록. 에 있는 파일 중 하나 지도 시간 하위 디렉토리는 첫 번째.cc. 만약에
클릭 첫 번째.cc 방금 통과한 코드를 찾을 수 있습니다.
소스 코드는 주로 SRC 예배 규칙서. 다음 중 하나를 통해 소스 코드를 볼 수 있습니다.
디렉토리 이름을 클릭하거나 파일 의 오른쪽에 링크
디렉토리 이름. 를 클릭하면 SRC 디렉토리, 당신은 목록으로 이동합니다
전에, SRC 하위 디렉토리. 다음을 클릭하면 core 하위 디렉토리에서 목록을 찾을 수 있습니다.
파일. (이 글을 쓰는 시점에서) 찾을 첫 번째 파일은 중단.h. 클릭하면
중단.h 링크를 클릭하면 소스 파일로 전송됩니다. 중단.h 유용한 매크로가 포함된
비정상적인 조건이 감지되면 스크립트를 종료합니다.
이 장에서 사용한 도우미의 소스 코드는 다음에서 찾을 수 있습니다.
src/응용 프로그램/도우미 예배 규칙서. 디렉토리 트리에서 자유롭게 찌르면 얻을 수 있습니다.
거기에 대한 느낌과 스타일 NS-3 프로그램.
조정
사용 전에, 로깅 모듈
우리는 이미 에 대해 간략히 살펴보았습니다. NS-3 넘어가는 동안 로깅 모듈
첫 번째.cc 스크립트. 이제 자세히 살펴보고 어떤 종류의 사용 사례가 있는지 살펴보겠습니다.
로깅 하위 시스템은 다루도록 설계되었습니다.
로깅 살펴보기
많은 대형 시스템은 일종의 메시지 로깅 기능을 지원하며 NS-3 아니다
예외. 경우에 따라 오류 메시지만 "운영자 콘솔"에 기록됩니다.
일반적으로 표준 오류 Unix 기반 시스템에서). 다른 시스템에서는 경고 메시지가
더 자세한 정보 메시지를 출력합니다. 경우에 따라 로깅 기능
출력을 빠르게 흐리게 만들 수 있는 디버그 메시지를 출력하는 데 사용됩니다.
NS-3 는 이러한 모든 상세 수준이 유용하다는 견해를 가지고 있으며
메시지 로깅에 대한 선택 가능한 다단계 접근 방식. 로깅을 완전히 비활성화할 수 있습니다.
구성 요소별로 활성화되거나 전역적으로 활성화됩니다. 선택 가능한 기능을 제공합니다.
자세한 수준. 그만큼 NS-3 log 모듈은 간단하고 상대적으로 사용하기 쉬운 기능을 제공합니다.
시뮬레이션에서 유용한 정보를 얻는 방법.
우리는 범용 메커니즘 --- 추적 ---을 제공한다는 것을 이해해야 합니다.
시뮬레이션 출력에 선호되는 데이터를 모델에서 가져옵니다(참조:
추적 시스템에 대한 자세한 내용은 추적 시스템 사용 튜토리얼 섹션 참조).
디버깅 정보, 경고, 오류 메시지 또는 모든
스크립트나 모델에서 빠른 메시지를 쉽게 얻고 싶을 때.
현재 XNUMX개 레벨의 로그 메시지가 정의되어 있습니다.
시스템.
· LOG_ERROR --- 로그 오류 메시지(연결된 매크로: NS_LOG_ERROR);
· LOG_WARN --- 로그 경고 메시지(연결된 매크로: NS_LOG_WARN);
· LOG_DEBUG --- 비교적 드문 임시 디버깅 메시지를 기록합니다(관련 매크로:
NS_LOG_DEBUG);
· LOG_INFO --- 프로그램 진행에 대한 로그 정보 메시지(관련 매크로:
NS_LOG_INFO);
· LOG_FUNCTION --- 호출된 각 함수를 설명하는 메시지를 기록합니다(XNUMX개의 관련 매크로:
구성원 함수에 사용되는 NS_LOG_FUNCTION 및 정적에 사용되는 NS_LOG_FUNCTION_NOARGS
기능);
· LOG_LOGIC -- 함수 내의 논리적 흐름을 설명하는 로그 메시지(관련 매크로:
NS_LOG_LOGIC);
· LOG_ALL --- 위에서 언급한 모든 항목을 기록합니다(연결된 매크로 없음).
각 LOG_TYPE에는 LOG_LEVEL_TYPE도 있습니다. 이 유형을 사용하면 모든
그것의 수준에 더하여 그 위의 수준. (이로 인해 LOG_ERROR 및
LOG_LEVEL_ERROR와 LOG_ALL 및 LOG_LEVEL_ALL은 기능적으로 동일합니다.)
예를 들어, LOG_INFO를 활성화하면 NS_LOG_INFO 매크로에서 제공하는 메시지만 활성화됩니다.
LOG_LEVEL_INFO를 활성화하면 NS_LOG_DEBUG, NS_LOG_WARN에서 제공하는 메시지도 활성화됩니다.
및 NS_LOG_ERROR 매크로.
또한 조건에 관계없이 항상 표시되는 무조건 로깅 매크로를 제공합니다.
로깅 수준 또는 구성 요소 선택.
· NS_LOG_UNCOND -- 연결된 메시지를 무조건적으로 기록합니다(연결된 로그 수준 없음).
각 레벨은 개별적으로 또는 누적하여 요청할 수 있습니다. 로깅은 다음을 사용하여 설정할 수 있습니다.
쉘 환경 변수(NS_LOG) 또는 로깅 시스템 함수 호출. 본 바와 같이
튜토리얼의 앞부분에서 로깅 시스템에는 Doxygen 문서가 있으며 이제
로깅 모듈 문서를 정독하지 않은 경우 정독할 좋은 시간입니다.
이제 설명서를 자세히 읽었으므로 해당 지식 중 일부를 사용하겠습니다.
흥미로운 정보를 얻기 위해 스크래치/myfirst.cc 당신이 가지고있는 예제 스크립트
이미 지어졌습니다.
사용 로깅
NS_LOG 환경 변수를 사용하여 더 많은 로깅을 설정해 보겠습니다.
방향을 잡고 이전에 했던 것처럼 마지막 스크립트를 실행합니다.
$ ./waf --스크래치/myfirst 실행
이제 친숙한 첫 번째 출력이 표시되어야 합니다. NS-3 예제 프로그램
$ Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.413초).
1024바이트를 10.1.1.2로 보냈습니다.
1024에서 10.1.1.1바이트 수신됨
1024에서 10.1.1.2바이트 수신됨
위에 보이는 "Sent" 및 "Received" 메시지가 실제로 기록되고 있는 것으로 나타났습니다.
의 메시지 UdpEchoClient응용 프로그램 and UdpEchoServer응용 프로그램. 우리는 물어볼 수 있습니다
예를 들어 로깅 수준을 설정하여 더 많은 정보를 인쇄하기 위한 클라이언트 애플리케이션
NS_LOG 환경 변수를 통해.
여기서부터는 다음을 사용하는 sh와 같은 셸을 사용한다고 가정하겠습니다.
"VARIABLE=value" 구문. csh와 같은 쉘을 사용하는 경우 다음을 수행해야 합니다.
내 예제를 해당 셸에 필요한 "setenv VARIABLE value" 구문으로 변환합니다.
현재 UDP 에코 클라이언트 애플리케이션은 다음 코드 행에 응답하고 있습니다.
스크래치/myfirst.cc,
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
이 코드 줄은 LOG_LEVEL_INFO 로깅 수준. 로깅을 통과할 때
레벨 플래그, 우리는 실제로 주어진 레벨과 모든 하위 레벨을 활성화합니다. 이 경우,
우리는 활성화했습니다 NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN and NS_LOG_ERROR. 우리는 증가시킬 수 있습니다
로깅 수준을 변경하고 스크립트를 변경하고 다시 컴파일하지 않고도 더 많은 정보를 얻을 수 있습니다.
다음과 같이 NS_LOG 환경 변수를 설정합니다.
$ 내보내기 NS_LOG=UdpEchoClientApplication=level_all
이것은 쉘 환경 변수를 설정합니다 NS_LOG 문자열에,
UdpEchoClientApplication=level_all
할당의 왼쪽은 설정하려는 로깅 구성 요소의 이름입니다.
오른쪽은 사용하려는 플래그입니다. 이 경우 전원을 켜겠습니다.
응용 프로그램의 모든 디버깅 수준. NS_LOG가 설정된 상태에서 스크립트를 실행하면
이렇게, NS-3 로깅 시스템이 변경 사항을 선택하고 다음이 표시되어야 합니다.
출력 :
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.404초).
UdpEchoClient응용 프로그램:UdpEchoClient()
UdpEchoClient응용 프로그램:데이터 크기 설정(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClient응용 프로그램:보내기()
1024바이트를 10.1.1.2로 보냈습니다.
1024에서 10.1.1.1바이트 수신됨
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
1024에서 10.1.1.2바이트 수신됨
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClient응용 프로그램:~UdpEchoClient()
애플리케이션에서 제공하는 추가 디버그 정보는 NS_LOG_FUNCTION에서 가져옵니다.
수준. 스크립트 중에 응용 프로그램의 함수가 호출될 때마다 표시됩니다.
실행. 일반적으로 멤버 함수에서 (적어도) NS_LOG_FUNCTION(this)를 사용하는 것은
우선의. 정적 함수에서만 NS_LOG_FUNCTION_NOARGS()를 사용하십시오. 그러나
에는 요구 사항이 없습니다. NS-3 모델이 특정 특정 항목을 지원해야 하는 시스템
로깅 기능. 기록되는 정보의 양에 대한 결정은
개별 모델 개발자. 에코 애플리케이션의 경우 상당한 양의 로그
출력이 가능합니다.
이제 애플리케이션에 대한 함수 호출 로그를 볼 수 있습니다. 만약 너라면
자세히 보면 문자열 사이에 하나의 콜론이 있음을 알 수 있습니다. UdpEchoClient응용 프로그램
및 C++ 범위 연산자가 예상되는 메서드 이름(::). 이것은
의도적.
이름은 실제로 클래스 이름이 아니라 로깅 구성 요소 이름입니다. 있을 때
소스 파일과 클래스 사이의 일대일 대응, 이것은 일반적으로
클래스 이름이지만 실제로는 클래스 이름이 아니라는 점을 이해해야 합니다.
이중 콜론 대신 단일 콜론을 사용하여 상대적으로 미묘하게
로깅 구성 요소 이름과 클래스 이름을 개념적으로 구분합니다.
경우에 따라 실제로 어떤 방법을 결정하기 어려울 수 있음이 밝혀졌습니다.
로그 메시지를 생성합니다. 위의 텍스트를 보면 문자열이 어디에 있는지 궁금할 수 있습니다.
"수상 1024 바이트 에 10.1.1.2"에서 옵니다. OR'ing으로 이 문제를 해결할 수 있습니다.
접두사_펑크 수준으로 NS_LOG 환경 변수. 다음을 시도하십시오.
$ 내보내기 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'
OR을 나타내는 데 사용하는 수직 막대 때문에 따옴표가 필요합니다.
작업은 Unix 파이프 커넥터이기도 합니다.
이제 스크립트를 실행하면 로깅 시스템이 모든
지정된 로그 구성 요소의 메시지에는 구성 요소 이름이 접두사로 추가됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.417초).
UdpEchoClient응용 프로그램:UdpEchoClient()
UdpEchoClient응용 프로그램:데이터 크기 설정(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClient응용 프로그램:보내기()
UdpEchoClientApplication:Send(): 1024바이트를 10.1.1.2로 보냈습니다.
1024에서 10.1.1.1바이트 수신됨
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): 1024에서 10.1.1.2바이트를 받았습니다.
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClient응용 프로그램:~UdpEchoClient()
이제 UDP 에코 클라이언트 애플리케이션에서 오는 모든 메시지가
이와 같이 식별됩니다. "Received 1024 bytes from 10.1.1.2" 메시지가 이제 명확하게 표시됩니다.
에코 클라이언트 애플리케이션에서 오는 것으로 식별됩니다. 나머지 메시지는
UDP 에코 서버 애플리케이션에서 오는 것입니다. 다음을 입력하여 해당 구성 요소를 활성화할 수 있습니다.
NS_LOG 환경 변수에서 콜론으로 구분된 구성 요소 목록입니다.
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
UdpEchoServerApplication=level_all|prefix_func'
경고: 다음 줄 바꿈을 제거해야 합니다. : 위의 예제 텍스트에서
문서 형식 지정 목적으로만 존재합니다.
이제 스크립트를 실행하면 두 에코 클라이언트의 모든 로그 메시지가 표시됩니다.
그리고 서버 애플리케이션. 이것이 문제를 디버깅하는 데 매우 유용할 수 있음을 알 수 있습니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.406초).
UdpEchoServer응용 프로그램:UdpEchoServer()
UdpEchoClient응용 프로그램:UdpEchoClient()
UdpEchoClient응용 프로그램:데이터 크기 설정(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClient응용 프로그램:보내기()
UdpEchoClientApplication:Send(): 1024바이트를 10.1.1.2로 보냈습니다.
UdpEchoServerApplication:HandleRead(): 1024에서 10.1.1.1바이트를 받았습니다.
UdpEchoServerApplication:HandleRead(): 에코 패킷
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): 1024에서 10.1.1.2바이트를 받았습니다.
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClient응용 프로그램:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
또한 때때로 로그 메시지가 생성되는 시뮬레이션 시간을 볼 수 있는 것이 유용합니다.
생성됩니다. prefix_time 비트에서 OR을 수행하여 이를 수행할 수 있습니다.
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time:
UdpEchoServerApplication=level_all|prefix_func|prefix_time'
다시 말하지만 위의 줄 바꿈을 제거해야 합니다. 지금 스크립트를 실행하면
다음 출력을 참조하십시오.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.418초).
0s UdpEchoServer응용 프로그램:UdpEchoServer()
0s UdpEchoClient응용 프로그램:UdpEchoClient()
0s UdpEchoClient응용 프로그램:데이터 크기 설정(1024)
1초 UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2초 UdpEchoClient응용 프로그램:보내기()
2s UdpEchoClientApplication:Send(): 1024바이트를 10.1.1.2로 보냈습니다.
2.00369s UdpEchoServerApplication:HandleRead(): 1024에서 10.1.1.1바이트 수신됨
2.00369s UdpEchoServerApplication:HandleRead(): 에코 패킷
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): 1024에서 10.1.1.2바이트를 수신했습니다.
10초 UdpEchoServerApplication:StopApplication()
10초 UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClient응용 프로그램:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
시뮬레이션 시간에 UdpEchoServer의 생성자가 호출되었음을 알 수 있습니다.
0초. 이것은 시뮬레이션이 시작되기 전에 실제로 발생하지만 시간은
XNUMX초로 표시됩니다. UdpEchoClient 생성자 메시지도 마찬가지입니다.
리콜 스크래치/first.cc 스크립트는 XNUMX초에 에코 서버 애플리케이션을 시작했습니다.
시뮬레이션에. 이제 응용 프로그램 시작 서버의 방법은,
실제로는 XNUMX초에 호출됩니다. echo 클라이언트 애플리케이션이
스크립트에서 요청한 대로 XNUMX초의 시뮬레이션 시간에 시작되었습니다.
이제 시뮬레이션 진행 상황을 다음에서 확인할 수 있습니다. 일정전송 전화
호출하는 클라이언트 전송 부터 핸들 읽기 에코 서버 애플리케이션의 콜백. 메모
포인트-투-포인트 링크를 통해 전송되는 패킷의 경과 시간은 3.69입니다.
밀리초. 에코 서버가 에코되었음을 알리는 메시지를 기록하는 것을 볼 수 있습니다.
패킷을 수신한 다음 다른 채널 지연 후에 에코 클라이언트가 패킷을 수신하는 것을 볼 수 있습니다.
에코 패킷 핸들 읽기 방법.
이 시뮬레이션에는 당신이 알지 못하는 많은 일들이 숨어 있습니다.
보는 것도. 모든 프로세스를 켜면 전체 프로세스를 매우 쉽게 수행할 수 있습니다.
시스템의 로깅 구성 요소. 설정해 보세요 NS_LOG 다음과 같은 변수,
$ 내보내기 'NS_LOG=*=level_all|prefix_func|prefix_time'
위의 별표는 로깅 구성 요소 와일드카드입니다. 이렇게 하면 모든
시뮬레이션에 사용된 모든 구성 요소를 로그인합니다. 나는 출력을 재현하지 않습니다
여기(이 글을 쓰는 시점에서 단일 패킷 에코에 대해 1265줄의 출력이 생성됨)
이 정보를 파일로 리디렉션하고 즐겨찾는
원하는 경우 편집자,
$ ./waf --스크래치/myfirst 실행 > log.out 2>&1
저는 개인적으로 매우 장황한 로깅 버전을 사용합니다.
문제가 있고 어디에서 문제가 발생하는지 전혀 모릅니다. 의 진행 상황을 따라갈 수 있습니다.
중단점을 설정하지 않고 디버거에서 코드를 단계별로 실행하지 않고도 매우 쉽게 코드를 작성할 수 있습니다.
내가 가장 좋아하는 편집기에서 출력을 편집하고 내가 기대하는 것을 검색할 수 있습니다.
그리고 내가 예상하지 못한 일이 일어나는 것을 봅니다. 무엇인지에 대한 일반적인 생각이 있을 때
문제가 발생하면 문제를 세밀하게 조사하기 위해 디버거로 전환합니다.
이러한 종류의 출력은 스크립트가 어떤 작업을 완전히 수행할 때 특히 유용할 수 있습니다.
예기치 않은. 디버거를 사용하여 스테핑하는 경우 예기치 않은 편위를 놓칠 수 있습니다.
완전히. 소풍을 기록하면 빠르게 볼 수 있습니다.
첨가 로깅 에 your 암호
다음을 통해 로그 구성 요소를 호출하여 시뮬레이션에 새 로깅을 추가할 수 있습니다.
여러 매크로. 에서 그렇게 합시다 myfirst.cc 우리가 가지고 있는 스크립트 할퀴다 디렉토리.
해당 스크립트에서 로깅 구성 요소를 정의했음을 기억하십시오.
NS_LOG_COMPONENT_DEFINE("FirstScriptExample");
이제 다음을 설정하여 이 구성 요소에 대한 모든 로깅을 활성화할 수 있음을 알고 있습니다.
NS_LOG 다양한 수준의 환경 변수. 계속해서 로깅을 추가해 보겠습니다.
대본. 정보 수준 로그 메시지를 추가하는 데 사용되는 매크로는 다음과 같습니다. NS_LOG_INFO. 가기
노드 생성을 시작하기 직전에 스크립트를 추가하십시오.
"토폴로지 작성"입니다. 이것은 이 코드 스니펫에서와 같이 수행됩니다.
엽니다 스크래치/myfirst.cc 좋아하는 편집기에서 줄을 추가하십시오.
NS_LOG_INFO("토폴로지 생성");
줄 바로 앞,
NodeContainer 노드;
노드.만들기(2);
이제 waf를 사용하여 스크립트를 빌드하고 NS_LOG 토렌트를 끄는 변수
이전에 활성화한 로깅:
$ ./와프
$ 내보내기 NS_LOG=
이제 스크립트를 실행하면
$ ./waf --스크래치/myfirst 실행
당신 것입니다 지원 연결된 로깅 구성 요소 이후 새 메시지를 참조하십시오.
(FirstScript예)이 활성화되지 않았습니다. 메시지를 보려면 다음을 수행해야 합니다.
~을 가능하게하다 FirstScript예 이상의 수준을 가진 로깅 구성 요소
NS_LOG_INFO. 이 특정 수준의 로깅만 보고 싶다면 활성화할 수 있습니다.
으로,
$ export NS_LOG=FirstScriptExample=정보
이제 스크립트를 실행하면 새로운 "토폴로지 생성 중" 로그 메시지가 표시됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.404초).
토폴로지 생성
1024바이트를 10.1.1.2로 보냈습니다.
1024에서 10.1.1.1바이트 수신됨
1024에서 10.1.1.2바이트 수신됨
사용 명령 라인 인수
재정의 태만 Attributes
방법을 변경할 수 있는 또 다른 방법 NS-3 스크립트는 편집 없이 동작하며 빌드는 다음을 통해 이루어집니다.
명령 선 인수. 명령줄 인수를 구문 분석하고
해당 인수를 기반으로 로컬 및 전역 변수를 자동으로 설정합니다.
명령줄 인수 시스템을 사용하는 첫 번째 단계는 명령줄을 선언하는 것입니다.
파서. 이는 다음 코드와 같이 매우 간단하게 수행됩니다(기본 프로그램에서).
INT
메인(int argc, char *argv[])
{
...
커맨드라인 cmd;
cmd.Parse(argc, argv);
...
}
이 간단한 두 줄 스니펫은 실제로 그 자체로 매우 유용합니다. 그것은
NS-3 전역 변수 및 속성 시스템. 계속해서 두 줄의 코드를
전에, 스크래치/myfirst.cc 시작 부분의 스크립트 본관. 계속해서 스크립트를 작성하고 실행하십시오.
그러나 다음과 같은 방법으로 스크립트에 도움을 요청하십시오.
$ ./waf --run "scratch/myfirst --PrintHelp"
이것은 Waf에게 스크래치/myfirst 스크립트를 작성하고 명령줄 인수를 전달합니다.
--PrintHelp 스크립트에. 어떤 프로그램이 어떤 프로그램을 가져오는지 분류하려면 따옴표가 필요합니다.
논쟁. 명령줄 파서는 이제 --PrintHelp 논쟁과 응답,
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.413초).
TcpL4프로토콜:TcpStateMachine()
CommandLine:HandleArgument(): 핸들 인수 이름=PrintHelp 값=
--PrintHelp: 이 도움말 메시지를 인쇄합니다.
--PrintGroups: 그룹 목록을 인쇄합니다.
--PrintTypeIds: 모든 TypeId를 인쇄합니다.
--PrintGroup=[그룹]: 그룹의 모든 TypeId를 인쇄합니다.
--PrintAttributes=[typeid]: typeid의 모든 속성을 인쇄합니다.
--PrintGlobals: 전역 목록을 인쇄합니다.
에 집중하자 --인쇄 속성 옵션. 우리는 이미 다음과 같이 암시했습니다. NS-3 속성
걸으면서 시스템 첫 번째.cc 스크립트. 우리는 다음과 같은 줄을 보았습니다.
코드
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("지연", StringValue("2ms"));
그리고 언급했다 데이터 속도 실제로 속성 의 PointToPointNet장치. 하자
명령줄 인수 파서를 사용하여 Attributes 의
PointToPointNetDevice. 도움말 목록에는 다음을 제공해야 한다고 나와 있습니다. 유형 ID. 이
해당 클래스의 클래스 이름에 해당합니다. Attributes 제자리에 있다. 이 경우
그것은 될 것이다. ns3::PointToPointNetDevice. 계속해서 입력해 보겠습니다.
$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"
시스템에서 모든 항목을 인쇄합니다. Attributes 이러한 종류의 넷 장치. 중
Attributes 나열된 것을 볼 수 있습니다.
--ns3::PointToPointNetDevice::DataRate=[32768bps]:
포인트 투 포인트 링크의 기본 데이터 속도
다음을 수행할 때 사용되는 기본값입니다. PointToPointNet장치 에 생성됩니다
체계. 우리는 이 기본값을 속성 설정 포인트투포인트도우미
위에. 점대점 장치 및 채널에 대한 기본값을 다음과 같이 사용하겠습니다.
삭제 SetDevice속성 전화와 SetChannel속성 에서 전화 myfirst.cc
우리는 스크래치 디렉토리에 있습니다.
이제 스크립트는 다음을 선언해야 합니다. 포인트투포인트도우미 그리고 아무것도하지 세트 운영
다음 예에서와 같이
...
NodeContainer 노드;
노드.만들기(2);
PointToPointHelper pointToPoint;
NetDeviceContainer 장치;
장치 = pointToPoint.Install(노드);
...
계속해서 Waf로 새 스크립트를 빌드합니다(./와프) 돌아가서 일부를 활성화하겠습니다.
UDP 에코 서버 애플리케이션에서 로깅하고 시간 접두사를 켭니다.
$ 내보내기 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'
스크립트를 실행하면 이제 다음 출력이 표시됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.405초).
0s UdpEchoServer응용 프로그램:UdpEchoServer()
1초 UdpEchoServerApplication:StartApplication()
1024바이트를 10.1.1.2로 보냈습니다.
2.25732s 1024에서 10.1.1.1바이트 수신
2.25732s 에코 패킷
1024에서 10.1.1.2바이트 수신됨
10초 UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
패킷이 발생한 시뮬레이션 시간을 마지막으로 보았을 때를 상기하십시오.
에코 서버에서 수신한 시간은 2.00369초였습니다.
2.00369s UdpEchoServerApplication:HandleRead(): 1024에서 10.1.1.1바이트 수신됨
이제 2.25732초에 패킷을 수신합니다. 이것은 우리가 방금 떨어뜨렸기 때문입니다.
의 데이터 속도 PointToPointNet장치 초당 기본값인 32768비트로 낮춥니다.
초당 XNUMX메가비트.
우리가 새로운 것을 제공한다면 데이터 속도 명령줄을 사용하여 시뮬레이션 속도를 높일 수 있습니다.
다시 위로. 도움말에 포함된 공식에 따라 다음과 같은 방식으로 이 작업을 수행합니다.
항목 :
$ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"
이렇게 하면 다음의 기본값이 설정됩니다. 데이터 속도 속성 당 XNUMX메가비트로 다시
두번째. 결과에 놀랐습니까? 원본을 얻으려면
스크립트의 동작을 되돌리려면 채널의 빛의 속도 지연을 설정해야 합니다.
또한. 명령줄 시스템에 다음을 인쇄하도록 요청할 수 있습니다. Attributes 채널의
우리가 net 장치에 대해 했던 것처럼:
$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel"
우리는 발견 Delay 속성 채널의 설정은 다음과 같이 설정됩니다.
--ns3::PointToPointChannel::지연=[0ns]:
채널을 통한 전송 지연
그런 다음 명령줄 시스템을 통해 이러한 기본값을 모두 설정할 수 있습니다.
$ ./waf --실행 "스크래치/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::지연=2ms"
이 경우 명시적으로 설정했을 때의 타이밍을 복구합니다. 데이터 속도 and Delay
스크립트에서 :
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.417초).
0s UdpEchoServer응용 프로그램:UdpEchoServer()
1초 UdpEchoServerApplication:StartApplication()
1024바이트를 10.1.1.2로 보냈습니다.
2.00369s 1024에서 10.1.1.1바이트 수신
2.00369s 에코 패킷
1024에서 10.1.1.2바이트 수신됨
10초 UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
패킷은 2.00369초에 서버에서 다시 수신됩니다. 우리는 할 수
실제로 설정 Attributes 이런 식으로 스크립트에서 사용됩니다. 특히 우리는 할 수 있습니다
설정 UDPEcho클라이언트 속성 최대 패킷 XNUMX이 아닌 다른 값으로.
어떻게 하시겠습니까? 시도 해봐. 장소를 주석 처리해야 함을 기억하십시오.
우리는 기본값을 재정의합니다 속성 그리고 명시적으로 설정 최대 패킷 스크립트에서. 그럼 너
스크립트를 다시 작성해야 합니다. 또한 실제로 설정하기 위한 구문을 찾아야 합니다.
명령줄 도움말 기능을 사용하여 새 기본 속성 값. 일단 이것만 있으면
명령에서 반향되는 패킷 수를 제어할 수 있어야 한다는 것을 알아냈습니다.
선. 우리는 좋은 사람들이기 때문에 명령줄이
같은 것,
$ ./waf --실행 "스크래치/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::지연=2ms
--ns3::UdpEchoClient::MaxPackets=2"
후킹 너의 소유 마케팅은:
명령줄 시스템에 고유한 후크를 추가할 수도 있습니다. 이것은 매우 간단하게 수행됩니다.
를 사용하여 값을 추가 명령줄 파서에 대한 메서드입니다.
이 기능을 사용하여 완전히 다른 환경에서 에코할 패킷 수를 지정해 보겠습니다.
방법. 라는 지역 변수를 추가해 보겠습니다. n패킷 부터 본관 기능. 초기화 하겠습니다
이전 기본 동작과 일치하도록 XNUMX로 변경합니다. 명령줄 파서가
이 값을 변경하려면 값을 파서에 연결해야 합니다. 호출을 추가하여 이를 수행합니다.
에 값을 추가. 계속해서 다음을 변경하십시오. 스크래치/myfirst.cc 로 시작하는 스크립트
다음 코드,
INT
메인(int argc, char *argv[])
{
uint32_t nPackets = 1;
커맨드라인 cmd;
cmd.AddValue("nPackets", "반향할 패킷 수", nPackets);
cmd.Parse(argc, argv);
...
스크립트에서 설정한 지점까지 아래로 스크롤합니다. 최대 패킷 속성 변경
변수로 설정되도록 n패킷 상수 대신 1 아래에 표시된 것처럼.
echoClient.SetAttribute("MaxPackets", UintegerValue(nPackets));
이제 스크립트를 실행하고 --PrintHelp 논쟁, 당신은 당신의 새로운
사용자 논의 도움말 표시에 나열됩니다.
시험,
$ ./waf --run "scratch/myfirst --PrintHelp"
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.403초).
--PrintHelp: 이 도움말 메시지를 인쇄합니다.
--PrintGroups: 그룹 목록을 인쇄합니다.
--PrintTypeIds: 모든 TypeId를 인쇄합니다.
--PrintGroup=[그룹]: 그룹의 모든 TypeId를 인쇄합니다.
--PrintAttributes=[typeid]: typeid의 모든 속성을 인쇄합니다.
--PrintGlobals: 전역 목록을 인쇄합니다.
사용자 인수:
--nPackets: 에코할 패킷 수
에코할 패킷 수를 지정하려면 이제
--n패킷 명령줄의 인수,
$ ./waf --run "scratch/myfirst --nPackets=2"
너는 지금보아야한다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.404초).
0s UdpEchoServer응용 프로그램:UdpEchoServer()
1초 UdpEchoServerApplication:StartApplication()
1024바이트를 10.1.1.2로 보냈습니다.
2.25732s 1024에서 10.1.1.1바이트 수신
2.25732s 에코 패킷
1024에서 10.1.1.2바이트 수신됨
1024바이트를 10.1.1.2로 보냈습니다.
3.25732s 1024에서 10.1.1.1바이트 수신
3.25732s 에코 패킷
1024에서 10.1.1.2바이트 수신됨
10초 UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
이제 두 개의 패킷을 에코했습니다. 꽤 쉽지 않나요?
당신은 당신이 인 경우에 그것을 볼 수 있습니다 NS-3 사용자는 명령줄 인수 시스템을 사용하여 다음을 수행할 수 있습니다.
글로벌 가치를 제어하고 Attributes. 모델 작성자인 경우 새 항목을 추가할 수 있습니다.
Attributes 너의 ~에게 사물 사용자가 자동으로 설정할 수 있습니다.
명령줄 시스템을 통해 사용자. 스크립트 작성자인 경우 새 항목을 추가할 수 있습니다.
스크립트에 변수를 추가하고 아주 쉽게 명령줄 시스템에 연결합니다.
사용 전에, 트레이싱
시뮬레이션의 요점은 추가 연구를 위한 출력을 생성하는 것입니다. NS-3
추적 시스템은 이를 위한 기본 메커니즘입니다. 부터 NS-3 C++ 프로그램, 표준
C++ 프로그램에서 출력을 생성하는 기능을 사용할 수 있습니다.
#포함
...
정수 메인()
{
...
std::cout << "x의 값은 " << x << std::endl;
...
}
로깅 모듈을 사용하여 솔루션에 약간의 구조를 추가할 수도 있습니다. 거기
그러한 접근법에 의해 생성된 많은 잘 알려진 문제이므로 우리는 다음을 제공했습니다.
우리가 중요하다고 생각한 문제를 해결하기 위한 일반 이벤트 추적 하위 시스템.
의 기본 목표 NS-3 추적 시스템은 다음과 같습니다.
· 기본 작업의 경우 추적 시스템에서 사용자가 표준 추적을 생성할 수 있어야 합니다.
널리 사용되는 추적 소스에 대해 추적을 생성하는 개체를 사용자 지정합니다.
· 중급 사용자는 추적 시스템을 확장하여 출력 형식을 수정할 수 있어야 합니다.
의 핵심을 수정하지 않고 생성하거나 새 추적 소스를 삽입합니다.
모의 실험 장치;
· 고급 사용자는 시뮬레이터 코어를 수정하여 새로운 추적 소스 및 싱크를 추가할 수 있습니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 추적 시스템은 독립적인 추적 소스 및
추적 싱크, 소스를 싱크에 연결하기 위한 균일한 메커니즘. 추적 소스는
시뮬레이션에서 발생하는 이벤트에 신호를 보내고 액세스를 제공할 수 있는 엔터티
흥미로운 기본 데이터. 예를 들어 추적 소스는 패킷이
네트워크 장치에서 수신하고 관심 있는 추적을 위해 패킷 내용에 대한 액세스를 제공합니다.
싱크대.
추적 소스는 그 자체로는 유용하지 않으며 다른 부분에 "연결"되어야 합니다.
싱크에서 제공하는 정보로 실제로 유용한 작업을 수행하는 코드입니다. 추적하다
싱크는 추적 소스에서 제공하는 이벤트 및 데이터의 소비자입니다. 예를 들어,
트레이스 싱크를 생성할 수 있습니다.
이전 예) 수신된 패킷의 흥미로운 부분을 인쇄합니다.
이렇게 명시적으로 구분하는 이유는 사용자가 새로운 유형의 싱크를
핵심을 편집하고 재컴파일할 필요 없이 기존 추적 소스
모의 실험 장치. 따라서 위의 예에서 사용자는 자신의 새 추적 싱크를 정의할 수 있습니다.
스크립트를 작성하고 이를 시뮬레이션 코어에 정의된 기존 추적 소스에 첨부합니다.
사용자 스크립트만 편집합니다.
이 자습서에서는 사전 정의된 일부 소스 및 싱크를 살펴보고 방법을 보여줍니다.
약간의 사용자 노력으로 사용자 정의할 수 있습니다. ns-3 설명서 또는 방법 섹션을 참조하십시오.
추적 확장을 포함한 고급 추적 구성에 대한 정보는
네임스페이스 및 새 추적 소스 만들기.
ASCII 트레이싱
NS-3 하위 수준 추적 시스템을 래핑하는 도우미 기능을 제공하여
쉽게 이해할 수 있는 일부 패킷 추적 구성과 관련된 세부 정보가 포함됩니다. 만약 너라면
이 기능을 활성화하면 ASCII 파일 --- 이름으로 출력이 표시됩니다. 을 위한
익숙한 사람들 NS-2 출력, 이 유형의 추적은 out.tr 생성
많은 스크립트로.
바로 뛰어들어 일부 ASCII 추적 출력을 스크래치/myfirst.cc
스크립트. 호출 직전 시뮬레이터::실행 (), 다음 코드 줄을 추가합니다.
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll(ascii.CreateFileStream("myfirst.tr"));
다른 많은 것들처럼 NS-3 관용구, 이 코드는 도우미 객체를 사용하여 ASCII 생성을 돕습니다.
흔적. 두 번째 줄에는 두 개의 중첩된 메서드 호출이 포함되어 있습니다. "내부" 방법,
생성파일스트림() 명명되지 않은 객체 관용구를 사용하여
스택(객체 이름 없음)을 호출한 메서드로 전달합니다. 우리는 이것에 들어갈 것입니다
앞으로는 더 많겠지만 지금 시점에서 알아야 할 것은
"myfirst.tr"이라는 파일을 나타내는 객체 NS-3. 당신은 말하고있다
NS-3 생성된 개체의 수명 문제를 처리하고 문제를 처리하기 위해
복사와 관련된 스트림 개체의 C++에 대한 잘 알려지지 않은(의도적인) 제한으로 인해 발생합니다.
생성자.
외부 전화, AsciiAll 활성화(), 헬퍼에게 ASCII를 활성화하고 싶다고 알립니다.
시뮬레이션의 모든 점대점 장치에 대한 추적 그리고 당신은 (제공된)
패킷 이동에 대한 정보를 ASCII 형식으로 기록하는 추적 싱크.
익숙한 사람들을 위해 NS-2, 추적된 이벤트는 널리 사용되는 추적 지점과 동일합니다.
"+", "-", "d" 및 "r" 이벤트를 기록합니다.
이제 스크립트를 빌드하고 명령줄에서 실행할 수 있습니다.
$ ./waf --스크래치/myfirst 실행
이전에 여러 번 본 것처럼 Waf에서 메시지가 표시되고
실행 중인 프로그램에서 일부 메시지와 함께 "'빌드'가 성공적으로 완료되었습니다."
프로그램이 실행될 때 프로그램은 이름이 지정된 파일을 생성합니다. myfirst.tr. 방법 때문에
Waf가 작동하면 파일이 로컬 디렉토리에 생성되지 않고 다음 위치에 생성됩니다.
기본적으로 저장소의 최상위 디렉토리. 추적 위치를 제어하려면
저장하면 다음을 사용할 수 있습니다. --cwd 이것을 지정하기 위한 Waf의 옵션. 우리는 그렇게 하지 않았으므로
저장소의 최상위 디렉토리로 변경하고 ASCII를 살펴봐야 합니다.
추적 파일 myfirst.tr 좋아하는 편집기에서.
파싱 아스키 추적
거기에는 꽤 조밀한 형태로 많은 정보가 있지만, 가장 먼저 알아차려야 할 것은
이 파일에는 별개의 줄이 많이 있다는 것입니다. 보기 어려울 수 있습니다
당신이 당신의 창을 상당히 넓히지 않는 한 이것은 분명합니다.
파일의 각 라인은 더듬다 event. 이 경우 이벤트를 추적하고 있습니다.
전에, 부치다 변발 시뮬레이션의 모든 점대점 네트 장치에 존재합니다. 그만큼
전송 대기열은 지점간 채널로 향하는 모든 패킷이 통과하는 대기열입니다.
통과해야 합니다. 추적 파일의 각 라인은 단일 문자로 시작합니다(
그 뒤에 공백). 이 문자는 다음과 같은 의미를 갖습니다.
· +: 장치 대기열에서 대기열에 넣기 작업이 발생했습니다.
· -: 장치 대기열에서 대기열 제거 작업이 발생했습니다.
· d: 일반적으로 대기열이 가득 차서 패킷이 삭제되었습니다.
· r: 네트워크 장치에서 패킷을 수신했습니다.
추적 파일의 첫 번째 줄을 좀 더 자세히 살펴보겠습니다. 내가 부숴버릴게
왼쪽에 참조 번호가 있는 섹션으로 구분(명확성을 위해 들여쓰기):
+
2
/NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/인큐
ns3::Ppp헤더(
점대점 프로토콜: IP(0x0021))
ns3::Ipv4헤더(
tos 0x0 ttl 64 id 0 프로토콜 17 오프셋 0 플래그 [없음]
길이: 1052 10.1.1.1 > 10.1.1.2)
ns3::UDp헤더(
길이: 1032 49153 > 9)
페이로드(크기=1024)
이 확장된 추적 이벤트(참조 번호 0)의 첫 번째 섹션은 작업입니다. 우리
이 + 문자이므로 이것은 대기열에 넣다 전송 대기열에 대한 작업.
두 번째 섹션(참조 1)은 초 단위로 표현된 시뮬레이션 시간입니다. 당신은 할 수있다
우리가 UdpEchoClient응용 프로그램 XNUMX초에 패킷 전송을 시작합니다.
여기서 우리는 이것이 실제로 일어나고 있다는 확인을 봅니다.
예제 트레이스(참조 2)의 다음 섹션은 어떤 트레이스 소스가 생성되었는지 알려줍니다.
이 이벤트(추적 네임스페이스로 표현됨). 추적 네임스페이스를 생각할 수 있습니다.
파일 시스템 이름 공간과 비슷합니다. 네임스페이스의 루트는
노드 목록. 이것은 다음에서 관리되는 컨테이너에 해당합니다. NS-3 모두 포함하는 핵심 코드
스크립트에서 생성된 노드의 파일 시스템에 디렉토리가 있는 것처럼
루트 아래에 노드 번호가 있을 수 있습니다. 노드 목록. 문자열 /노드리스트/0
따라서 XNUMX번째 노드를 참조합니다. 노드 목록 일반적으로 "노드"라고 생각하는
0". 각 노드에는 설치된 장치 목록이 있습니다. 이 목록이 나타납니다.
네임스페이스의 다음. 이 추적 이벤트가 장치 목록/0 하는 것입니다
노드에 설치된 XNUMX번째 장치.
다음 문자열, $ns3::PointToPointNetDevice 어떤 종류의 장치가 있는지 알려줍니다.
노드 XNUMX에 대한 장치 목록의 XNUMX번째 위치. 작업을 기억하십시오. + 에서 발견
참조 00은 대기열에 넣기 작업이 장치의 전송 대기열에서 발생했음을 의미합니다.
이는 "추적 경로"의 마지막 세그먼트에 반영됩니다. TxQueue/인큐.
추적의 나머지 섹션은 상당히 직관적이어야 합니다. 참조 3-4는 다음을 나타냅니다.
패킷이 점대점 프로토콜로 캡슐화됩니다. 참고 문헌 5-7은
패킷에는 IP 버전 10.1.1.1 헤더가 있고 IP 주소 XNUMX에서 시작되었으며
10.1.1.2로 예정되어 있습니다. 참조 8-9는 이 패킷이 UDP 헤더를 가지고 있음을 보여줍니다.
마지막으로 참조 10은 페이로드가 예상되는 1024바이트임을 보여줍니다.
추적 파일의 다음 줄은 동일한 패킷이 전송에서 대기열에서 제외되는 것을 보여줍니다.
같은 노드에서 대기합니다.
추적 파일의 세 번째 줄은 네트워크 장치에서 수신되는 패킷을 보여줍니다.
에코 서버가 있는 노드. 아래에 해당 이벤트를 재현했습니다.
r
2.25732
/NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
ns3::Ipv4헤더(
tos 0x0 ttl 64 id 0 프로토콜 17 오프셋 0 플래그 [없음]
길이: 1052 10.1.1.1 > 10.1.1.2)
ns3::UDp헤더(
길이: 1032 49153 > 9)
페이로드(크기=1024)
추적 작업이 이제 r 시뮬레이션 시간이 2.25732로 증가했습니다.
초. 자습서 단계를 자세히 따라왔다면 이는 다음을 의미합니다.
~를 남겨 놓다 데이터 속도 네트워크 장치 및 채널 Delay 기본값으로 설정합니다.
이 시간은 이전 섹션에서 이전에 본 것처럼 친숙해야 합니다.
추적 소스 네임스페이스 항목(참조 02)이 이 이벤트가
노드 1(/노드리스트/1) 및 패킷 수신 추적 소스(/MacRx). 그것
다음을 통해 토폴로지를 통해 패킷의 진행 상황을 쉽게 따라갈 수 있어야 합니다.
파일의 나머지 추적을 살펴봅니다.
PCAP 트레이싱
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 장치 헬퍼는 또한 추적 파일을 생성하는 데 사용할 수 있습니다. .pcap 체재. 그만큼
약어 pcap(일반적으로 소문자로 작성됨)은 패킷 캡처를 의미하며 실제로는
의 정의를 포함하는 API .pcap 파일 형식. 가장 인기있는 프로그램은
이 형식을 읽고 표시할 수 있는 것은 Wireshark(이전에는 Ethereal이라고 함)입니다. 그러나 거기에
이 패킷 형식을 사용하는 많은 트래픽 추적 분석기입니다. 우리는 사용자가
pcap 추적을 분석하는 데 사용할 수 있는 많은 도구를 활용하십시오. 이 튜토리얼에서 우리는
tcpdump로 pcap 추적을 보는 데 집중하십시오.
pcap 추적을 활성화하는 데 사용되는 코드는 한 줄입니다.
pointToPoint.EnablePcapAll("myfirst");
방금 추가한 ASCII 추적 코드 뒤에 이 코드 줄을 삽입하십시오.
스크래치/myfirst.cc. "myfirst"라는 문자열만 전달했고
"myfirst.pcap" 또는 이와 유사한 것. 이는 매개변수가 접두사가 아니라 접두사이기 때문입니다.
완전한 파일 이름. 도우미는 실제로 모든 지점 간 추적 파일을 만듭니다.
시뮬레이션 장치. 파일 이름은 접두사, 노드 번호,
장치 번호 및 ".pcap" 접미사.
예제 스크립트에서 결국 "myfirst-0-0.pcap"이라는 파일이 표시되고
노드 1-장치 0 및 노드 0-장치 0에 대한 pcap 추적인 "myfirst-1-0.pcap",
각각.
pcap 추적을 활성화하는 코드 줄을 추가하면 다음에서 스크립트를 실행할 수 있습니다.
일반적인 방법:
$ ./waf --스크래치/myfirst 실행
배포판의 최상위 디렉토리를 보면 이제 세 개의 로그가 표시됩니다.
파일 : myfirst.tr 이전에 조사한 ASCII 추적 파일입니다. myfirst-0-0.pcap
and myfirst-1-0.pcap 방금 생성한 새 pcap 파일입니다.
읽기 출력 과 TCP 덤프
이 시점에서 할 수 있는 가장 쉬운 일은 다음을 사용하는 것입니다. TCP 덤프 ~을 보다 pcap 파일.
$ tcpdump -nn -tt -r myfirst-0-0.pcap
파일 myfirst-0-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, 길이 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, 길이 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
파일 myfirst-1-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, 길이 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, 길이 1024
의 덤프에서 볼 수 있습니다. myfirst-0-0.pcap (클라이언트 장치) 에코 패킷은
시뮬레이션으로 2초에 전송됩니다. 두 번째 덤프(myfirst-1-0.pcap)
2.257324초에 패킷이 수신되는 것을 볼 수 있습니다. 당신은 패킷이
두 번째 덤프에서 2.257324초에 다시 에코되고 마지막으로 패킷이
2.514648초에 첫 번째 덤프에서 클라이언트에서 다시 수신되었습니다.
읽기 출력 과 와이어 샤크
Wireshark에 익숙하지 않은 경우 다음을 수행할 수 있는 웹 사이트가 있습니다.
프로그램 및 문서 다운로드: http://www.wireshark.org/.
Wireshark는 이러한 추적을 표시하는 데 사용할 수 있는 그래픽 사용자 인터페이스입니다.
파일. Wireshark를 사용할 수 있는 경우 각 추적 파일을 열고 표시할 수 있습니다.
를 사용하여 패킷을 캡처한 것처럼 내용을 패킷 손수건.
건물 토폴로지
건물 a 버스 네트워크 토폴로지
이 섹션에서 우리는 NS-3 네트워크 장치 및 채널
버스 네트워크의 예를 다룹니다. NS-3 우리가 CSMA라고 부르는 네트 장치와 채널을 제공합니다.
(캐리어 감지 다중 접속).
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 CSMA 장치는 이더넷 정신으로 단순한 네트워크를 모델링합니다. 진정한 이더넷
CSMA/CD(Carrier Sense Multiple Access with Collision Detection) 방식을 사용하여
공유 전송 매체를 놓고 경쟁하기 위해 기하급수적으로 증가하는 백오프. 그만큼 NS-3
CSMA 장치 및 채널 모델은 이것의 하위 집합일 뿐입니다.
구성할 때 점대점 토폴로지 도우미 개체를 본 것처럼
점대점 토폴로지의 경우 이 섹션에서 동등한 CSMA 토폴로지 도우미를 볼 수 있습니다.
이러한 도우미의 모양과 작동은 매우 친숙해 보일 것입니다.
examples/tutorial} 디렉터리에 예제 스크립트를 제공합니다. 이 스크립트는
전에, 첫 번째.cc 스크립트를 작성하고 CSMA 네트워크를 점대점 시뮬레이션에 추가합니다.
존경받는. 계속해서 열기 예제/튜토리얼/second.cc 좋아하는 편집기에서. 너
이미 충분히 보았을 것이다 NS-3 이 코드에서 진행되는 대부분의 작업을 이해하는 코드
하지만 우리는 전체 스크립트를 살펴보고 일부 출력을 검사할 것입니다.
에서와 같이 첫 번째.cc 예(및 모든 ns-3 예에서) 파일은 emacs로 시작합니다.
모드 라인과 일부 GPL 상용구.
실제 코드는 모듈 포함 파일을 로드하는 것으로 시작합니다. 첫 번째.cc
예.
#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"
놀랍게도 유용할 수 있는 한 가지는 만화를 보여주는 약간의 ASCII 아트입니다.
예제에서 구성한 네트워크 토폴로지의 에서 유사한 "그림"을 찾을 수 있습니다.
우리의 예의 대부분.
이 경우 점대점 예제를 확장할 것임을 알 수 있습니다(링크
아래의 노드 n0과 n1 사이) 오른쪽에서 버스 네트워크를 끊습니다. 알아채다
실제로 노드 수를 변경할 수 있으므로 이것이 기본 네트워크 토폴로지입니다.
LAN에서 생성됩니다. nCsma를 XNUMX로 설정하면 nCsma에 총 XNUMX개의 노드가 있게 됩니다.
LAN(CSMA 채널) --- 하나의 필수 노드와 하나의 "추가" 노드. 기본적으로 세 가지
아래와 같이 "추가" 노드:
// 기본 네트워크 토폴로지
//
// 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// 점대점 | | | |
// ================
// 랜 10.1.2.0
그러면 ns-3 네임스페이스는 익숙한 로깅 구성 요소가 정의됩니다. 이것은 모두
에 있었다 첫 번째.cc, 아직 새로운 것이 없습니다.
네임스페이스 ns3 사용;
NS_LOG_COMPONENT_DEFINE("SecondScriptExample");
메인 프로그램은 약간 다른 방식으로 시작됩니다. 자세한 정보 표시 플래그를 사용하여
여부를 결정합니다. UdpEchoClient응용 프로그램 and UdpEchoServer응용 프로그램 로깅
구성 요소가 활성화됩니다. 이 플래그의 기본값은 true입니다(로깅 구성 요소가 활성화됨).
하지만 이 예제의 회귀 테스트 중에 로깅을 끌 수 있습니다.
장치의 수를 변경할 수 있는 몇 가지 친숙한 코드가 표시됩니다.
명령줄 인수를 통한 CSMA 네트워크. 우리는
명령줄 인수 섹션에서 변경하기 위해 보낸 패킷 수. 마지막
라인은 최소한 하나의 "추가" 노드가 있는지 확인합니다.
코드는 이전에 다룬 API의 변형으로 구성되어 있으므로 완전히
튜토리얼의 이 시점에서 다음 코드에 익숙합니다.
부울 상세 정보 = 참;
uint32_t nCsma = 3;
커맨드라인 cmd;
cmd.AddValue ("nCsma", "\"extra\" CSMA 노드/장치 수", nCsma);
cmd.AddValue ("verbose", "참일 경우 로그하도록 echo 응용 프로그램에 지시", verbose);
cmd.Parse(argc, argv);
if(상세)
{
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
nCsma = nCsma == 0 ? 1: nCsma;
다음 단계는 지점 간 링크를 통해 연결할 두 개의 노드를 만드는 것입니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 노드컨테이너 에서 수행한 것처럼 이 작업을 수행하는 데 사용됩니다. 첫 번째.cc.
NodeContainer p2pNodes;
p2pNodes.Create(2);
다음으로 다른 선언 노드컨테이너 버스의 일부가 될 노드를 유지하기 위해
(CSMA) 네트워크. 먼저 컨테이너 개체 자체를 인스턴스화합니다.
NodeContainer csmaNodes;
csmaNodes.Add(p2pNodes.Get(1));
csmaNodes.만들기(nCsma);
다음 코드 줄 가져옵니다. 첫 번째 노드(인덱스가 XNUMX인 경우)
점대점 노드 컨테이너 및 CSMA를 가져올 노드의 컨테이너에 추가
장치. 문제의 노드는 점대점 장치로 끝날 것입니다. and CSMA
장치. 그런 다음 나머지 CSMA를 구성하는 여러 "추가" 노드를 만듭니다.
회로망. CSMA 네트워크에 이미 하나의 노드가 있으므로
점대점 및 CSMA 네트워크 장치 모두에서 "추가" 노드의 수는
CSMA 섹션에서 원하는 노드에서 XNUMX을 뺀 값입니다.
다음 코드는 이제 꽤 익숙할 것입니다. 우리는 포인트투포인트도우미
관련 기본값을 설정합니다. Attributes 초당 XNUMX메가비트를 생성하도록
도우미를 사용하여 만든 장치의 송신기 및 채널의 XNUMX밀리초 지연
도우미에 의해 생성됩니다.
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("지연", StringValue("2ms"));
NetDeviceContainer p2p장치;
p2pDevices = pointToPoint.Install(p2pNodes);
그런 다음 NetDevice컨테이너 점대점 네트 장치를 추적하기 위해
그리고 우리 설치 지점 간 노드의 장치.
CSMA 장치 및 채널에 대한 도우미를 보게 될 것이라고 위에서 언급했습니다.
다음 줄에서 그것들을 소개합니다. 그만큼 CsmaHelper 처럼 작동 포인트투포인트도우미하지만,
CSMA 장치 및 채널을 생성하고 연결합니다. CSMA 장치의 경우
채널 쌍에서 데이터 속도는 채널 속성 대신에
장치 속성. 실제 CSMA 네트워크는 혼합을 허용하지 않기 때문입니다.
예를 들어, 주어진 채널의 10Base-T 및 100Base-T 장치. 먼저 데이터 속도를 다음으로 설정했습니다.
초당 100메가비트, 채널의 광속 지연을 6560으로 설정
나노초(1미터 세그먼트에서 피트당 100나노초로 임의로 선택됨).
다음을 설정할 수 있습니다. 속성 기본 데이터 유형을 사용합니다.
CsmaHelper csma;
csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
csma.SetChannelAttribute("지연", TimeValue(NanoSeconds(6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install(csmaNodes);
우리가 만든 것처럼 NetDevice컨테이너 에 의해 생성된 장치를 유지하기 위해
포인트투포인트도우미 우리는 NetDevice컨테이너 우리가 만든 장치를 보관하기 위해
CsmaHelper. 우리는 설치 방법 CsmaHelper 에 장치를 설치하려면
의 노드 csma노드 노드컨테이너.
이제 노드, 장치 및 채널이 생성되었지만 프로토콜 스택이 없습니다.
현재의. 에서와 같이 첫 번째.cc 스크립트, 우리는 인터넷스택헬퍼 설치하기 위해서
이 스택.
InternetStackHelper 스택;
stack.Install(p2pNodes.Get(0));
stack.Install(csmaNodes);
우리가 노드 중 하나를 p2p노드 컨테이너에 추가했습니다.
csma노드 컨테이너. 따라서 나머지 스택에만 스택을 설치하면 됩니다. p2p노드
노드 및 모든 노드 csma노드 모든 노드를 포함하는 컨테이너
시뮬레이션.
에서와 같이 첫 번째.cc 예제 스크립트에서 우리는 IPv4AddressHelper 에
장치 인터페이스에 IP 주소를 할당합니다. 먼저 네트워크 10.1.1.0을 사용하여 생성합니다.
두 개의 지점 간 장치에 필요한 두 개의 주소.
Ipv4AddressHelper 주소;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2p인터페이스;
p2pInterfaces = address.Assign(p2pDevices);
쉽게 꺼낼 수 있도록 생성된 인터페이스를 컨테이너에 저장합니다.
나중에 응용 프로그램을 설정하는 데 사용할 정보를 주소 지정합니다.
이제 CSMA 장치 인터페이스에 IP 주소를 할당해야 합니다. 작업이 작동합니다.
point-to-point의 경우와 마찬가지로 지금은
가변 개수의 CSMA 장치가 있는 컨테이너 ---
명령줄 인수로 CSMA 장치를 변경할 수 있습니다. CSMA 장치가 연결됩니다.
이 경우 아래와 같이 네트워크 번호 10.1.2.0의 IP 주소를 사용합니다.
address.SetBase("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = 주소.할당(csmaDevices);
이제 토폴로지가 구축되었지만 애플리케이션이 필요합니다. 이 섹션은
기본적으로 애플리케이션 섹션과 유사합니다. 첫 번째.cc 하지만 우리는
CSMA 장치와 클라이언트가 있는 노드 중 하나에서 서버를 인스턴스화합니다.
점대점 장치만 있는 노드.
먼저 에코 서버를 설정합니다. 우리는 UdpEchoServer도우미 그리고 필수 제공
속성 서버 포트 번호인 생성자에 대한 값입니다. 이 포트를 기억하십시오.
를 사용하여 나중에 변경할 수 있습니다. 속성 설정 원하는 경우 방법이지만
생성자에게 제공됩니다.
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma));
serverApps.Start(초(1.0));
serverApps.Stop(초(10.0));
리콜 csma노드 노드컨테이너 위해 생성된 노드 중 하나를 포함합니다.
점대점 네트워크 및 nCsma "추가" 노드. 우리가 얻고자 하는 것은 마지막
"추가" 노드. XNUMX번째 항목 csma노드 컨테이너는 지점 간
마디. 이를 쉽게 생각하는 방법은 하나의 "추가" CSMA 노드를 생성하면
다음 중 하나의 인덱스에 있을 것입니다. csma노드 컨테이너. 유도에 의해, 우리가 만들면 nCsma "추가의"
마지막 노드는 인덱스에 있을 노드 nCsma. 에 전시된 것을 볼 수 있습니다. 돈을 받아가세요 첫 번째의
코드 줄.
클라이언트 애플리케이션은 첫 번째.cc 예제 스크립트. 다시,
우리는 필수를 제공합니다 Attributes 부터 UdpEchoClient도우미 생성자에서(이 경우
원격 주소 및 포트). 우리는 클라이언트에게 서버로 패킷을 보내라고 지시합니다.
마지막 "추가" CSMA 노드에 설치됩니다. 가장 왼쪽에 클라이언트를 설치합니다.
토폴로지 그림에 표시된 점대점 노드.
UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue (1));
echoClient.SetAttribute("간격", TimeValue(초(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));
ApplicationContainer clientApps = echoClient.Install(p2pNodes.Get(0));
clientApps.Start(초(2.0));
clientApps.Stop(초(10.0));
실제로 여기에 인터네트워크를 구축했기 때문에 어떤 형태의 인터네트워크가 필요합니다.
라우팅. NS-3 귀하를 돕기 위해 우리가 글로벌 라우팅이라고 부르는 것을 제공합니다. 글로벌 라우팅 테이크
시뮬레이션에서 전체 인터네트워크에 액세스할 수 있다는 사실의 이점과
시뮬레이션을 위해 생성된 모든 노드를 통해 실행 --- 어려운 작업을 수행합니다.
라우터를 구성하지 않고도 라우팅을 설정할 수 있습니다.
기본적으로 발생하는 일은 각 노드가 OSPF 라우터인 것처럼 동작하여 다음을 수행하는 것입니다.
무대 뒤의 다른 모든 라우터와 즉각적이고 마술처럼 통신합니다. 각 노드
링크 광고를 생성하고 이를 글로벌 경로 관리자에게 직접 전달합니다.
이 전역 정보를 사용하여 각 노드에 대한 라우팅 테이블을 구성합니다. 환경
이 형식의 라우팅은 한 줄짜리입니다.
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
다음으로 pcap 추적을 활성화합니다. pcap 추적을 활성화하는 첫 번째 코드 줄은
point-to-point 도우미는 이제 익숙할 것입니다. 두 번째 줄은 pcap을 활성화합니다.
CSMA 헬퍼에서 추적하고 아직 만나지 못한 추가 매개변수가 있습니다.
pointToPoint.EnablePcapAll("초");
csma.EnablePcap("초", csmaDevices.Get(1), true);
CSMA 네트워크는 다지점 간 네트워크입니다. 이것은 할 수 있음을 의미합니다.
이 경우) 공유 매체의 여러 끝점. 이러한 각 끝점에는 네트워크가 있습니다.
그것과 관련된 장치. 추적 수집에 대한 두 가지 기본 대안이 있습니다.
그러한 네트워크의 정보. 한 가지 방법은 각 네트 장치에 대한 추적 파일을 만드는 것입니다.
해당 네트 장치에서 내보내거나 소비하는 패킷만 저장합니다. 또 다른 방법
장치 중 하나를 선택하여 무차별 모드로 설정하는 것입니다. 그러면 그 단일 장치
모든 패킷에 대해 네트워크를 "스니핑"하고 단일 pcap 파일에 저장합니다. 이것이 방법입니다
TCP 덤프, 예를 들어 작동합니다. 이 마지막 매개변수는 CSMA 헬퍼에게 다음 여부를 알려줍니다.
무차별 모드에서 패킷을 캡처하도록 조정합니다.
이 예에서는 CSMA 네트워크에 있는 장치 중 하나를 선택하고 물어볼 것입니다.
네트워크의 난잡한 스니핑을 수행하여 무엇을 에뮬레이션합니다. TCP 덤프 할것이다.
Linux 시스템을 사용 중이라면 다음과 같이 할 수 있습니다. TCP 덤프 -i eth0 ~을 얻기 위해
추적하다. 이 경우 다음을 사용하여 장치를 지정합니다. csmaDevices.Get(1), 선택하는
컨테이너의 첫 번째 장치. 마지막 매개변수를 true로 설정하면 무차별
캡처.
코드의 마지막 섹션은 다음과 같이 시뮬레이션을 실행하고 정리합니다. 첫 번째.cc
예.
시뮬레이터::실행();
시뮬레이터::파괴();
0가 돌아;
}
이 예제를 실행하려면 초.cc 스크래치 디렉토리에 예제 스크립트
waf를 사용하여 첫 번째.cc 예. 당신이에있는 경우
방금 입력한 저장소의 최상위 디렉토리,
$ cp 예제/튜토리얼/second.cc 스크래치/mysecond.cc
$ ./와프
경고: 우리는 파일을 사용합니다 초.cc 작동하는지 확인하기 위한 회귀 테스트 중 하나로
튜토리얼 경험을 긍정적으로 만들기 위해 우리가 생각하는 것과 정확히 일치합니다.
이것은 이름이 지정된 실행 파일을 의미합니다. 초 프로젝트에 이미 존재합니다. 피하려면
당신이 실행하고 있는 것에 대해 혼란이 있다면, 다음으로 이름을 바꾸십시오. mysecond.cc 추천
위.
당신이 튜토리얼을 종교적으로 따르고 있다면(당신은 그렇지 않습니까) 여전히 당신은
NS_LOG 변수가 설정되었으므로 해당 변수를 지우고 프로그램을 실행하십시오.
$ 내보내기 NS_LOG=
$ ./waf --스크래치/mysecond 실행
UDP 에코 애플리케이션을 설정한 이후로 첫 번째.cc, 그럴거야
스크립트를 실행할 때 유사한 출력이 표시됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.415초).
1024바이트를 10.1.2.4로 보냈습니다.
1024에서 10.1.1.1바이트 수신됨
1024에서 10.1.2.4바이트 수신됨
첫 번째 메시지인 "보낸 1024 바이트 에 10.1.2.4,"는 UDP 에코 클라이언트입니다.
패킷을 서버로 보냅니다. 이 경우 서버는 다른 네트워크에 있습니다.
(10.1.2.0). 두 번째 메시지, "수상 1024 바이트 에 10.1.1.1,"는 UDP 에코에서 가져온 것입니다.
에코 패킷을 수신할 때 생성되는 서버. 마지막 메시지 "수상 1024
바이트 에 10.1.2.4,"는 에코 클라이언트에서 왔으며 에코를 수신했음을 나타냅니다.
다시 서버에서.
이제 최상위 디렉토리로 이동하여 보면 세 개의 추적 파일이 있습니다.
second-0-0.pcap second-1-0.pcap second-2-0.pcap
잠시 이 파일의 이름을 살펴보겠습니다. 모두 같은 형태를 가지고 있으며,
- - .pcap. 예를 들어 목록의 첫 번째 파일은
초-0-0.pcap 이는 노드 XNUMX, 장치 XNUMX의 pcap 추적입니다. 이것이
노드 XNUMX의 점대점 네트 장치. 파일 초-1-0.pcap 에 대한 pcap 추적입니다.
노드 XNUMX의 장치 XNUMX, 또한 점대점 네트 장치; 그리고 파일 초-2-0.pcap is
노드 XNUMX의 장치 XNUMX에 대한 pcap 추적.
섹션 시작 부분의 토폴로지 그림을 다시 참조하면
해당 노드 XNUMX은 점대점 링크의 가장 왼쪽 노드이고 노드 XNUMX은 노드입니다.
점대점 장치와 CSMA 장치를 모두 가지고 있습니다. 노드 XNUMX가
CSMA 네트워크의 첫 번째 "추가" 노드와 해당 장치 XNUMX이 장치로 선택되었습니다.
무차별 모드 추적을 캡처합니다.
이제 인터네트워크를 통해 에코 패킷을 따라가 봅시다. 먼저 다음의 tcpdump를 수행합니다.
가장 왼쪽 지점 간 노드에 대한 추적 파일 --- 노드 XNUMX.
$ tcpdump -nn -tt -r 초-0-0.pcap
pcap 파일의 내용이 표시되어야 합니다.
파일 second-0-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, 길이 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, 길이 1024
덤프의 첫 번째 라인은 링크 유형이 PPP(point-to-point)임을 나타냅니다.
예상하다. 그런 다음 IP와 연결된 장치를 통해 노드 XNUMX을 떠나는 에코 패킷을 볼 수 있습니다.
주소 10.1.1.1은 IP 주소 10.1.2.4(가장 오른쪽 CSMA 노드)로 향합니다. 이 패킷
포인트-투-포인트 링크를 통해 이동하고 포인트-투-포인트 네트 장치에 의해 수신됩니다.
노드 XNUMX. 한 번 보자:
$ tcpdump -nn -tt -r 초-1-0.pcap
이제 지점 간 링크의 다른 쪽의 pcap 추적 출력이 표시되어야 합니다.
파일 second-1-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, 길이 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, 길이 1024
여기에서 링크 유형도 예상한 대로 PPP임을 알 수 있습니다. IP에서 패킷이 보입니다.
IP 주소 10.1.1.1로 향하는 주소 2.000000(10.1.2.4초에 전송됨)
이 인터페이스에 나타납니다. 이제 내부적으로 이 노드로 패킷이 전달됩니다.
CSMA 인터페이스와 우리는 궁극적으로 향하는 해당 장치에서 튀어나오는 것을 볼 수 있습니다.
목적지.
우리는 CSMA 네트워크에 대한 난잡한 스니퍼 노드로 노드 2를 선택했음을 기억하십시오.
그런 다음 second-2-0.pcap을 살펴보고 있는지 확인합니다.
$ tcpdump -nn -tt -r 초-2-0.pcap
이제 노드 XNUMX의 무차별 덤프인 장치 XNUMX이 표시되어야 합니다.
파일 second-2-0.pcap에서 읽기, 링크 유형 EN10MB(이더넷)
2.007698 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, 길이 50
2.007710 ARP, 응답 10.1.2.4는 00:00:00:00:00:06, 길이 50입니다.
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, 길이 1024
2.013815 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, 길이 50
2.013828 ARP, 응답 10.1.2.1는 00:00:00:00:00:03, 길이 50입니다.
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, 길이 1024
보시다시피 링크 유형은 이제 "이더넷"입니다. 그런데 새로운 것이 나타났습니다. 그만큼
버스 네트워크 필요 ARP, 주소 확인 프로토콜. 노드 XNUMX은 전송해야 함을 알고 있습니다.
패킷을 IP 주소 10.1.2.4로 보내지만 MAC 주소를 알지 못합니다.
해당 노드. CSMA 네트워크(ff:ff:ff:ff:ff:ff)에서 브로드캐스트하여
IP 주소가 10.1.2.4인 장치. 이 경우 가장 오른쪽 노드는 다음과 같이 응답합니다.
MAC 주소 00:00:00:00:00:06에 있습니다. 노드 XNUMX는 이 작업에 직접 관여하지 않습니다.
교환하지만 네트워크를 스니핑하고 표시되는 모든 트래픽을 보고합니다.
이 교환은 다음 줄에서 볼 수 있습니다.
2.007698 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, 길이 50
2.007710 ARP, 응답 10.1.2.4는 00:00:00:00:00:06, 길이 50입니다.
그런 다음 노드 XNUMX, 장치 XNUMX이 진행되어 UDP 에코 서버에 에코 패킷을 보냅니다.
IP 주소 10.1.2.4.
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, 길이 1024
서버는 에코 요청을 수신하고 패킷을 돌려 보내려고 시도합니다.
출처. 서버는 이 주소가 다음을 통해 도달하는 다른 네트워크에 있음을 알고 있습니다.
IP 주소 10.1.2.1. 이것은 우리가 글로벌 라우팅을 초기화했고 모든 것을 파악했기 때문입니다.
우리를 위해 이것의 밖으로. 그러나 에코 서버 노드는 첫 번째 MAC 주소를 알지 못합니다.
CSMA 노드이므로 첫 번째 CSMA 노드가 수행해야 했던 것처럼 ARP를 수행해야 합니다.
2.013815 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, 길이 50
2.013828 ARP, 응답 10.1.2.1는 00:00:00:00:00:03, 길이 50입니다.
그런 다음 서버는 에코를 전달 노드로 다시 보냅니다.
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, 길이 1024
point-to-point 링크의 가장 오른쪽 노드를 되돌아보면,
$ tcpdump -nn -tt -r 초-1-0.pcap
이제 에코된 패킷이 마지막으로 점대점 링크로 되돌아오는 것을 볼 수 있습니다.
추적 덤프 라인.
파일 second-1-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, 길이 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, 길이 1024
마지막으로 에코를 시작한 노드를 다시 볼 수 있습니다.
$ tcpdump -nn -tt -r 초-0-0.pcap
에코된 패킷이 2.007602초에 소스에 다시 도착하는지 확인합니다.
파일 second-0-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, 길이 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, 길이 1024
마지막으로 CSMA 장치의 수를 제어하는 기능을 추가한 것을 기억하십시오.
명령줄 인수로 시뮬레이션합니다. 이 인수는 다음과 같은 방식으로 변경할 수 있습니다.
우리는 에코된 패킷의 수를 변경하는 것을 보았습니다 첫 번째.cc 예. 실행해 보세요
"추가" 장치 수가 XNUMX개로 설정된 프로그램:
$ ./waf --run "scratch/mysecond --nCsma=4"
이제 확인해야 합니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.405초).
시간에 2s 클라이언트는 1024 바이트를 10.1.2.5 포트 9로 보냈습니다.
시간 2.0118초에 서버는 1024 포트 10.1.1.1에서 49153바이트를 수신했습니다.
2.0118초에 서버가 1024바이트를 10.1.1.1 포트 49153으로 보냈습니다.
시간 2.02461초에 클라이언트가 1024 포트 10.1.2.5에서 9바이트를 수신했습니다.
이제 에코 서버가 마지막 CSMA 노드로 재배치되었습니다.
10.1.2.5 기본 케이스 대신 10.1.2.4.
방관자가 생성한 추적 파일에 만족하지 않을 수 있습니다.
CSMA 네트워크. 단일 장치에서 추적을 얻고 싶을 수도 있지만 그렇지 않을 수도 있습니다.
네트워크의 다른 트래픽에 관심을 가져야 합니다. 당신은 이것을 상당히 쉽게 할 수 있습니다.
살펴 보겠습니다. 스크래치/mysecond.cc 그 코드를 추가하면 우리가 더 많은 것을 할 수 있습니다.
특정. NS-3 도우미는 노드 번호와 장치 번호를 다음과 같이 사용하는 메서드를 제공합니다.
매개변수. 계속해서 교체하십시오. Pcap 활성화 아래 전화로 전화하십시오.
pointToPoint.EnablePcap("초", p2pNodes.Get(0)->GetId(), 0);
csma.EnablePcap("초", csmaNodes.Get(nCsma)->GetId(), 0, false);
csma.EnablePcap("초", csmaNodes.Get(nCsma-1)->GetId(), 0, false);
우리는 기본 이름이 "second"인 pcap 파일을 만들고 싶다는 것을 알고 있으며 또한 알고 있습니다.
두 경우 모두 관심 있는 장치가 XNUMX이 될 것이므로 해당 매개변수는
정말 흥미로운.
노드 번호를 얻으려면 두 가지 선택이 있습니다. 첫째, 노드는
만든 순서대로 XNUMX부터 시작하여 단조롭게 증가하는 패션
그들을. 노드 번호를 얻는 한 가지 방법은 이 번호를 "수동으로" 파악하는 것입니다.
노드 생성 순서를 고려합니다. 네트워크 토폴로지를 살펴보면
파일의 시작 부분에 있는 그림, 우리는 당신을 위해 이것을했고 당신은 볼 수 있습니다
마지막 CSMA 노드는 노드 번호가 됩니다. nCsma + 1. 이 접근 방식은 짜증나게 될 수 있습니다.
더 큰 시뮬레이션에서는 어렵습니다.
여기서 우리가 사용하는 또 다른 방법은 노드 컨테이너 포함하는
포인터 NS-3 노드 사물. 그만큼 노드 개체에는 다음과 같은 메서드가 있습니다. ID 가져오기 어느 것
우리가 찾는 노드 번호인 해당 노드의 ID를 반환합니다. 를 보러 가자
독시젠을 위한 노드 더 아래에 있는 해당 메서드를 찾습니다. NS-3 핵심 코드
우리가 지금까지 본 것보다; 그러나 때로는 유용한 것을 부지런히 찾아야 합니다.
릴리스에 대한 Doxygen 문서로 이동합니다(Doxygen 문서에서 찾을 수 있음을 기억하십시오.
프로젝트 웹 사이트). 당신은에 도착할 수 있습니다 노드 를 통해 문서화
"Classes" 탭에서 찾을 때까지 "Class List" 아래로 스크롤 ns3::노드. 선택
ns3::노드 에 대한 문서로 이동합니다. 노드 수업. 만약 당신이 지금
아래로 스크롤 ID 가져오기 방법을 선택하여 상세페이지로 이동합니다.
방법에 대한 문서. 사용하여 ID 가져오기 방법은 노드 번호를 결정할 수 있습니다.
복잡한 토폴로지에서 훨씬 쉽습니다.
혼란을 피하기 위해 최상위 디렉토리에서 이전 추적 파일을 지우십시오.
무슨 일이야,
$ rm *.pcap
$ rm *.tr
새 스크립트를 빌드하고 시뮬레이션 설정을 실행하면 nCsma 100에,
$ ./waf --run "scratch/mysecond --nCsma=100"
다음 출력이 표시됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.407초).
시간에 2s 클라이언트는 1024 바이트를 10.1.2.101 포트 9로 보냈습니다.
시간 2.0068초에 서버는 1024 포트 10.1.1.1에서 49153바이트를 수신했습니다.
2.0068초에 서버가 1024바이트를 10.1.1.1 포트 49153으로 보냈습니다.
시간 2.01761초에 클라이언트가 1024 포트 10.1.2.101에서 9바이트를 수신했습니다.
에코 서버는 이제 10.1.2.101개에 해당하는 100에 있습니다.
마지막 노드에 에코 서버가 있는 "추가" CSMA 노드. pcap 파일을 나열하면
표시되는 최상위 디렉토리,
second-0-0.pcap second-100-0.pcap second-101-0.pcap
추적 파일 초-0-0.pcap 에코인 "가장 왼쪽" 지점간 장치입니다.
패킷 소스. 파일 초-101-0.pcap 가장 오른쪽 CSMA 장치에 해당합니다.
에코 서버가 상주하는 곳입니다. 의 마지막 매개변수가
에코 서버 노드에서 pcap 추적을 활성화하기 위한 호출이 거짓이었습니다. 이는 추적을 의미합니다.
해당 노드에 모인 노드는 무차별 모드가 아닙니다.
난잡한 추적과 그렇지 않은 추적의 차이점을 설명하기 위해 우리는 또한
마지막에서 다음 노드에 대한 무차별 추적을 요청했습니다. 계속해서 살펴보십시오.
전에, TCP 덤프 for 초-100-0.pcap.
$ tcpdump -nn -tt -r 초-100-0.pcap
이제 노드 100이 에코 교환의 방관자임을 알 수 있습니다. 유일한
수신하는 패킷은 전체 CSMA에 브로드캐스트되는 ARP 요청입니다.
네트워크.
파일 second-100-0.pcap에서 읽기, 링크 유형 EN10MB(이더넷)
2.006698 ARP, Request who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, 길이 50
2.013815 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.101, 길이 50
이제 TCP 덤프 for 초-101-0.pcap.
$ tcpdump -nn -tt -r 초-101-0.pcap
이제 노드 101이 실제로 에코 교환의 참가자임을 알 수 있습니다.
파일 second-101-0.pcap에서 읽기, 링크 유형 EN10MB(이더넷)
2.006698 ARP, Request who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, 길이 50
2.006698 ARP, 응답 10.1.2.101는 00:00:00:00:00:67, 길이 50입니다.
2.006803 IP 10.1.1.1.49153 > 10.1.2.101.9: UDP, 길이 1024
2.013803 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.101, 길이 50
2.013828 ARP, 응답 10.1.2.1는 00:00:00:00:00:03, 길이 50입니다.
2.013828 IP 10.1.2.101.9 > 10.1.1.1.49153: UDP, 길이 1024
모형, Attributes and 현실
이것은 작은 여행을 하고 중요한 포인트를 만들기에 편리한 장소입니다. 할 수 있습니다
또는 명확하지 않을 수 있지만 시뮬레이션을 사용할 때마다 다음을 수행하는 것이 중요합니다.
모델링되는 것과 그렇지 않은 것을 정확히 이해합니다. 예를 들어 다음과 같은 유혹이 있습니다.
이전 섹션에서 사용된 CSMA 장치 및 채널을 실제인 것처럼 생각하십시오.
이더넷 장치; 발생할 일을 직접 반영하는 시뮬레이션 결과를 기대합니다.
실제 이더넷에서. 그렇지 않다.
모델은 정의상 현실의 추상화입니다. 결국 책임이다
소위 "정확도 범위" 및 "도메인"을 결정하기 위한 시뮬레이션 스크립트 작성자의
전체로서의 시뮬레이션의 "적용 가능성", 따라서 그 구성 부분.
경우에 따라 씨에스마, 무엇인지 결정하는 것은 상당히 쉽습니다. 지원 모델. 에 의해
모델 설명 읽기(csma.h) 충돌 감지가 없음을 알 수 있습니다.
시뮬레이션에서 CSMA 모델의 사용이 얼마나 적용 가능한지 결정합니다.
결과에 포함할 수 있는 주의 사항. 다른 경우에는 매우 쉬울 수 있습니다.
나가서 구매할 수 있는 현실과 일치하지 않을 수 있는 행동을 구성합니다. 그것
몇 가지 그러한 사례를 조사하는 데 시간을 할애할 가치가 있음을 증명할 것입니다.
시뮬레이션에서 현실의 범위를 쉽게 벗어날 수 있습니다.
보시다시피 NS-3 제공 Attributes 사용자가 쉽게 모델 변경을 설정할 수 있는
행동. 다음 두 가지를 고려하십시오. Attributes 의 CsmaNet장치: 음투 and
캡슐화 모드. 그만큼 음투 속성은 최대 전송 단위를 나타냅니다.
장치. 이것은 장치가 사용할 수 있는 가장 큰 PDU(Protocol Data Unit)의 크기입니다.
보내다.
MTU는 기본적으로 1500바이트입니다. CsmaNet장치. 이 기본값은 숫자에 해당합니다.
RFC 894, "A Standard for the Transmission of IP Datagrams over Ethernet
네트워크." 숫자는 실제로 10Base5의 최대 패킷 크기에서 파생됩니다.
(전체 사양 이더넷) 네트워크 -- 1518바이트. DIX 캡슐화를 빼면
이더넷 패킷(18바이트)에 대한 오버헤드는 가능한 최대 데이터 크기로 끝납니다.
(MTU) 1500바이트. 하나는 또한 찾을 수 있습니다 MTU IEEE 802.3 네트워크의 경우 1492
바이트. 이는 LLC/SNAP 캡슐화가 XNUMX바이트의 추가 오버헤드를 추가하기 때문입니다.
패킷. 두 경우 모두 기본 하드웨어는 1518바이트만 보낼 수 있지만 데이터는
크기가 다릅니다.
캡슐화 모드를 설정하기 위해, CsmaNet장치 ~을 제공하다 속성 라는
캡슐화 모드 가치를 가질 수 있는 딕스 or LLC. 이들은 이더넷에 해당합니다.
및 LLC/SNAP 프레이밍.
한 사람이 떠나면 음투 1500바이트에서 캡슐화 모드를 다음으로 변경합니다. LLC, 결과
LLC/SNAP 프레이밍으로 1500바이트 PDU를 캡슐화하는 네트워크가 될 것입니다.
1526바이트의 패킷을 전송할 수 있기 때문에 많은 네트워크에서 불법입니다.
패킷당 최대 1518바이트. 이것은 아마도 다음과 같은 시뮬레이션을 초래할 것입니다.
당신이 기대하는 현실을 미묘하게 반영하지 않습니다.
그림을 복잡하게 만들기 위해 점보 프레임(1500 < MTU <= 9000 바이트)이 있고
IEEE에서 공식적으로 인가하지 않았지만
일부 고속(기가비트) 네트워크 및 NIC에서 사용할 수 있습니다. 하나는 떠날 수
캡슐화 모드가 다음으로 설정됨 딕스, 설정 음투 속성 에 CsmaNet장치 ~ 64000바이트
-- 관련이 있더라도 Csma채널 데이터 속도 초당 10메가비트로 설정되었습니다. 이것
기본적으로 1980년대 스타일의 10Base5로 만든 이더넷 스위치를 모델링합니다.
슈퍼 점보 데이터그램을 지원하는 네트워크. 이것은 확실히 예전의 것이 아니다.
만들어지거나 만들어질 가능성이 없지만 구성하기가 매우 쉽습니다.
이전 예에서는 명령줄을 사용하여 100개의 시뮬레이션을 만들었습니다.
씨에스마 노드. 500개의 노드로 시뮬레이션을 쉽게 생성할 수 있습니다. 만약 너라면
실제로 전체 사양의 최대 길이인 10Base5 뱀파이어 탭 네트워크를 모델링하고 있었습니다.
이더넷 케이블은 500미터이며 최소 탭 간격은 2.5미터입니다. 즉 거기에
실제 네트워크에서 200번만 탭할 수 있습니다. 당신은 아주 쉽게 불법을 만들 수 있습니다
네트워크도 마찬가지입니다. 이로 인해 의미 있는 시뮬레이션이 발생할 수도 있고 그렇지 않을 수도 있습니다.
모델링하려는 대상에 따라 다릅니다.
유사한 상황이 여러 곳에서 발생할 수 있습니다. NS-3 그리고 모든 시뮬레이터에서. 예를 들어,
노드가 동일한 공간을 차지하도록 노드를 배치할 수 있습니다.
또는 표준을 위반하는 증폭기 또는 잡음 수준을 구성할 수 있습니다.
물리의 기본 법칙.
NS-3 일반적으로 유연성을 선호하며 많은 모델에서 자유롭게 설정할 수 있습니다. Attributes
임의의 일관성이나 특정 기본 사양을 적용하지 않고.
이것에서 집으로 가져갈 것은 NS-3 슈퍼 유연한 기반을 제공 할 것입니다
실험해 볼 수 있습니다. 시스템에 요청하는 내용을 이해하는 것은 사용자에게 달려 있습니다.
당신이 만든 시뮬레이션이 어떤 의미와 어떤 것을 가지고 있는지 확인하기 위해
당신이 정의한 현실과의 연결.
건물 a Wireless 네트워크 토폴로지
이 섹션에서는 다음에 대한 지식을 더욱 확장할 것입니다. NS-3 네트워크 장치 및
무선 네트워크의 예를 다루는 채널. NS-3 802.11 모델 세트 제공
802.11 사양의 정확한 MAC 수준 구현을 제공하려는 시도
802.11a 사양의 "그렇게 느리지 않은" PHY 수준 모델.
점대점 및 CSMA 토폴로지 도우미 개체를 모두 본 것처럼
point-to-point 토폴로지 구성, 우리는 동등한 것을 보게 될 것입니다. 무선 랜 토폴로지 도우미
이 구역. 이러한 도우미의 모양과 작동은 매우 친숙하게 보일 것입니다.
너.
우리는 우리의 예제 스크립트를 제공합니다 예제/튜토리얼 예배 규칙서. 이 스크립트는
전에, 초.cc 스크립트를 작성하고 Wi-Fi 네트워크를 추가합니다. 계속해서 열기
예제/튜토리얼/third.cc 좋아하는 편집기에서. 당신은 이미 충분히 보았을 것입니다
NS-3 이 예제에서 진행되는 대부분의 작업을 이해하기 위한 코드이지만 몇 가지 새로운
전체 스크립트를 검토하고 일부 출력을 검사합니다.
에서와 같이 초.cc 예(그리고 모두 NS-3 예) 파일은 emacs로 시작합니다.
모드 라인과 일부 GPL 상용구.
기본 네트워크 토폴로지를 보여주는 ASCII 아트(아래에 재현됨)를 살펴보십시오.
예제에서 구성했습니다. 예제를 더 확장할 것임을 알 수 있습니다.
무선 네트워크를 왼쪽에 걸면 됩니다. 이것은 기본 네트워크입니다.
유선 및 무선에서 생성된 노드 수를 실제로 변경할 수 있으므로 토폴로지
네트워크. 에서와 같이 초.cc 스크립트 케이스, 변경하는 경우 nCsma, 그것은 당신에게 줄 것입니다
"추가" CSMA 노드의 수. 마찬가지로 설정할 수 있습니다. n와이파이 얼마나 많은지 제어하기 위해 STA
(스테이션) 노드가 시뮬레이션에 생성됩니다. 항상 하나있을 것입니다 AP (액세스 포인트)
무선 네트워크의 노드. 기본적으로 XNUMX개의 "추가" CSMA 노드와 XNUMX개의 "추가" CSMA 노드가 있습니다.
무선 전화 STA 노드.
코드는 모듈 포함 파일을 로드하는 것으로 시작합니다. 초.cc 예.
Wi-Fi 모듈 및 이동성에 해당하는 몇 가지 새로운 기능이 포함되어 있습니다.
아래에서 논의할 모듈입니다.
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
네트워크 토폴로지 그림은 다음과 같습니다.
// 기본 네트워크 토폴로지
//
// 와이파이 10.1.3.0
// AP
// * * * *
// | | | | 10.1.1.0
// n5 n6 n7 n0 -------------- n1 n2 n3 n4
// 점대점 | | | |
// ================
// 랜 10.1.2.0
왼쪽에 있는 노드에 새 네트워크 장치를 추가하고 있음을 알 수 있습니다.
무선 네트워크의 액세스 포인트가 되는 지점 간 링크. 다수의
무선 STA 노드가 생성되어 왼쪽과 같이 새로운 10.1.3.0 네트워크를 채웁니다.
그림의 측면.
삽화가 끝난 후, NS-3 네임스페이스는 익숙한 로깅 구성 요소가 정의됩니다.
지금쯤이면 모두 익숙할 것입니다.
네임스페이스 ns3 사용;
NS_LOG_COMPONENT_DEFINE("ThirdScriptExample");
메인 프로그램은 다음과 같이 시작됩니다. 초.cc 몇 가지 명령줄 매개변수를 추가하여
로깅 구성 요소를 활성화 또는 비활성화하고 생성된 장치 수를 변경합니다.
부울 상세 정보 = 참;
uint32_t nCsma = 3;
uint32_t nWifi = 3;
커맨드라인 cmd;
cmd.AddValue ("nCsma", "\"extra\" CSMA 노드/장치 수", nCsma);
cmd.AddValue ("nWifi", "wifi STA 장치 수", nWifi);
cmd.AddValue ("verbose", "참일 경우 로그하도록 echo 응용 프로그램에 지시", verbose);
cmd.Parse(argc,argv);
if(상세)
{
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
앞의 모든 예에서와 마찬가지로 다음 단계는 두 개의 노드를 만드는 것입니다.
점대점 링크를 통해 연결하십시오.
NodeContainer p2pNodes;
p2pNodes.Create(2);
다음으로 오랜 친구를 봅니다. 우리는 포인트투포인트도우미 관련 설정
디폴트 값 Attributes 장치에 초당 XNUMX메가비트 송신기를 생성합니다.
헬퍼와 헬퍼에 의해 생성된 채널에 대한 XNUMX밀리초 지연을 사용하여 생성됩니다.
우리는 그 전체적으로 노드의 장치와 노드 사이의 채널.
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("지연", StringValue("2ms"));
NetDeviceContainer p2p장치;
p2pDevices = pointToPoint.Install(p2pNodes);
다음으로 다른 선언 노드컨테이너 버스의 일부가 될 노드를 유지하기 위해
(CSMA) 네트워크.
NodeContainer csmaNodes;
csmaNodes.Add(p2pNodes.Get(1));
csmaNodes.만들기(nCsma);
다음 코드 줄 가져옵니다. 첫 번째 노드(인덱스가 XNUMX인 경우)
점대점 노드 컨테이너 및 CSMA를 가져올 노드의 컨테이너에 추가
장치. 문제의 노드는 점대점 장치와 CSMA로 끝납니다.
장치. 그런 다음 나머지 CSMA를 구성하는 여러 "추가" 노드를 만듭니다.
네트워크.
그런 다음 CsmaHelper 그리고 그것을 설정 Attributes 이전 예제에서 했던 것처럼.
우리는 NetDevice컨테이너 생성된 CSMA 네트 장치를 추적한 다음
설치 선택한 노드의 CSMA 장치.
CsmaHelper csma;
csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
csma.SetChannelAttribute("지연", TimeValue(NanoSeconds(6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install(csmaNodes);
다음으로 Wi-Fi 네트워크의 일부가 될 노드를 생성합니다. 우리는
명령줄 인수에 지정된 대로 여러 "스테이션" 노드를 생성하고
지점 간 링크의 "가장 왼쪽" 노드를 노드로 사용할 것입니다.
액세스 포인트.
NodeContainer wifiStaNodes;
wifiStaNodes.Create(nWifi);
NodeContainer wifiApNode = p2pNodes.Get(0);
코드의 다음 비트는 Wi-Fi 장치와 사이의 상호 연결 채널을 구성합니다.
이 와이파이 노드. 먼저 PHY 및 채널 도우미를 구성합니다.
YansWifiChannelHelper 채널 = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
단순화를 위해 이 코드는 기본 PHY 계층 구성 및 채널 모델을 사용합니다.
에 대한 API doxygen 문서에 문서화되어 있습니다.
YansWifiChannelHelper::기본값 and YansWifiPhyHelper::기본값 행동 양식. 일단 이러한 개체
생성되면 채널 객체를 생성하고 이를 PHY 계층 객체 관리자에 연결합니다.
에 의해 생성된 모든 PHY 레이어 객체가 YansWifiPhyHelper 공유하다
동일한 기본 채널, 즉 동일한 무선 매체를 공유하고
통신 및 간섭:
phy.SetChannel(채널.만들기());
PHY 도우미가 구성되면 MAC 계층에 집중할 수 있습니다. 여기서 우리는 일을 선택합니다
non-Qos MAC을 사용하므로 NqosWifiMacHelper 객체를 사용하여 MAC 매개변수를 설정합니다.
WifiHelper wifi = WifiHelper::Default ();
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 원격 스테이션 관리자 설정 메서드는 도우미에게 비율 제어 알고리즘의 유형을 알려줍니다.
사용. 여기서 도우미에게 AARF 알고리즘을 사용하도록 요청하고 있습니다. --- 세부 사항은 물론,
Doxygen에서 사용할 수 있습니다.
다음으로 MAC 유형, 즉 우리가 원하는 인프라 네트워크의 SSID를 구성합니다.
스테이션이 활성 프로빙을 수행하지 않도록 설정하고 확인합니다.
Ssid ssid = Ssid ("ns-3-ssid");
mac.SetType("ns3::StaWifiMac",
"Ssid", SsidValue(ssid),
"ActiveProbing", BooleanValue(거짓));
이 코드는 먼저 사용될 802.11 SSID(Service Set Identifier) 객체를 생성합니다.
"Ssid"의 값을 설정하려면 속성 MAC 계층 구현의 특정
도우미가 생성할 MAC 계층의 종류는 다음과 같이 지정됩니다. 속성 의 존재로
"ns3::StaWifiMac" 유형. 의 사용 NqosWifiMac도우미 보장합니다
"Qos 지원됨" 속성 생성된 MAC 개체에 대해 false로 설정됩니다. 이들의 조합
두 가지 구성은 다음에 생성되는 MAC 인스턴스가 non-QoS non-AP가 됨을 의미합니다.
인프라 BSS(즉, AP가 있는 BSS)의 스테이션(STA). 마지막으로,
"액티브프로빙" 속성 거짓으로 설정됩니다. 이는 프로브 요청이
이 도우미가 만든 MAC에서 보냅니다.
MAC 및 PHY 모두에서 모든 스테이션별 매개변수가 완전히 구성되면
이제 익숙한 레이어를 호출할 수 있습니다. 설치 이들의 Wi-Fi 장치를 만드는 방법
스테이션:
NetDeviceContainer staDevices;
staDevices = wifi.Install(phy, mac, wifiStaNodes);
모든 STA 노드에 대해 Wi-Fi를 구성했으며 이제 AP를 구성해야 합니다.
(액세스 포인트) 노드. 기본값을 변경하여 이 프로세스를 시작합니다. Attributes 의
NqosWifiMac도우미 AP의 요구 사항을 반영합니다.
mac.SetType("ns3::ApWifiMac",
"Ssid", SsidValue(ssid));
이 경우 NqosWifiMac도우미 "ns3::ApWifiMac"의 MAC 계층을 생성할 것입니다.
후자는 AP로 구성된 MAC 인스턴스가 생성되어야 함을 지정하고
"QosSupported"를 의미하는 도우미 유형 속성 false로 설정해야 함 - 비활성화
생성된 AP에서 802.11e/WMM 스타일 QoS 지원.
다음 라인은 동일한 PHY 레벨 세트를 공유하는 단일 AP를 생성합니다. Attributes (그리고
채널) 스테이션으로:
NetDeviceContainer apDevices;
apDevices = wifi.Install(phy, mac, wifiApNode);
이제 모빌리티 모델을 추가하겠습니다. 우리는 STA 노드가 움직이고 방황하기를 원합니다.
경계 상자 내부를 둘러보고 AP 노드를 정지 상태로 만들고 싶습니다. 우리는
이동성 도우미 우리가 이것을 쉽게 할 수 있도록. 먼저 인스턴스화 이동성 도우미 대상
그리고 일부 설정 Attributes "위치 할당자" 기능을 제어합니다.
이동성도우미 이동성;
mobility.SetPositionAllocator("ns3::GridPositionAllocator",
"MinX", DoubleValue(0.0),
"최소", DoubleValue(0.0),
"DeltaX", DoubleValue(5.0),
"DeltaY", DoubleValue(10.0),
"GridWidth", UintegerValue (3),
"레이아웃 유형", StringValue("RowFirst"));
이 코드는 이동 도우미에게 XNUMX차원 그리드를 사용하여 처음에
STA 노드. 수업을 위해 Doxygen을 자유롭게 탐색하십시오. ns3::GridPositionAllocator 볼 수
정확히 무슨 일이 일어나고 있는지.
초기 그리드에 노드를 배치했지만 이제 이동 방법을 알려줘야 합니다.
우리는 RandomWalk2d이동성모델 노드가 임의의 방향으로 이동합니다.
경계 상자 내부의 임의 속도.
mobility.SetMobilityModel("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue(직사각형(-50, 50, -50, 50)));
우리는 이제 이동성 도우미 STA 노드에 이동성 모델을 설치합니다.
이동성.설치(wifiStaNodes);
시뮬레이션 중에 액세스 포인트가 고정된 위치에 유지되기를 원합니다. 우리
이 노드에 대한 이동성 모델을
ns3::ConstantPositionMobilityModel:
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
이동성.설치(wifiApNode);
이제 노드, 장치 및 채널이 생성되었으며 이동성 모델이 선택되었습니다.
Wifi 노드가 있지만 프로토콜 스택이 없습니다. 우리가 이전에 많은 일을 한 것처럼
시간, 우리는 인터넷스택헬퍼 이러한 스택을 설치합니다.
InternetStackHelper 스택;
stack.Install(csmaNodes);
stack.Install(wifiApNode);
stack.Install(wifiStaNodes);
에서와 같이 초.cc 예제 스크립트에서 우리는 IPv4AddressHelper 에
장치 인터페이스에 IP 주소를 할당합니다. 먼저 네트워크 10.1.1.0을 사용하여 생성합니다.
두 개의 지점 간 장치에 필요한 두 개의 주소. 그런 다음 네트워크 10.1.2.0을 사용합니다.
CSMA 네트워크에 주소를 할당한 다음 네트워크 10.1.3.0에서 주소를 할당합니다.
무선 네트워크의 STA 장치와 AP 모두에.
Ipv4AddressHelper 주소;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2p인터페이스;
p2pInterfaces = address.Assign(p2pDevices);
address.SetBase("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = 주소.할당(csmaDevices);
address.SetBase("10.1.3.0", "255.255.255.0");
address.Assign(staDevices);
address.Assign(apDevices);
그림의 시작 부분에 있는 "가장 오른쪽" 노드에 에코 서버를 배치합니다.
파일. 우리는 전에 이것을 했습니다.
UdpEchoServerHelper echoServer(9);
ApplicationContainer serverApps = echoServer.Install(csmaNodes.Get(nCsma));
serverApps.Start(초(1.0));
serverApps.Stop(초(10.0));
그리고 에코 클라이언트를 우리가 생성한 마지막 STA 노드에 놓고 서버를 가리킵니다.
CSMA 네트워크. 이전에도 유사한 작업을 본 적이 있습니다.
UdpEchoClientHelper echoClient(csmaInterfaces.GetAddress(nCsma), 9);
echoClient.SetAttribute("MaxPackets", UintegerValue (1));
echoClient.SetAttribute("간격", TimeValue(초(1.0)));
echoClient.SetAttribute("PacketSize", UintegerValue(1024));
ApplicationContainer 클라이언트 앱 =
echoClient.Install(wifiStaNodes.Get(nWifi - 1));
clientApps.Start(초(2.0));
clientApps.Stop(초(10.0));
여기에서 인터네트워크를 구축했으므로 다음과 같이 인터네트워크 라우팅을 활성화해야 합니다.
우리는에서했다 초.cc 예제 스크립트.
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
일부 사용자를 놀라게 할 수 있는 한 가지는 방금 만든 시뮬레이션이
절대 "자연스럽게" 멈추지 않습니다. 무선 액세스 포인트에 다음을 요청했기 때문입니다.
비콘을 생성합니다. 그것은 비콘을 영원히 생성할 것이고 이것은 시뮬레이터를 생성할 것입니다.
이벤트가 미래에 무기한으로 예정되어 있으므로 시뮬레이터에 중지하라고 알려야 합니다.
비콘 생성 이벤트가 예정되어 있더라도. 다음 코드 줄
비콘을 영원히 시뮬레이트하지 않고
본질적으로 무한 루프.
시뮬레이터::정지(초(10.0));
우리는 세 가지 네트워크를 모두 포괄하기에 충분한 추적을 생성합니다.
pointToPoint.EnablePcapAll("세 번째");
phy.EnablePcap("제0", apDevices.Get(XNUMX));
csma.EnablePcap("제0", csmaDevices.Get(XNUMX), true);
이 세 줄의 코드는 두 지점 간 노드에서 pcap 추적을 시작합니다.
백본 역할을 하며 Wifi 네트워크에서 무차별(모니터) 모드 추적을 시작합니다.
CSMA 네트워크에서 난잡한 추적을 시작합니다. 이것은 우리가 모든 것을 볼 수 있습니다
최소 수의 추적 파일이 있는 트래픽.
마지막으로 실제로 시뮬레이션을 실행하고 정리한 다음 프로그램을 종료합니다.
시뮬레이터::실행();
시뮬레이터::파괴();
0가 돌아;
}
이 예제를 실행하려면 다음을 복사해야 합니다. 세 번째.cc 예제 스크립트를
디렉터리를 스크래치하고 Waf를 사용하여 초.cc 예. 만약 너라면
입력하려는 저장소의 최상위 디렉토리에 있습니다.
$ cp 예제/튜토리얼/third.cc 스크래치/mythird.cc
$ ./와프
$ ./waf --스크래치/mythird 실행
다시 말하지만, 우리는 UDP 에코 애플리케이션을 설정했기 때문에 초.cc
스크립트를 실행하면 비슷한 출력이 표시됩니다.
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 디렉토리를 떠납니다.
'빌드'가 성공적으로 완료되었습니다(0.407초).
시간에 2s 클라이언트는 1024 바이트를 10.1.2.4 포트 9로 보냈습니다.
시간 2.01796초에 서버는 1024 포트 10.1.3.3에서 49153바이트를 수신했습니다.
2.01796초에 서버가 1024바이트를 10.1.3.3 포트 49153으로 보냈습니다.
시간 2.03364초에 클라이언트가 1024 포트 10.1.2.4에서 9바이트를 수신했습니다.
첫 번째 메시지를 기억하세요. 보낸 1024 바이트 에 10.1.2.4,"는 UDP 에코 클라이언트입니다.
패킷을 서버로 보냅니다. 이 경우 클라이언트는 무선 네트워크에 있습니다.
(10.1.3.0). 두 번째 메시지, "수상 1024 바이트 에 10.1.3.3,"는 UDP 에코에서 가져온 것입니다.
에코 패킷을 수신할 때 생성되는 서버. 마지막 메시지 "수상 1024
바이트 에 10.1.2.4,"는 에코 클라이언트에서 왔으며 에코를 수신했음을 나타냅니다.
다시 서버에서.
이제 최상위 디렉토리로 이동하여 보면 다음에서 XNUMX개의 추적 파일을 찾을 수 있습니다.
이 시뮬레이션은 노드 XNUMX에서 XNUMX개, 노드 XNUMX에서 XNUMX개입니다.
third-0-0.pcap third-0-1.pcap third-1-0.pcap third-1-1.pcap
"third-0-0.pcap" 파일은 노드 XNUMX의 점대점 장치에 해당합니다.
"백본"의 왼쪽. "third-1-0.pcap" 파일은 점대점에 해당합니다.
노드 0의 장치 -- "백본"의 오른쪽. "third-1-XNUMX.pcap" 파일은
Wi-Fi 네트워크의 난잡한(모니터 모드) 추적 및 "third-1-1.pcap" 파일
CSMA 네트워크의 난잡한 추적이 됩니다. 검사를 통해 이를 확인할 수 있습니까?
코드?
에코 클라이언트가 Wi-Fi 네트워크에 있으므로 거기서 시작하겠습니다. 다음을 살펴보겠습니다.
해당 네트워크에서 캡처한 난잡한(모니터 모드) 추적.
$ tcpdump -nn -tt -r 세 번째-0-1.pcap
이전에 여기에서 본 적이 없는 Wi-Fi처럼 보이는 콘텐츠가 표시되어야 합니다.
파일 third-0-1.pcap에서 읽기, 링크 유형 IEEE802_11(802.11)
0.000025 비콘(ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit] IBSS
0.000308 연결 요청(ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit]
0.000324 Acknowledgment RA:00:00:00:00:00:08
0.000402 연결 응답 도움(0) :: 성공
0.000546 Acknowledgment RA:00:00:00:00:00:0a
0.000721 연결 요청(ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit]
0.000737 Acknowledgment RA:00:00:00:00:00:07
0.000824 연결 응답 도움(0) :: 성공
0.000968 Acknowledgment RA:00:00:00:00:00:0a
0.001134 연결 요청(ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit]
0.001150 Acknowledgment RA:00:00:00:00:00:09
0.001273 연결 응답 도움(0) :: 성공
0.001417 Acknowledgment RA:00:00:00:00:00:0a
0.102400 비콘(ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit] IBSS
0.204800 비콘(ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit] IBSS
0.307200 비콘(ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0Mbit] IBSS
이제 링크 유형이 예상한 대로 802.11임을 알 수 있습니다. 당신은 아마 할 수 있습니다
무슨 일이 일어나고 있는지 이해하고 여기에서 IP 에코 요청 및 응답 패킷을 찾습니다.
추적하다. 추적 덤프를 완전히 구문 분석하기 위한 연습으로 남겨둡니다.
이제 point-to-point 링크 우측의 pcap 파일을 보면,
$ tcpdump -nn -tt -r 세 번째-0-0.pcap
다시 말하지만, 익숙한 내용이 표시되어야 합니다.
파일 third-0-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.008151 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, 길이 1024
2.026758 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, 길이 1024
이것은 왼쪽에서 오른쪽으로(Wifi에서 CSMA로) 갔다가 다시 돌아오는 에코 패킷입니다.
점대점 링크.
이제 point-to-point 링크 우측의 pcap 파일을 보면,
$ tcpdump -nn -tt -r 세 번째-1-0.pcap
다시 말하지만, 익숙한 내용이 표시되어야 합니다.
파일 third-1-0.pcap에서 읽기, 링크 유형 PPP(PPP)
2.011837 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, 길이 1024
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, 길이 1024
이것은 또한 왼쪽에서 오른쪽으로(Wifi에서 CSMA로) 갔다가 다시 되돌아오는 에코 패킷입니다.
예상할 수 있는 약간 다른 타이밍으로 지점 간 링크를 통해.
에코 서버는 CSMA 네트워크에 있으며 거기에서 난잡한 추적을 살펴보겠습니다.
$ tcpdump -nn -tt -r 세 번째-1-1.pcap
다음과 같은 친숙한 내용이 표시됩니다.
파일 third-1-1.pcap에서 읽기, 링크 유형 EN10MB(이더넷)
2.017837 ARP, Request who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1, 길이 50
2.017861 ARP, 응답 10.1.2.4는 00:00:00:00:00:06, 길이 50입니다.
2.017861 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, 길이 1024
2.022966 ARP, Request who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.4, 길이 50
2.022966 ARP, 응답 10.1.2.1는 00:00:00:00:00:03, 길이 50입니다.
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, 길이 1024
이것은 쉽게 이해되어야 합니다. 잊었다면 돌아가서 토론을 살펴보십시오.
in 초.cc. 이것은 같은 순서입니다.
이제 우리는 무선 네트워크에 대한 이동성 모델을 설정하는 데 많은 시간을 할애했습니다.
STA 노드가 실제로 움직이고 있다는 것을 보여주지 않고 끝내는 것은 부끄러운 일입니다.
시뮬레이션 동안 주변. 에 연결하여 이 작업을 수행해 보겠습니다. 이동성 모델 코스
추적 소스를 변경하십시오. 이것은 자세한 추적 섹션을 엿볼 뿐입니다.
다가오고 있지만 이것은 예를 들어보기에 아주 좋은 곳인 것 같습니다.
"NS-3 조정" 섹션에서 언급한 바와 같이 NS-3 추적 시스템은 추적으로 나뉩니다.
소스와 트레이스 싱크, 그리고 우리는 둘을 연결하는 기능을 제공합니다. 우리는
이동성 모델은 추적 이벤트를 발생시키기 위해 사전 정의된 코스 변경 추적 소스입니다. 우리
예쁜 소스를 표시할 소스에 연결하려면 트레이스 싱크를 작성해야 합니다.
우리를 위한 정보. 어렵다는 평판에도 불구하고 실제로는 매우 간단합니다.
메인 프로그램 직전에 스크래치/mythird.cc 스크립트(즉,
NS_LOG_COMPONENT_DEFINE 문) 다음 함수를 추가합니다.
무효화
CourseChange(std::문자열 컨텍스트, Ptr 모델)
{
벡터 위치 = 모델->GetPosition();
NS_LOG_UNCOND(컨텍스트 <
" x = " << 위치.x << ", y = " << 위치.y);
}
이 코드는 모빌리티 모델에서 위치 정보만 가져오고 무조건
노드의 x 및 y 위치를 기록합니다. 우리는 이 기능이
에코 클라이언트가 있는 무선 노드가 위치를 변경할 때마다 호출됩니다. 우리는 이것을 한다
를 사용하여 구성::연결 기능. 스크립트에 다음 코드 줄을 추가하십시오.
이전 시뮬레이터::실행 요구.
표준::ostringstream oss;
OSS <
"/NodeList/" << wifiStaNodes.Get(nWifi - 1)->GetId() <
"/$ns3::MobilityModel/CourseChange";
Config::Connect(oss.str(), MakeCallback(&CourseChange));
여기서 우리가 하는 일은 이벤트의 추적 네임스페이스 경로를 포함하는 문자열을 만드는 것입니다.
우리가 연결하려는. 먼저 사용하려는 노드를 파악해야 합니다.
전에, ID 가져오기 앞에서 설명한 방법. CSMA 기본 개수의 경우와
무선 노드, 이것은 노드 XNUMX로 판명되고 추적 네임스페이스 경로는
모빌리티 모델은 다음과 같습니다.
/NodeList/7/$ns3::MobilityModel/CourseChange
추적 섹션의 논의를 기반으로 이 추적 경로가
전역 NodeList의 일곱 번째 노드를 참조합니다. 라고 하는 것을 지정합니다.
집계된 객체 유형 ns3::모빌리티모델. 달러 기호 접두어는 다음을 의미합니다.
MobilityModel은 노드 XNUMX로 집계됩니다. 경로의 마지막 구성 요소는
해당 모델의 "CourseChange" 이벤트에 연결됩니다.
다음을 호출하여 노드 XNUMX의 추적 소스와 추적 싱크를 연결합니다.
구성::연결 이 네임스페이스 경로를 전달합니다. 이 작업이 완료되면 모든 과정이 변경됩니다.
노드 XNUMX의 이벤트는 트레이스 싱크에 연결되어 다음을 출력합니다.
새로운 위치.
이제 시뮬레이션을 실행하면 코스 변경이 발생하는 대로 표시되는 것을 볼 수 있습니다.
'빌드'가 성공적으로 완료되었습니다(5.989초).
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10, y = 0
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.3841, y = 0.923277
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2049, y = 1.90708
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.8136, y = 1.11368
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.8452, y = 2.11318
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.9797, y = 3.10409
시간에 2s 클라이언트는 1024 바이트를 10.1.2.4 포트 9로 보냈습니다.
시간 2.01796초에 서버는 1024 포트 10.1.3.3에서 49153바이트를 수신했습니다.
2.01796초에 서버가 1024바이트를 10.1.3.3 포트 49153으로 보냈습니다.
시간 2.03364초에 클라이언트가 1024 포트 10.1.2.4에서 9바이트를 수신했습니다.
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.3273, y = 4.04175
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.013, y = 4.76955
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.4317, y = 5.67771
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.4607, y = 5.91681
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.0155, y = 6.74878
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.0076, y = 6.62336
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.6285, y = 5.698
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.32, y = 4.97559
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.1134, y = 3.99715
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.8359, y = 4.68851
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.5953, y = 3.71789
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.7595, y = 4.26688
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.7629, y = 4.34913
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.2292, y = 5.19485
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2344, y = 5.09394
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.3601, y = 4.60846
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.40025, y = 4.32795
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.14292, y = 4.99761
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.08299, y = 5.99581
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.26068, y = 5.42677
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.35917, y = 6.42191
/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.66805, y = 7.14466
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.71414, y = 6.84456
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.42489, y = 7.80181
트레이싱
배경
UsingTracingSystem에서 언급했듯이 NS-3 시뮬레이션은
연구를 위한 출력을 생성합니다. 출력을 얻기 위한 두 가지 기본 전략이 있습니다. NS-3:
일반적인 사전 정의된 대량 출력 메커니즘을 사용하고 콘텐츠를 구문 분석하여 추출
흥미로운 정보; 또는 어떻게든 정확하게 전달하는 출력 메커니즘을 개발합니다.
(아마도) 원하는 정보.
미리 정의된 대량 출력 메커니즘을 사용하면 다음을 변경할 필요가 없다는 이점이 있습니다.
NS-3, 하지만 관심 있는 데이터를 구문 분석하고 필터링하려면 스크립트를 작성해야 할 수 있습니다. 자주,
PCAP 또는 NS_LOG 출력 메시지는 시뮬레이션 실행 중에 수집되고 별도로 실행됩니다.
사용하는 스크립트를 통해 GREP, SED or AWK 메시지를 구문 분석하고 축소 및 변환
데이터를 관리 가능한 형태로 변환을 수행하도록 프로그램을 작성해야 하므로 이
공짜로 오지 않습니다. NS_LOG 출력은 다음의 일부로 간주되지 않습니다. NS-3 API 및 수
릴리스 간에 경고 없이 변경됩니다. 게다가, NS_LOG 출력은
디버그 빌드이므로 이에 의존하면 성능이 저하됩니다. 물론,
사전 정의된 출력 메커니즘에 관심 있는 정보가 존재하지 않는 경우, 이
접근이 실패합니다.
미리 정의된 대량 메커니즘에 약간의 정보를 추가해야 하는 경우 다음을 수행할 수 있습니다.
확실히 완료; 다음 중 하나를 사용하는 경우 NS-3 메커니즘을 사용하면 코드가 추가될 수 있습니다.
공헌으로.
NS-3 고유한 문제 중 일부를 방지하는 추적이라는 또 다른 메커니즘을 제공합니다.
대량 출력 메커니즘에서. 몇 가지 중요한 이점이 있습니다. 먼저 할 수 있습니다.
관심 있는 이벤트만 추적하여 관리해야 하는 데이터 양을 줄입니다.
(대규모 시뮬레이션의 경우 후처리를 위해 모든 것을 디스크에 덤프하면 I/O가 생성될 수 있습니다.
병목 현상). 둘째, 이 방법을 사용하면 출력 형식을 제어할 수 있습니다.
다음과 같은 후처리 단계를 피할 수 있습니다. SED, AWK, 펄 or 파이썬 스크립트. 만약에
원하는 경우 출력을 gnuplot에서 허용하는 형식으로 직접 형식화할 수 있습니다.
예(GnuplotHelper 참조). 코어에 후크를 추가할 수 있습니다.
다른 사용자가 액세스하지만 명시적으로 요청하지 않는 한 정보를 생성하지 않습니다.
그렇게 하세요. 이러한 이유로 우리는 NS-3 추적 시스템이 가장 좋은 방법입니다.
시뮬레이션 외부의 정보이며 따라서 가장 중요한 메커니즘 중 하나입니다.
이해하다 NS-3.
무딘 기구
프로그램에서 정보를 얻는 방법에는 여러 가지가 있습니다. 가장 직관적인 방법은
다음과 같이 정보를 표준 출력에 직접 인쇄합니다.
#포함
...
무효화
SomeFunction(무효)
{
uint32_t x = SOME_INTERESTING_VALUE;
...
std::cout << "x의 값은 " << x << std::endl;
...
}
아무도 당신이 핵심으로 깊숙이 들어가는 것을 막지 못할 것입니다. NS-3 인쇄 추가
진술. 이것은 정말 하기 쉽고, 결국, 당신은 당신의
자신의 NS-3 나뭇가지. 이것은 아마도 장기적으로 매우 만족스럽지 않을 것입니다.
그래도 용어.
프로그램에서 인쇄문의 수가 증가함에 따라
많은 수의 출력이 점점 더 복잡해질 것입니다. 결국, 당신은 느낄 수 있습니다
어떤 방식으로 어떤 정보가 인쇄되는지 제어해야 할 필요성
특정 범주의 인쇄물을 끄거나 양을 늘리거나 줄입니다.
당신이 원하는 정보. 이 경로를 계속 따라가면 다음과 같은 사실을 발견할 수 있습니다.
다시 구현 NS_LOG 메커니즘(UsingLogging 참조). 이를 방지하기 위해 다음 중 하나를
가장 먼저 고려해야 할 사항은 다음을 사용하는 것입니다. NS_LOG 자체.
위에서 정보를 얻는 한 가지 방법에 대해 언급했습니다. NS-3 기존 구문 분석 NS_LOG
흥미로운 정보를 출력합니다. 약간의 정보를 발견했다면
필요가 기존 로그 출력에 없으면 핵심을 편집할 수 있습니다. NS-3 간단히 추가
출력 스트림에 대한 흥미로운 정보. 지금, 이것은 확실히
다음과 같이 자신의 인쇄 문을 추가하십시오. NS-3 코딩 규칙과
잠재적으로 기존 코어에 대한 패치로 다른 사람들에게 유용할 수 있습니다.
임의의 예를 선택해 보겠습니다. 더 많은 로깅을 추가하려면 NS-3 TCP 소켓
(tcp-소켓-base.cc) 구현에서 새 메시지를 추가할 수 있습니다. 알아채다
에 해당 TcpSocketBase::ReceivedAck() ACK가 없는 경우에 대한 로그 메시지가 없습니다. 너
간단히 하나를 추가하여 코드를 변경할 수 있습니다. 원본은 다음과 같습니다.
/** 새로 받은 ACK 처리 */
무효화
TcpSocketBase::ReceivedAck(Ptr 패킷, const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION(이 << tcpHeader);
// ACK를 받았습니다. ACK 번호를 가장 높은 unacked seqno와 비교하십시오.
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // ACK 플래그가 없으면 무시
}
...
ACK가 없는 경우를 기록하려면 새 NS_LOG_LOGIC 인간을 if 문 본문:
/** 새로 받은 ACK 처리 */
무효화
TcpSocketBase::ReceivedAck(Ptr 패킷, const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION(이 << tcpHeader);
// ACK를 받았습니다. ACK 번호를 가장 높은 unacked seqno와 비교하십시오.
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // ACK 플래그가 없으면 무시
NS_LOG_LOGIC("TcpSocketBase " << 이 << " ACK 플래그 없음");
}
...
이것은 언뜻보기에 상당히 간단하고 만족스러워 보일 수 있지만 고려해야 할 사항은
추가할 코드를 작성할 것입니다. NS_LOG 진술과 당신은 또한 작성해야합니다
코드(에서와 같이 GREP, SED or AWK 스크립트)를 분리하기 위해 로그 출력을 구문 분석합니다.
정보. 이는 사용자가
로깅 시스템에서는 일반적으로 로그 구성 요소 수준까지만 제어할 수 있습니다.
전체 소스 코드 파일.
기존 모듈에 코드를 추가하는 경우 출력과 함께 살아야 합니다.
다른 모든 개발자가 흥미를 느꼈습니다. 당신은 그것을 얻기 위해 찾을 수 있습니다
필요한 정보가 적다면 엄청난 양의 정보를 헤쳐 나가야 할 수도 있습니다.
관심이 없는 관련 없는 메시지. 거대한 로그를 저장해야 할 수도 있습니다.
파일을 디스크에 저장하고 원하는 작업을 할 때마다 몇 줄로 처리합니다.
에 대한 보장이 없기 때문에 NS-3 의 안정성에 대해 NS_LOG 출력, 당신은 또한
의존하는 로그 출력 조각이 사라지거나 변경되는 것을 발견하십시오.
릴리스. 출력 구조에 의존하는 경우 다른 메시지가 표시될 수 있습니다.
구문 분석 코드에 영향을 미칠 수 있는 추가 또는 삭제.
마지막으로, NS_LOG 출력은 디버그 빌드에서만 사용할 수 있으며 로그 출력을 가져올 수 없습니다.
약 XNUMX배 빠르게 실행되는 최적화된 빌드. 의지하다 NS_LOG 성능을 부과
패널티.
이러한 이유로 우리는 인쇄를 다음과 같이 고려합니다. 표준::컷 and NS_LOG 빠르고
더 많은 정보를 얻는 더러운 방법 NS-3, 그러나 진지한 작업에는 적합하지 않습니다.
안정적인 API를 사용하여 안정적인 시설을 갖추는 것이 바람직합니다.
핵심 시스템은 필요한 정보만 얻습니다. 할 수 있는 것이 바람직하다
이것은 핵심 시스템을 변경하고 다시 컴파일할 필요 없이 가능합니다. 더 좋은 것은
관심 항목이 변경되거나 흥미로운 이벤트가 발생하면 사용자 코드에 알리는 시스템
사용자가 적극적으로 시스템을 탐색할 필요가 없습니다.
소지품.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 추적 시스템은 이러한 라인을 따라 작동하도록 설계되었으며 다음과 잘 통합됩니다.
속성 및 구성 비교적 간단한 사용 시나리오를 허용하는 하위 시스템.
살펴보기
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 추적 시스템은 독립적인 추적 소스 및
소스를 싱크에 연결하기 위한 균일한 메커니즘과 함께 싱크를 추적합니다.
추적 소스는 시뮬레이션에서 발생하는 이벤트에 신호를 보내고 다음을 제공할 수 있는 엔터티입니다.
흥미로운 기본 데이터에 액세스할 수 있습니다. 예를 들어 추적 소스는
패킷은 네트 장치에 의해 수신되고 패킷 내용에 대한 액세스를 제공합니다.
관심 추적 싱크. 추적 소스는 관심 있는 상태가 언제 표시될 수도 있습니다.
변화는 모델에서 일어난다. 예를 들어, TCP 모델의 혼잡 창은 소수입니다.
추적 소스 후보. 혼잡 구간이 연결된 트레이스를 변경할 때마다
싱크는 이전 값과 새 값으로 알림을 받습니다.
추적 소스는 그 자체로는 유용하지 않습니다. 다른 코드 조각에 연결되어야 합니다.
소스에서 제공하는 정보로 실제로 유용한 작업을 수행합니다. 그만큼
추적 정보를 사용하는 엔터티를 추적 싱크라고 합니다. 추적 소스는
데이터 및 트레이스 싱크의 생성자는 소비자입니다. 이 명시적인 분할은 큰
작성자를 모델링하는 시스템 주변에 흩어져 있는 추적 소스의 수
유용할 수 있다고 믿습니다. 추적 소스를 삽입하면 매우 작은 실행이 도입됩니다.
간접비.
추적 소스에서 생성된 추적 이벤트의 소비자는 XNUMX명 이상일 수 있습니다. 하나는 수
추적 소스를 일종의 점대다점 정보 링크로 생각하십시오. 귀하의 코드
코어 코드의 특정 부분에서 추적 이벤트를 찾는 것은 행복하게 공존할 수 있습니다.
동일한 정보와 완전히 다른 작업을 수행하는 다른 코드.
사용자가 추적 싱크를 이러한 소스 중 하나에 연결하지 않으면 아무 것도 출력되지 않습니다. 사용하여
추적 시스템, 귀하와 동일한 추적 소스에 연결된 다른 사람들 모두 점점
정확히 그들이 원하는 것과 시스템에서 원하는 것만. 둘 다 아니야
시스템에서 출력되는 정보를 변경하여 다른 사용자에게 영향을 미침. 만약 너라면
트레이스 소스를 추가하는 경우 훌륭한 오픈 소스 시민으로서 귀하의 작업은 다른 사용자에게 허용될 수 있습니다.
사용자가 전반적으로 매우 유용할 수 있는 새로운 유틸리티를 제공할 수 있습니다.
로 변경 NS-3 핵심.
단순, 간단, 편리 예시
몇 분 동안 간단한 추적 예제를 살펴보겠습니다. 우리는 필요할 것입니다
예제에서 무슨 일이 일어나고 있는지 이해하기 위해 콜백에 대한 약간의 배경 지식이 있으므로
곧바로 작은 우회로를 이용해야 합니다.
콜백
콜백 시스템의 목표 NS-3 하나의 코드 조각이 함수를 호출하도록 허용하는 것입니다.
(또는 C++의 메서드) 특정 모듈 간 종속성이 없습니다. 이것은 궁극적으로 의미합니다
일종의 간접 참조가 필요합니다. 호출된 함수의 주소를
변하기 쉬운. 이 변수를 함수에 대한 포인터 변수라고 합니다. 관계
함수와 함수에 대한 포인터 사이는 실제로 객체와 함수의 포인터와 다르지 않습니다.
객체에 대한 포인터.
C에서 함수에 대한 포인터의 표준 예는
PFI(함수 반환 정수에 대한 포인터). PFI의 경우 INT 매개변수, 이
다음과 같이 선언할 수 있습니다.
int (*pfi)(int arg) = 0;
(하지만 읽어보세요. C++-FAQ 섹션 33 이런 코드를 작성하기 전에!) 여기서 얻을 수 있는 것
단순히 이름이 붙은 변수입니다 피피 이는 값 0으로 초기화됩니다.
이 포인터를 의미 있는 것으로 초기화하려면
일치하는 서명. 이 경우 다음과 같은 기능을 제공할 수 있습니다.
int MyFunction(int 인수) {}
이 대상이 있는 경우 함수를 가리키도록 변수를 초기화할 수 있습니다.
pfi = 내기능;
그런 다음 보다 암시적인 호출 형식을 사용하여 MyFunction을 간접적으로 호출할 수 있습니다.
int 결과 = (*pfi) (1234);
이것은 함수 포인터를 역참조하는 것처럼 보이기 때문에 암시적입니다.
포인터를 역 참조하는 것처럼. 그러나 일반적으로 사람들은
컴파일러가 무슨 일이 일어나고 있는지 알고 있고 더 짧은 형식을 사용할 것이라는 사실:
정수 결과 = pfi(1234);
다음과 같은 함수를 호출하는 것 같습니다. 피피하지만 컴파일러는 충분히 똑똑합니다.
변수를 통해 호출하는 방법을 알고 있습니다. 피피 함수에 간접적으로 마이펑션.
개념적으로 이는 추적 시스템이 작동하는 방식과 거의 동일합니다. 기본적으로 추적
싱크대 is 콜백. 추적 싱크가 추적 이벤트 수신에 관심을 표시하면
추적 소스가 내부적으로 보유한 콜백 목록에 자신을 콜백으로 추가합니다.
흥미로운 이벤트가 발생하면 추적 소스가 해당 이벤트를 호출합니다. 운영자(...) 제공
XNUMX개 이상의 인수. 그만큼 운영자(...) 결국 시스템 속으로 방황하고
방금 본 간접 호출과 매우 유사하여 XNUMX개 이상의 값을 제공합니다.
에 대한 호출과 마찬가지로 매개변수 피피 위에서 대상 함수에 하나의 매개변수를 전달했습니다.
마이펑션.
추적 시스템이 추가하는 중요한 차이점은 각 추적 소스에 대해
콜백의 내부 목록입니다. 간접 호출을 한 번만 하는 대신 추적
소스는 여러 콜백을 호출할 수 있습니다. 트레이스 싱크가 다음에 대한 관심을 표현하는 경우
추적 소스의 알림은 기본적으로 자체 기능을 추가하도록 배열합니다.
콜백 목록.
이것이 실제로 어떻게 배열되는지에 대한 자세한 내용에 관심이 있다면 NS-3, 느낌
콜백 섹션을 자유롭게 읽어보세요. NS-3 매뉴얼.
연습 : 네번째.cc
우리는 추적의 가장 간단한 예를 구현하기 위해 몇 가지 코드를 제공했습니다.
조립할 수 있는 것입니다. 튜토리얼 디렉토리에서 이 코드를 다음과 같이 찾을 수 있습니다. 네번째.cc.
살펴보겠습니다:
/* -*- 모드:C++; c-파일 스타일:"gnu"; 들여쓰기 탭 모드:nil; -*- */
/*
* 이 프로그램은 무료 소프트웨어입니다. 재배포 및/또는 수정할 수 있습니다.
* 다음과 같이 GNU General Public License 버전 2의 조건에 따릅니다.
* 자유 소프트웨어 재단에서 발행;
*
* 이 프로그램은 유용하게 사용되길 바라는 마음에서 배포되며,
* 그러나 어떠한 보증도 제공하지 않습니다. 묵시적 보증도 없이
* 상품성 또는 특정 목적에의 적합성. 참조
* 자세한 내용은 GNU General Public License를 참조하십시오.
*
* GNU General Public License 사본을 받았어야 합니다.
* 이 프로그램과 함께; 그렇지 않은 경우 자유 소프트웨어에 쓰기
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ns3/object.h"
#include "ns3/uinteger.h"
#include "ns3/traced-value.h"
#include "ns3/trace-source-accessor.h"
#포함
네임스페이스 ns3 사용;
이 코드의 대부분은 여러분에게 매우 익숙할 것입니다. 위에서 언급한 것처럼 추적 시스템은
개체 및 특성 시스템을 많이 사용하므로 포함해야 합니다.
위의 처음 두 개 포함은 해당 시스템에 대한 선언을 명시적으로 가져옵니다. 너
핵심 모듈 헤더를 사용하여 모든 것을 한 번에 얻을 수 있지만 우리는 포함을 수행합니다.
이 모든 것이 실제로 얼마나 간단한지 설명하기 위해 여기에 명시적으로 설명합니다.
파일, 추적 값.h 데이터 추적에 필요한 선언을 가져옵니다.
가치 의미론을 따릅니다. 일반적으로 값 의미론은 단지
객체의 주소를 전달하는 대신 객체 자체를 주변에 전달합니다. 이게 다 뭐야 진짜
이는 실제로 TracedValue에 대한 모든 변경 사항을 추적할 수 있음을 의미합니다.
간단한 방법.
추적 시스템이 속성과 통합되고 속성이 개체와 함께 작동하므로
이 있어야합니다 NS-3 목적 추적 소스가 존재할 수 있도록 합니다. 다음 코드 조각
작업할 수 있는 간단한 개체를 선언하고 정의합니다.
클래스 MyObject : 공용 객체
{
공공의:
정적 TypeId GetTypeId(무효)
{
정적 TypeId tid = TypeId("MyObject")
.SetParent(객체::GetTypeId())
.AddConstructor ()
.AddTraceSource("MyInteger",
"추적할 정수 값입니다.",
MakeTraceSourceAccessor(&MyObject::m_myInt),
"ns3::추적::값::Int32Callback")
;
정시 반환;
}
내객체() {}
추적된 값 m_myInt;
};
추적과 관련하여 위의 두 가지 중요한 코드 라인은 .AddTraceSource
그리고 추적된 값 의 선언 m_myInt.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 .AddTraceSource 추적 소스를 연결하는 데 사용되는 "후크"를 제공합니다.
Config 시스템을 통해 외부 세계. 첫 번째 인수는 이 추적의 이름입니다.
Config 시스템에 표시되는 소스입니다. 두 번째 인수는 도움말 문자열입니다.
이제 세 번째 인수를 살펴보십시오. 사실에 초점을 맞추십시오. 논의 세 번째 주장 중:
&MyObject::m_myInt. 이것은 클래스에 추가되는 TracedValue입니다. 그것은
항상 클래스 데이터 멤버입니다. (마지막 인수는 형식 정의 위한
TracedValue 유형(문자열). 올바른 문서를 생성하는 데 사용됩니다.
특히 보다 일반적인 유형의 경우에 유용한 콜백 함수 서명입니다.
콜백.)
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 추적된 값<> 선언은 콜백을 구동하는 인프라를 제공합니다.
프로세스. 기본 값이 변경될 때마다 TracedValue 메커니즘은 다음을 제공합니다.
해당 변수의 이전 값과 새 값 모두, 이 경우에는 정수32_t 값. 추적
이 TracedValue에 대한 싱크 함수에는 서명이 필요합니다.
void (* TracedValueCallback)(const int32_t oldValue, const int32_t newValue);
이 추적 소스를 연결하는 모든 추적 싱크에는 이 서명이 있어야 합니다. 아래에서 논의하겠습니다.
다른 경우에 필요한 콜백 서명을 결정하는 방법.
물론, 계속해서 네번째.cc 우리는보다:
무효화
IntTrace(int32_t oldValue, int32_t newValue)
{
std::cout << "추적된 " << oldValue << "에서 " << newValue << std::endl;
}
이는 일치하는 추적 싱크의 정의입니다. 콜백에 직접적으로 대응됩니다.
함수 서명. 일단 연결되면 이 함수는 다음이 있을 때마다 호출됩니다.
추적된 값 변경.
이제 추적 소스와 추적 싱크를 보았습니다. 남은 것은 연결하는 코드입니다.
발생하는 싱크 소스 본관:
INT
메인(int argc, char *argv[])
{
포인트 myObject = CreateObject ();
myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace));
myObject->m_myInt = 1234;
}
여기서는 먼저 추적 소스가 있는 MyObject 인스턴스를 만듭니다.
다음 단계는 TraceConnectWithoutContext, 추적 간의 연결을 형성합니다.
소스 및 추적 싱크. 첫 번째 인수는 추적 소스 이름 "MyInteger"입니다.
우리는 위에서 보았습니다. 주목하세요 MakeCallback 템플릿 기능. 이 기능은 마법을 수행
기본을 만드는 데 필요합니다. NS-3 콜백 객체를 함수와 연결
인트레이스. TraceConnect 제공된 기능과
오버로드 운영자() "MyInteger" 속성이 참조하는 추적 변수에 있습니다.
이 연결이 이루어진 후 추적 소스는 제공된 콜백을 "실행"합니다.
기능.
이 모든 것을 가능하게 하는 코드는 물론 사소하지 않지만 핵심은 다음과 같습니다.
당신은 처럼 보이는 무언가를 준비하고 있습니다 pfi() 호출할 위의 예
추적 소스를 통해 의 선언 추적된 값 m_myInt; 개체에서
자체적으로 오버로드된 할당 연산자를 제공하는 데 필요한 마법을 수행합니다.
사용 운영자() 원하는 매개변수로 콜백을 실제로 호출합니다. 그만큼
.AddTraceSource 콜백을 구성 시스템에 연결하는 마법을 수행하고
TraceConnectWithoutContext 함수를 추적에 연결하는 마법을 수행합니다.
소스는 속성 이름으로 지정됩니다.
지금은 컨텍스트에 대한 부분을 무시하겠습니다.
마지막으로 값을 할당하는 줄은 m_myInt:
myObject->m_myInt = 1234;
~을 호출하는 것으로 해석되어야 한다. operator = 멤버 변수에 m_myInt 과
정수 1234 매개변수로 전달됩니다.
이후 m_myInt 하는 추적된 값, 이 연산자는 콜백을 실행하도록 정의됩니다.
void를 반환하고 두 개의 정수 값을 매개변수로 사용합니다. --- 이전 값과 새 값
문제의 정수에 대해. 이것이 바로 콜백의 함수 서명입니다.
우리가 제공한 기능 --- 인트레이스.
요약하면 추적 소스는 본질적으로 콜백 목록을 보유하는 변수입니다. ㅏ
트레이스 싱크는 콜백의 대상으로 사용되는 함수입니다. 속성 및 개체 유형
정보 시스템은 추적 소스를 추적 싱크에 연결하는 방법을 제공하는 데 사용됩니다.
추적 소스를 "적중"하는 행위는 추적 소스에서 연산자를 실행하는 것입니다.
콜백을 실행합니다. 이로 인해 관심을 등록하는 추적 싱크 콜백이 발생합니다.
소스에서 제공하는 매개변수를 사용하여 소스를 호출합니다.
이제 이 예제를 빌드하고 실행하면
$ ./waf --네 번째 실행
의 출력을 볼 수 있습니다. 인트레이스 추적 소스가 있는 즉시 함수 실행
때리다:
추적된 0 ~ 1234
코드를 실행했을 때, myObject->m_myInt = 1234;, 추적 소스가 실행되고
이전 및 이후 값을 추적 싱크에 자동으로 제공했습니다. 함수
인트레이스 그런 다음 이것을 표준 출력으로 인쇄했습니다.
연결하기 과 구성
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 TraceConnectWithoutContext 위의 간단한 예에 표시된 호출은 실제로 매우
시스템에서는 거의 사용되지 않습니다. 보다 일반적으로, 구성 하위 시스템은 추적을 선택하는 데 사용됩니다.
소위 말하는 것을 사용하여 시스템의 소스 구성 통로. 우리는 이것에 대한 예를 다음에서 보았습니다.
실험할 때 "CourseChange" 이벤트를 연결한 이전 섹션
세 번째.cc.
Mobility에서 코스 변경 정보를 인쇄하기 위해 추적 싱크를 정의했음을 기억하세요.
우리의 시뮬레이션 모델. 이제 이 기능이 무엇인지 훨씬 더 명확하게 알 수 있을 것입니다.
하기:
무효화
CourseChange(std::문자열 컨텍스트, Ptr 모델)
{
벡터 위치 = 모델->GetPosition();
NS_LOG_UNCOND(컨텍스트 <
" x = " << 위치.x << ", y = " << 위치.y);
}
"CourseChange" 추적 소스를 위의 추적 싱크에 연결할 때 다음을 사용했습니다.
사전 정의된 항목 간의 연결을 정렬할 때 소스를 지정하는 구성 경로
추적 소스 및 새 추적 싱크:
표준::ostringstream oss;
oss << "/NodeList/"
<< wifiStaNodes.Get (nWifi - 1)->GetId ()
<< "/$ns3::MobilityModel/CourseChange";
Config::Connect(oss.str(), MakeCallback(&CourseChange));
때때로 상대적으로 신비한 코드로 간주되는 것을 이해하고 시도해 봅시다.
설명을 위해 다음에서 반환된 노드 번호를 가정합니다. ID 가져오기() is
"7". 이 경우 위의 경로는 다음과 같습니다.
"/NodeList/7/$ns3::MobilityModel/CourseChange"
구성 경로의 마지막 세그먼트는 다음과 같아야 합니다. 속성 의 목적. 사실, 당신이 있었다면
에 대한 포인터 목적 "CourseChange"가 있는 것입니다. 속성 편리해요, 이렇게 써도 돼요
이전 예에서 했던 것처럼 말이죠. 이제 우리는 일반적으로
우리를 가리키는 포인터 노드 NodeContainer에서. 에서 세 번째.cc 예, 관심 노드
에 저장됩니다 wifiStaNodes NodeContainer. 사실 길을 정리하면서
우리는 이 컨테이너를 사용하여 Ptr 우리가 부르던 것 ID 가져오기(). 우리는 가질 수 있었다
이것을 사용 Ptr Connect 메소드를 직접 호출하려면 다음을 수행하십시오.
포인트 theObject = wifiStaNodes.Get(nWifi - 1);
theObject->TraceConnectWithoutContext("CourseChange", MakeCallback(&CourseChange));
. 세 번째.cc 예를 들어, 우리는 실제로 추가 "컨텍스트"가 함께 전달되기를 원했습니다.
콜백 매개변수(아래에 설명됨)를 사용하여 실제로 사용할 수 있습니다.
다음과 같은 동등한 코드:
포인트 theObject = wifiStaNodes.Get(nWifi - 1);
theObject->TraceConnect("CourseChange", MakeCallback(&CourseChange));
내부 코드는 다음과 같습니다. 구성::ConnectWithoutContext and 구성::연결
실제로 찾아보세요 포인트 그리고 적절한 전화 TraceConnect 가장 낮은 방법
수평.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 구성 함수는 체인을 나타내는 경로를 취합니다. 목적 포인터. 각 세그먼트
경로의 개체 특성에 해당합니다. 마지막 세그먼트는
관심 분야 및 객체를 포함하거나 찾으려면 이전 세그먼트를 입력해야 합니다. 그만큼 구성 암호
경로의 마지막 세그먼트에 도달할 때까지 이 경로를 구문 분석하고 "보행"합니다. 그때
마지막 세그먼트를 다음과 같이 해석합니다. 속성 걷는 동안 발견한 마지막 개체에 대해
길. 그만큼 구성 그런 다음 적절한 함수를 호출합니다. TraceConnect or
TraceConnectWithoutContext 최종 객체에 대한 메소드입니다. 잠시 후에 무슨 일이 일어나는지 봅시다
위 경로를 따라가시면 더 자세히 알 수 있습니다.
경로의 선행 "/" 문자는 소위 네임스페이스를 나타냅니다. 중 하나
구성 시스템에 미리 정의된 네임스페이스는 "NodeList"입니다.
시뮬레이션의 노드. 목록의 항목은 목록의 색인으로 참조됩니다.
"/NodeList/7"은 시뮬레이션 중에 생성된 노드 목록의 XNUMX번째 노드를 나타냅니다.
(리콜 지수는 다음에서 시작됩니다. 0'). 이 참고 is 실제로 a ``포인트 ` 그리고 그건 그렇고
의 하위 클래스 ns3::객체.
의 개체 모델 섹션에 설명된 대로 NS-3 수동, 우리는 널리 사용합니다
개체 집계. 이를 통해 서로 다른 개체 간의 연결을 형성할 수 있습니다.
복잡한 상속 트리를 구축하거나 어떤 객체가 포함될지 미리 결정하지 않고
노드의. 집계의 각 개체는 다른 개체에서 접근할 수 있습니다.
이 예에서 걷고 있는 다음 경로 세그먼트는 "$" 문자로 시작합니다. 이것
세그먼트가 객체 유형의 이름임을 구성 시스템에 나타냅니다.
객체 가져오기 해당 유형을 찾는 호출을 수행해야 합니다. 그것은 밝혀졌다 이동성 도우미
에 사용 세 번째.cc 모빌리티 모델을 각 모델에 통합하거나 연관시키도록 준비합니다.
무선 전화 노드. "$"를 추가하면
아마도 이전에 집계되었을 것입니다. 이것을 포인터를 전환하는 것으로 생각할 수 있습니다.
원래 Ptr 관련 이동성 모델에 대한 "/NodeList/7"에 지정된 대로 ---
유형의 것 ns3::모빌리티모델. 당신이 익숙하다면 객체 가져오기, 우리는 물었습니다
다음을 수행하는 시스템:
Ptr mobilityModel = 노드->GetObject ()
이제 경로의 마지막 개체에 있으므로 다음의 속성에 주의를 돌립니다.
그 개체. 그만큼 이동성 모델 클래스는 "CourseChange"라는 속성을 정의합니다. 당신은 할 수 있습니다
소스 코드를 보면 이를 알 수 있습니다. src/이동성/모델/이동성-model.cc and
즐겨 사용하는 편집기에서 "CourseChange"를 검색하세요. 당신은 찾아야한다
.AddTraceSource("코스 변경",
"위치 및/또는 속도 벡터의 값이 변경되었습니다",
MakeTraceSourceAccessor(&MobilityModel::m_courseChangeTrace),
"ns3::MobilityModel::CourseChangeCallback")
이 시점에서는 매우 친숙해 보일 것입니다.
기본 추적 변수의 해당 선언을 찾으면
이동성-model.h 당신은 발견할 것이다
추적된 콜백 > m_courseChangeTrace;
유형 선언 추적된 콜백 식별하다 m_courseChangeTrace 특별한 목록으로
위에서 설명한 Config 함수를 사용하여 후킹할 수 있는 콜백입니다. 그만큼 형식 정의 for
콜백 함수 서명도 헤더 파일에 정의되어 있습니다.
typedef void (* CourseChangeCallback)(Ptr * 모델);
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 이동성 모델 클래스는 공통 인터페이스를 제공하는 기본 클래스로 설계되었습니다.
모든 특정 하위 클래스. 파일 끝까지 검색하면 다음이 표시됩니다.
정의된 메서드 호출 NotifyCourseChange():
무효화
MobilityModel::NotifyCourseChange (void) const
{
m_courseChangeTrace(이);
}
파생 클래스는 지원을 위해 과정을 변경할 때마다 이 메서드를 호출합니다.
트레이싱. 이 메소드는 다음을 호출합니다. 운영자() 기초에 m_courseChangeTrace, 그
그러면 등록된 모든 콜백을 호출하여 모든 추적 싱크를 호출합니다.
Config 함수를 호출하여 추적 소스에 관심을 등록했습니다.
그래서 세 번째.cc 우리가 살펴본 예 중 하나에서 코스가 변경될 때마다
RandomWalk2d이동성모델 인스턴스가 설치되면 NotifyCourseChange() 전화
이는 이동성 모델 기본 클래스. 위에서 볼 수 있듯이 이는 호출됩니다. 운영자()
on m_courseChangeTrace그러면 등록된 추적 싱크를 호출합니다. 예에서
관심을 등록하는 유일한 코드는 구성 경로를 제공하는 코드였습니다.
따라서 코스변경 노드 번호 XNUMX에서 후크된 함수는
콜백만 호출되었습니다.
퍼즐의 마지막 조각은 "컨텍스트"입니다. 우리가 보고 있는 출력을 본 것을 기억하십시오.
다음과 같은 것 세 번째.cc:
/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.27897, y =
2.22677
출력의 첫 번째 부분은 컨텍스트입니다. 그것은 단순히 통과하는 길이다.
구성 코드는 추적 소스를 찾았습니다. 우리가 살펴본 경우에는 다음이 있을 수 있습니다.
가 있는 노드 수에 해당하는 시스템의 추적 소스 수
모빌리티 모델. 어떤 추적 소스가 실제로 있는지 식별할 수 있는 방법이 필요합니다.
콜백을 실행한 것입니다. 가장 쉬운 방법은 다음과 연결하는 것입니다. 구성::연결, 대신
of 구성::ConnectWithoutContext.
발견 지우면 좋을거같음 . SM
추적 시스템의 새로운 사용자에게 필연적으로 나타나는 첫 번째 질문은, "좋아요,
I 알고있다 그 가 절대로 필요한 것 be 더듬다 소스 in 전에, 시뮬레이션 핵심, 비자 면제 프로그램에 해당하는 국가의 시민권을 가지고 있지만 방법 do I 발견 아웃 뭐
더듬다 소스 are 가능 에 나?"
두 번째 질문은, "좋아요, I 발견 a 더듬다 출처, 방법 do I 그림 아웃 전에, 구성 통로
에 사용 언제 I 잇다 에 그것?"
세 번째 질문은, "좋아요, I 발견 a 더듬다 and 전에, 구성 통로, 방법 do I 그림
아웃 뭐 전에, return 유형 and 형식적인 인수 of my 콜백 기능 필요한 것 에 BE?"
네 번째 질문은, "좋아요, I 입력 그 모든 in and 있어 이 엄청나게 기괴한 오류
메시지, 뭐 in 전에, 세계 하지 it 평균?"
우리는 이들 각각을 차례로 다룰 것입니다.
유효한 지우면 좋을거같음 . SM
괜찮아, I 알고있다 그 가 절대로 필요한 것 be 더듬다 소스 in 전에, 시뮬레이션 핵심, 비자 면제 프로그램에 해당하는 국가의 시민권을 가지고 있지만 방법 do I 발견
아웃 뭐 더듬다 소스 are 가능 에 나를?
첫 번째 질문에 대한 답은 다음에서 찾을 수 있습니다. NS-3 API 문서. 당신이에 가면
프로젝트 웹 사이트, NS-3 프로젝트, 탐색 메뉴에서 "문서"에 대한 링크를 찾을 수 있습니다.
술집. 이 링크를 선택하면 설명서 페이지로 이동합니다. 이있다
최신 안정 버전에 대한 문서로 이동하는 "최신 릴리스" 링크
방출 NS-3. "API 문서" 링크를 선택하면 다음 페이지로 이동됩니다.
NS-3 API 설명서 페이지.
사이드바에서 다음으로 시작하는 계층 구조를 볼 수 있습니다.
· NS-3
· ns-3 문서
· 모든 TraceSource
· 모든 속성
· 모든 GlobalValues
여기서 관심 있는 목록은 "모든 TraceSources"입니다. 계속해서 해당 링크를 선택하세요.
아마도 그리 놀랍지도 않게 사용 가능한 모든 추적 소스 목록이 표시될 것입니다.
in NS-3.
예를 들어 아래로 스크롤하여 ns3::모빌리티모델. 다음에 대한 항목을 찾을 수 있습니다.
CourseChange: 위치 및/또는 속도 벡터의 값이 변경되었습니다.
이것을 우리가 사용한 추적 소스로 인식해야 합니다. 세 번째.cc 예. 정독하다
이 목록이 도움이 될 것입니다.
구성 경로
괜찮아, I 발견 a 더듬다 출처, 방법 do I 그림 아웃 전에, 구성 통로 에 사용 언제 I 잇다 에
이것?
관심 있는 개체를 알고 있는 경우 해당 개체에 대한 "자세한 설명" 섹션을 참조하세요.
클래스는 사용 가능한 모든 추적 소스를 나열합니다. 예를 들어, "All
TraceSources'를 클릭하세요. ns3::모빌리티모델 링크를 클릭하면
에 대한 문서 이동성 모델 수업. 거의 페이지 상단에 한 줄이 있습니다.
수업에 대한 간략한 설명이며 "더 보기..." 링크로 끝납니다. 건너뛰려면 이 링크를 클릭하세요.
API 요약을 확인하고 클래스의 "자세한 설명"으로 이동하세요. 의 끝에서
설명은 (최대) 세 개의 목록입니다.
· 구성 경로: 이 클래스의 일반적인 구성 경로 목록입니다.
· Attributes: 이 클래스가 제공하는 모든 속성의 목록입니다.
· TraceSource: 이 클래스에서 사용할 수 있는 모든 TraceSource의 목록입니다.
먼저 구성 경로에 대해 논의하겠습니다.
"All"에서 "CourseChange" 추적 소스를 찾았다고 가정해 보겠습니다.
TraceSources" 목록에 연결하는 방법을 알고 싶습니다.
(다시 말하지만, 세 번째.cc 예) 한 ns3::RandomWalk2d이동성모델. 그래서 어느쪽이든
"All TraceSources" 목록에서 클래스 이름을 클릭하거나
ns3::RandomWalk2d이동성모델 "클래스 목록"에서. 어느 쪽이든 지금은 살펴봐야 합니다.
"ns3::RandomWalk2dMobilityModel 클래스 참조" 페이지에서.
이제 "자세한 설명" 섹션까지 아래로 스크롤하면
클래스 메서드 및 속성(또는 클래스 끝에 있는 "자세히..." 링크를 클릭하세요.)
페이지 상단의 간략한 설명)에 대한 전체 문서를 볼 수 있습니다.
수업. 계속해서 아래로 스크롤하여 "구성 경로" 목록을 찾습니다.
구성 경로
ns3::RandomWalk2d이동성모델 다음 경로를 통해 액세스할 수 있습니다.
구성::설정 and 구성::연결:
· "/NodeList/[i]/$ns3::MobilityModel/$ns3::RandomWalk2dMobilityModel"
문서에는 다음 위치로 이동하는 방법이 나와 있습니다. RandomWalk2d이동성모델 물체. 비교하다
위의 문자열과 예제 코드에서 실제로 사용한 문자열:
"/NodeList/7/$ns3::MobilityModel"
차이점은 두 개가 있다는 사실 때문입니다. 객체 가져오기 호출은 발견된 문자열에 내포되어 있습니다.
문서에서. 첫 번째는 $ns3::이동성모델 에 대한 집계를 쿼리합니다.
기본 클래스. 두 번째 암시 객체 가져오기 을 요구하다 $ns3::RandomWalk2dMobilityModel,
기본 클래스를 구체적인 구현 클래스로 캐스팅하는 데 사용됩니다. 문서
이 두 가지 작업을 모두 보여줍니다. 실제 추적 소스는 다음과 같습니다.
looking for 는 기본 클래스에서 찾을 수 있습니다.
추적 소스 목록에 대한 "자세한 설명" 섹션을 자세히 살펴보십시오.
당신은 발견 할 것이다
이 유형에 대해 정의된 TraceSource가 없습니다.
TraceSource 한정된 in 부모의 수업 ``ns3::이동성모델``
· 코스변경: 위치 및/또는 속도 벡터의 값이 변경되었습니다.
콜백 서명: ns3::MobilityModel::CourseChangeCallback
이것이 바로 당신이 알아야 할 것입니다. 관심 있는 추적 소스는 다음에서 찾을 수 있습니다.
ns3::모빌리티모델 (어차피 당신도 알고 있었겠지만). 이 API의 흥미로운 점은
문서에 따르면 위의 구성 경로에 추가 캐스트가 필요하지 않다고 나와 있습니다.
추적 소스가 실제로 기본 클래스에 있으므로 구체적인 클래스로 이동합니다.
그러므로 추가적인 객체 가져오기 필수는 아니며 다음 경로를 사용하면 됩니다.
"/NodeList/[i]/$ns3::MobilityModel"
이는 예제 경로와 완벽하게 일치합니다.
"/NodeList/7/$ns3::MobilityModel"
여담으로, 구성 경로를 찾는 또 다른 방법은 다음과 같습니다. GREP 주위에 NS-3 코드베이스
이미 알아낸 누군가를 위해. 항상 다른 사람의 것을 복사하려고 노력해야 합니다.
자신의 코드를 작성하기 전에 작업 코드. 다음과 같이 시도해 보세요.
$ 찾기 . -이름 '*.cc' | xargs grep 과정 변경 | grep 연결
작업 코드와 함께 답을 찾을 수 있습니다. 예를 들어, 이 경우에는
src/이동성/예제/main-random-topology.cc 당신이 사용하기를 기다리는 무언가가 있습니다:
구성::연결("/NodeList/*/$ns3::MobilityModel/CourseChange",
MakeCallback(&CourseChange));
잠시 후에 이 예제로 돌아갑니다.
콜백 서명
괜찮아, I 발견 a 더듬다 and 전에, 구성 통로, 방법 do I 그림 아웃 뭐 전에, return 유형
and 형식적인 인수 of my 콜백 기능 필요한 것 에 있다?
가장 쉬운 방법은 콜백 서명을 검사하는 것입니다. 형식 정의, 이는
클래스에 대한 "자세한 설명"에서 추적 소스의 "콜백 서명"은 다음과 같습니다.
위에 표시된.
에서 "CourseChange" 추적 소스 항목 반복 ns3::RandomWalk2d이동성모델 we
있다:
· 코스변경: 위치 및/또는 속도 벡터의 값이 변경되었습니다.
콜백 서명: ns3::MobilityModel::CourseChangeCallback
콜백 서명은 관련 링크로 제공됩니다. 형식 정의, 우리가 찾는 곳
형식 정의 무효화 (* CourseChangeCallback)(const 표준::문자열 문맥, 포인트
모빌리티모델> * 모델);
추적된 콜백 코스 변경 알림에 대한 서명입니다.
콜백이 다음을 사용하여 연결된 경우 컨텍스트 없이 연결 생략 문맥 의 주장
서명.
파라미터:
[in] context Trace 소스에서 제공하는 컨텍스트 문자열입니다.
[in] model 경로를 변경하는 MobilityModel입니다.
위와 같이 사용중인 것을 보려면 GREP 주위에 NS-3 예를 들어 코드베이스를 참조하세요. 예
위에서, ~로부터 src/이동성/예제/main-random-topology.cc, "CourseChange"를 연결합니다.
소스를 추적 코스변경 동일한 파일의 기능:
정적 공극
CourseChange(std::문자열 컨텍스트, Ptr 모델)
{
...
}
이 기능은 다음과 같습니다.
· 잠시 후에 설명할 "컨텍스트" 문자열 인수를 사용합니다. (콜백의 경우
를 사용하여 연결됩니다. 컨텍스트 없이 연결 기능 문맥 주장은
생략.)
· 이동성 모델 마지막 인수로 제공됨(또는 다음과 같은 경우
컨텍스트 없이 연결 사용).
· 반품 무효화.
우연히 콜백 서명이 문서화되지 않았고 이에 대한 예제도 없는 경우
올바른 콜백 함수 서명을 결정하는 것은 어려울 수 있습니다.
실제로 소스 코드에서 파악하십시오.
코드 연습을 시작하기 전에 친절하게 간단한 방법만 알려드리겠습니다.
이것을 알아내기 위해: 콜백의 반환 값은 항상 무효화. 공식
매개변수 목록 추적된 콜백 템플릿 매개변수 목록에서 찾을 수 있습니다.
선언. 현재 예에서는 다음과 같습니다. 이동성-model.h우리가있는 곳
이전에 다음을 발견했습니다.
추적된 콜백 > m_courseChangeTrace;
템플릿 매개변수 목록 사이에는 일대일 대응이 있습니다.
콜백 함수의 선언 및 형식 인수입니다. 여기, 하나 있어요
템플릿 매개변수는 포인트 모빌리티모델>. 이것은 당신에게
void를 반환하고 a를 취하는 함수 포인트 모빌리티모델>. 예를 들면 :
무효화
코스변경(Ptr 모델)
{
...
}
네가 원한다면 그게 전부야 구성::ConnectWithoutContext. 맥락을 원하시면,
당신은 필요 구성::연결 문자열 컨텍스트를 취하는 콜백 함수를 사용한 다음
템플릿 인수:
무효화
CourseChange(const std::string 컨텍스트, Ptr 모델)
{
...
}
당신이 당신의 CourseChange콜백 기능은 귀하의 앱에서만 볼 수 있습니다.
로컬 파일에 키워드를 추가할 수 있습니다. 정적 인 그리고 생각해 내다 :
정적 공극
CourseChange(const std::string 경로, Ptr 모델)
{
...
}
이것은 우리가 세 번째.cc 예.
실시
이 섹션은 전적으로 선택 사항입니다. 특히 그런 사람들에게는 울퉁불퉁한 여정이 될 것입니다.
템플릿의 세부 사항에 익숙하지 않습니다. 그러나 이 과정을 통과하면 다음과 같은 결과를 얻게 됩니다.
많은 일을 아주 잘 처리해 NS-3 낮은 수준의 관용어.
그래서 다시 콜백 함수의 서명이 필요한지 알아 봅시다.
"CourseChange" 추적 소스입니다. 고통스럽겠지만 이것만 하면 된다
한 번. 이 과정을 거치고 나면 다음을 볼 수 있습니다. 추적된 콜백 and
이해하다.
가장 먼저 살펴봐야 할 것은 추적 소스의 선언입니다. 그것을 기억해
이것은 안에 있다 이동성-model.h, 이전에 찾은 내용은 다음과 같습니다.
추적된 콜백 > m_courseChangeTrace;
이 선언은 템플릿용입니다. 템플릿 매개변수는 꺾쇠괄호 안에 있습니다.
그래서 우리는 그것이 무엇인지 알아내는 데 정말로 관심이 있습니다. 추적된콜백<> 이다. 당신이 가지고 있다면
이게 어디서 발견될지는 전혀 모르겠는데, GREP 당신의 친구입니다.
우리는 아마도 다음과 같은 종류의 선언에 관심이 있을 것입니다. NS-3 출처, 그래서
먼저 로 변경 SRC 예배 규칙서. 그런 다음 이 선언이
일종의 헤더 파일에 있어야 하므로 GREP 그것을 위해:
$ 찾기 . -이름 '*.h' | xargs grep TracedCallback
303줄이 날아가는 것을 볼 수 있습니다. wc 얼마나 나빴는지 알아보기 위해). 하지만
그것은 많은 것처럼 보일 수도 있지만 실제로는 많은 것이 아닙니다. 출력을 파이프로 연결하면 됩니다. 배우기 and
그것을 통해 스캔을 시작합니다. 첫 페이지에서 매우 의심스러운 몇 가지를 볼 수 있습니다.
템플릿처럼 보이는 것.
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::TracedCallback ()
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext (c ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Connect (const CallbackB ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::DisconnectWithoutContext ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Disconnect (const Callba ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (void) const ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1) const ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
이 모든 것이 헤더 파일에서 나온 것으로 밝혀졌습니다. 추적된 콜백.h 어떤 소리가 나는지
매우 유망합니다. 그런 다음 다음을 살펴볼 수 있습니다. 이동성-model.h 그리고 줄이 있는 걸 보세요
이 직감을 확인합니다.
#include "ns3/traced-callback.h"
물론 다른 방향에서 이 문제를 살펴보고 다음을 살펴보는 것부터 시작할 수도 있습니다.
에 포함됩니다 이동성-model.h 그리고 다음이 포함된 것을 확인했습니다. 추적된 콜백.h and
이 파일이 원하는 파일이어야 한다고 추론합니다.
두 경우 모두 다음 단계는 다음을 살펴보는 것입니다. src/코어/모델/traced-callback.h in
무슨 일이 일어나고 있는지 확인하기 위해 가장 좋아하는 편집자.
파일 상단에 위안이 될 만한 설명이 표시됩니다.
ns3::TracedCallback은 일반적인 ns3::Callback과 거의 똑같은 API를 가지고 있지만
호출을 단일 함수로 전달하는 대신(일반적으로 ns3::Callback이 그렇듯이),
호출을 ns3::Callback 체인으로 전달합니다.
이것은 매우 친숙하게 들릴 것이며 올바른 길을 가고 있음을 알려줄 것입니다.
이 댓글 바로 뒤에는 다음이 표시됩니다.
주형
typename T3 = 비어 있음, typename T4 = 비어 있음,
typename T5 = 비어 있음, typename T6 = 비어 있음,
유형 이름 T7 = 비어 있음, 유형 이름 T8 = 비어 있음>
클래스 TracedCallback
{
...
이는 TracedCallback이 템플릿 클래스임을 알려줍니다. 여덟 가지 가능한 유형이 있습니다.
기본값이 있는 매개변수. 돌아가서 이것을 당신의 선언과 비교하십시오.
이해하려고:
추적된 콜백 > m_courseChangeTrace;
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 유형 이름 T1 템플릿 클래스 선언은 다음에 해당합니다. 포인트
모빌리티모델> 위 선언에서. 다른 모든 유형 매개변수는 다음과 같이 유지됩니다.
기본값. 생성자를 보면 실제로 많은 것을 알 수 없습니다. 한 곳은
콜백 함수와 추적 시스템 간의 연결이
인간을 연결하기 and 컨텍스트 없이 연결 기능. 아래로 스크롤하면 다음과 같은 내용이 표시됩니다.
컨텍스트 없이 연결 방법:
주형
유형 이름 T3, 유형 이름 T4,
유형 이름 T5, 유형 이름 T6,
typename T7, typename T8>
무효화
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext ...
{
Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> cb;
cb.할당(콜백);
m_callbackList.push_back(cb);
}
당신은 지금 짐승의 뱃속에 있습니다. 템플릿이 인스턴스화되면
위의 선언은 컴파일러가 대체합니다. T1 과 포인트 모빌리티모델>.
무효화
추적 콜백 ::ConnectWithoutContext ... cb
{
콜백 > CB;
cb.할당(콜백);
m_callbackList.push_back(cb);
}
이제 우리가 이야기한 모든 구현을 볼 수 있습니다. 코드
올바른 유형의 콜백을 생성하고 여기에 함수를 할당합니다. 이것이
동등한 피피 = 마이펑션 이 섹션의 시작 부분에서 논의했습니다. 코드
그런 다음 이 소스에 대한 콜백 목록에 콜백을 추가합니다. 남은 건
콜백의 정의를 살펴보겠습니다. 같은 것을 사용하여 GREP 우리가 찾던 트릭
추적된 콜백, 당신은 파일을 찾을 수 있습니다 ./core/callback.h 우리가 그 사람이야
살펴볼 필요가 있습니다.
파일을 자세히 살펴보면 아마도 거의 이해할 수 없는 내용이 많이 보일 것입니다.
템플릿 코드. 결국 콜백에 대한 일부 API 설명서에 도달하게 됩니다.
그러나 템플릿 클래스. 다행히 영어가 있습니다.
콜백 템플릿 클래스.
이 클래스 템플릿은 Functor 디자인 패턴을 구현합니다. 선언하는 데 사용됩니다.
유형 콜백:
· 선택 사항이 아닌 첫 번째 템플릿 인수는 콜백의 반환 유형을 나타냅니다.
· 나머지(선택적) 템플릿 인수는 후속 템플릿의 유형을 나타냅니다.
콜백에 대한 인수.
· 최대 XNUMX개의 인수가 지원됩니다.
우리는 무엇이 무엇인지 알아내려고 노력하고 있습니다.
콜백 > CB;
선언 수단. 이제 우리는 첫 번째(선택 사항 아님)
템플릿 인수, 무효화는 콜백의 반환 유형을 나타냅니다. 두번째
(선택사항) 템플릿 인수, 포인트 모빌리티모델> 첫 번째 유형을 나타냅니다.
콜백에 대한 인수입니다.
문제의 콜백은 추적 이벤트를 수신하는 기능입니다. 이것으로부터 당신은 할 수 있습니다
반환하는 함수가 필요하다고 추론 무효화 그리고 걸립니다 포인트 모빌리티모델>.
예를 들어,
무효화
CourseChangeCallback(Ptr 모델)
{
...
}
네가 원한다면 그게 전부야 구성::ConnectWithoutContext. 맥락을 원하시면,
당신은 필요 구성::연결 문자열 컨텍스트를 사용하는 콜백 함수를 사용합니다. 이것
왜냐하면 연결하기 기능이 사용자에게 컨텍스트를 제공합니다. 너는 필요할거야:
무효화
CourseChangeCallback(std::문자열 컨텍스트, Ptr 모델)
{
...
}
당신이 당신의 CourseChange콜백 로컬 파일에만 표시됩니다.
키워드를 추가할 수 있습니다 정적 인 그리고 생각해 내다 :
정적 공극
CourseChangeCallback(std::문자열 경로, Ptr 모델)
{
...
}
이것은 우리가 세 번째.cc 예. 아마도 당신은 지금 돌아가서
이전 섹션을 다시 읽으십시오(Take My Word for It).
콜백 구현에 대한 자세한 내용에 관심이 있으시면 언제든지 문의해 주세요.
를 살펴보기 위해 NS-3 수동. 그들은 가장 자주 사용되는 구조 중 하나입니다.
낮은 수준의 부분 NS-3. 내 생각에는 그것은 꽤 우아한 일이다.
추적된 값
이 섹션의 앞부분에서 우리는 다음을 사용하는 간단한 코드를 제시했습니다.
추적된 값 추적 코드의 기본을 보여줍니다. 우리는 그냥 얼버무렸어
TracedValue가 실제로 무엇이며 이에 대한 반환 유형 및 공식 인수를 찾는 방법
콜백.
앞서 언급했듯이 파일은 추적 값.h 추적에 필요한 선언을 가져옵니다.
가치 의미론을 따르는 데이터. 일반적으로 값 의미론은 다음을 의미합니다.
객체의 주소를 전달하는 대신 객체 자체를 전달합니다. 우리는 연장한다
할당 스타일 연산자의 전체 집합을 포함해야 하는 요구 사항은 다음과 같습니다.
POD(Plain-Old-Data) 유형에 대해 미리 정의됨:
┌────────────────────────────────┬─────────────┐
│operator = (과제) │ │
├────────────────────────────────┼─────────────┤
│연산자*= │ 연산자/= │
├────────────────────────────────┼─────────────┤
│연산자+= │ 연산자-= │
├────────────────────────────────┼─────────────┤
│연산자++ (접두사 및 │ │
│접미사) │ │
├────────────────────────────────┼─────────────┤
│운영자-- (접두사 및 │ │
│접미사) │ │
├────────────────────────────────┼─────────────┤
│연산자<<= │ 연산자>>= │
├────────────────────────────────┼─────────────┤
│연산자&= │ 연산자|= │
├────────────────────────────────┼─────────────┤
│연산자%= │ 연산자^= │
└────────────────────────────────┴─────────────┘
이것이 실제로 의미하는 바는 해당 항목을 사용하여 이루어진 모든 변경 사항을 추적할 수 있다는 것입니다.
값 의미를 갖는 C++ 개체에 대한 연산자입니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 추적된 값<> 위에서 본 선언은
위에서 언급한 연산자를 사용하고 콜백 프로세스를 구동합니다. 연산자를 사용하는 경우
위의 추적된 값 해당 변수의 이전 값과 새 값을 모두 제공합니다.
이 경우 정수32_t 값. 의 검사로 추적된 값 선언, 우리는 알고있다
추적 싱크 함수에는 인수가 있습니다. (상수 정수32_t 오래된 값, const를 정수32_t 새로운 값).
에 대한 반환 유형 추적된 값 콜백 함수는 항상 무효화, 그래서 예상되는
콜백 서명은 다음과 같습니다.
void (* TracedValueCallback)(const int32_t oldValue, const int32_t newValue);
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 .AddTraceSource 인간을 유형 ID 가져오기 방법은 연결에 사용되는 "후크"를 제공합니다.
Config 시스템을 통해 소스를 외부 세계로 추적합니다. 우리는 이미 논의
처음 세 가지 도구 추적 소스 추가: 구성 시스템의 속성 이름, 도움말
문자열 및 TracedValue 클래스 데이터 멤버의 주소입니다.
예제의 마지막 문자열 인수 "ns3::Traced::Value::Int32"는
형식 정의 콜백 함수 서명용. 이러한 서명을 정의해야 합니다.
정규화된 유형 이름을 추적 소스 추가, API 문서에서 다음을 수행할 수 있습니다.
추적 소스를 함수 서명에 연결합니다. TracedValue의 경우 서명은 다음과 같습니다.
똑바로; TracedCallbacks의 경우 API 문서가 실제로 도움이 되는 것을 이미 확인했습니다.
부동산 예시
TCP에 관한 가장 잘 알려진 책 중 하나에서 가져온 예를 들어 보겠습니다. "TCP/IP
W. Richard Stevens의 Illustrated, Volume 1: The Protocols"는 고전입니다. 방금 뒤집었습니다.
책이 열리고 혼잡 창과 시퀀스의 멋진 플롯을 가로질러 실행되었습니다.
366페이지의 숫자 대 시간. Stevens는 이를 "그림 21.10. cwnd 및 시간의 값"이라고 부릅니다.
데이터가 전송되는 동안 시퀀스 번호를 보내세요." cwnd 부분을 다시 만들어 보겠습니다.
그 음모의 NS-3 추적 시스템을 사용하고 그누플롯.
유효한 지우면 좋을거같음 . SM
가장 먼저 생각해야 할 것은 데이터를 어떻게 가져올 것인가 하는 것입니다. 우리는 무엇입니까
추적해야합니까? 따라서 "모든 추적 소스" 목록을 참조하여 작업해야 할 사항을 확인하겠습니다.
와 함께. 이 내용은 다음에서 찾을 수 있음을 기억하세요. NS-3 API 문서. 스크롤을 해보면
목록에서 결국 다음을 찾을 수 있습니다.
ns3::TcpNewReno
· 혼잡 창: TCP 연결의 혼잡 창
· SlowStart 임계값: TCP 느린 시작 임계값(바이트)
그것은 NS-3 TCP 구현은 (대부분) 파일에 존재합니다.
src/인터넷/모델/tcp-socket-base.cc 혼잡 제어 변형은 다음과 같은 파일에 있습니다.
as src/인터넷/모델/tcp-newreno.cc. 이것을 모른다면 a 사전,
재귀 GREP 장난:
$ 찾기 . -이름 '*.cc' | xargs grep -i tcp
해당 파일을 가리키는 tcp 인스턴스의 페이지를 하나씩 찾을 수 있습니다.
에 대한 수업 문서 가져오기 TcpNewReno 그리고 목록으로 건너뛰기
당신이 찾을 TraceSource
TraceSource
· 혼잡 창: TCP 연결의 혼잡 구간
콜백 서명: ns3::추적::값::Uint322Callback
콜백을 클릭하면 형식 정의 링크를 클릭하면 이제 예상할 수 있는 서명이 표시됩니다.
typedef void(* ns3::Traced::Value::Int32Callback)(const int32_t oldValue, const int32_t newValue)
이제 이 코드를 완전히 이해해야 합니다. 만약 우리가 포인터를 가지고 있다면 TcpNewReno,
우리는 할 수있다. TraceConnect 적절한 "CongestionWindow" 추적 소스를 제공하는 경우
콜백 대상. 이는 간단한 예에서 본 것과 동일한 종류의 추적 소스입니다.
우리가 이야기하고 있는 것을 제외하고 이 섹션의 시작 부분에 uint32_t 대신
정수32_t. 그리고 우리는 그 서명과 함께 콜백 함수를 제공해야 한다는 것을 알고 있습니다.
발견 예
수정할 수 있는 작업 코드를 찾는 것이 항상 가장 좋습니다.
처음부터 시작하는 것보다. 따라서 이제 비즈니스의 첫 번째 순서는 다음과 같은 코드를 찾는 것입니다.
이미 "CongestionWindow" 추적 소스를 연결하고 수정할 수 있는지 확인합니다. 평소와 같이
GREP 당신의 친구입니다:
$ 찾기 . -이름 '*.cc' | xargs grep CongestionWindow
이는 몇 가지 유망한 후보자를 지적할 것입니다: 예/tcp/tcp-large-transfer.cc
and src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc.
우리는 아직 테스트 코드를 방문하지 않았으므로 그곳을 살펴보겠습니다. 당신은
일반적으로 테스트 코드가 상당히 작다는 것을 알 수 있으므로 이는 아마도 매우 좋은 선택일 것입니다.
엽니다 src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc 좋아하는 편집기에서 다음을 검색하세요.
"혼잡 창". 당신은 발견 할 것이다,
ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow",
MakeCallback(&Ns3TcpCwndTestCase1::CwndChange, 이));
이것은 당신에게 매우 친숙해 보일 것입니다. 위에서 언급했듯이
TcpNewReno, 우리는 할 수 있었다 TraceConnect "CongestionWindow" 추적 소스로 이동합니다. 바로 그거야
우리가 여기에 있는 것; 그래서 이 코드 라인이 정확히 우리가 원하는 것을 한다는 것이 밝혀졌습니다.
계속해서 이 함수에서 필요한 코드를 추출해 보겠습니다(Ns3TcpCwndTestCase1::도런
(무효의)). 이 함수를 보면 마치 NS-3
스크립트. 그것이 정확히 무엇인지 밝혀졌습니다. 테스트에 의해 실행되는 스크립트입니다.
프레임워크를 꺼내어 포장하면 됩니다. 본관 대신에 도런. 꽤
이 과정을 단계별로 진행하는 것보다 포팅 결과로 생성된 파일을 제공했습니다.
이 테스트는 네이티브로 돌아갑니다. NS-3 스크립트 -- 예제/튜토리얼/fifth.cc.
동적 더듬다 지우면 좋을거같음 . SM
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 다섯번째.cc 예는 반드시 이해해야 하는 매우 중요한 규칙을 보여줍니다.
모든 종류의 추적 소스를 사용하기 전에 다음과 같은 대상이 있는지 확인해야 합니다.
구성::연결 명령을 사용하기 전에 존재합니다. 이것은 말하는 것과 다르지 않다.
개체를 호출하기 전에 개체를 인스턴스화해야 합니다. 이것이 명백해 보일지 모르지만
이런 식으로 말하면 처음으로 시스템을 사용하려는 많은 사람들이 걸려 넘어집니다.
시간.
잠시 기본으로 돌아가자. 에 존재하는 세 가지 기본 실행 단계가 있습니다.
어떤 NS-3 스크립트. 첫 번째 단계는 "구성 시간" 또는 "설정"이라고도 합니다.
시간"으로 표시되며 해당 기간 동안 존재합니다. 본관 스크립트 기능이 실행 중이지만
전에 시뮬레이터::실행 호출됩니다. 두 번째 단계는 "시뮬레이션 시간"이라고도 합니다.
그리고 다음과 같은 기간 동안 존재합니다. 시뮬레이터::실행 적극적으로 행사를 진행하고 있습니다.
시뮬레이션 실행이 완료된 후, 시뮬레이터::실행 다시 제어권을 반환합니다
전에, 본관 기능. 이런 일이 발생하면 스크립트는 "Teardown"
페이즈(Phase)'는 설정 과정에서 생성된 구조물과 물체를 분해하고,
풀어 놓았다.
아마도 추적 시스템을 사용하려고 할 때 저지르는 가장 일반적인 실수는 다음과 같다고 가정하는 것입니다.
동적으로 생성된 엔터티 ...동안 시뮬레이션 시간 구성 중에 사용할 수 있습니다.
시간. 특히, NS-3 소켓 자주 생성되는 동적 개체입니다. 어플리케이션 에
의사 소통 노드. NS-3 어플리케이션 항상 '시작 시간'과 '중지'가 있습니다.
시간"과 관련이 있습니다. 대부분의 경우, 어플리케이션 시도하지 않을 것입니다
동적 객체를 생성하려면 응용 프로그램 시작 메서드는 일부 "시작"에서 호출됩니다.
시간". 이는 앱이 실행되기 전에 시뮬레이션이 완전히 구성되었는지 확인하기 위한 것입니다.
(존재하지 않는 노드에 연결을 시도하면 어떻게 될까요?)
아직 구성하는 동안인가요?). 결과적으로 구성 단계에서는 다음을 수행할 수 없습니다.
추적 소스 중 하나가 동적으로 생성된 경우 추적 소스에 연결합니다.
시뮬레이션.
이 수수께끼에 대한 두 가지 해결책은 다음과 같습니다.
1. 동적 객체가 생성된 후 실행되는 시뮬레이터 이벤트를 생성하고
해당 이벤트가 실행되는 시점을 추적합니다. 또는
2. 구성 시 동적 개체를 생성하고 연결한 다음 해당 개체를
시뮬레이션 시간 동안 사용할 시스템.
우리는 두 번째 접근 방식을 취했습니다. 다섯번째.cc 예. 이 결정으로 인해 우리는
전에, 마이앱 어플리케이션, 그 전체 목적은 소켓 매개 변수로.
연습 : 다섯번째.cc
이제 혼잡도를 분석하여 구성한 예제 프로그램을 살펴보겠습니다.
창 테스트. 열려 있는 예제/튜토리얼/fifth.cc 좋아하는 편집기에서. 넌 봐야 해
친숙해 보이는 코드:
/* -*- 모드:C++; c-파일 스타일:"gnu"; 들여쓰기 탭 모드:nil; -*- */
/*
* 이 프로그램은 무료 소프트웨어입니다. 재배포 및/또는 수정할 수 있습니다.
* 다음과 같이 GNU General Public License 버전 2의 조건에 따릅니다.
* 자유 소프트웨어 재단에서 발행;
*
* 이 프로그램은 유용하게 사용되길 바라는 마음에서 배포되며,
* 그러나 어떠한 보증도 제공하지 않습니다. 묵시적 보증도 없이
* 상품성 또는 특정 목적에의 적합성. 참조
* 자세한 내용은 GNU General Public License를 참조하십시오.
*
* GNU General Public License 사본을 받았어야 합니다.
* 이 프로그램과 함께; 그렇지 않은 경우 자유 소프트웨어에 쓰기
* 재단, 포함., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#포함하다
#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"
네임스페이스 ns3 사용;
NS_LOG_COMPONENT_DEFINE("다섯 번째 스크립트 예제");
이 내용은 모두 다루었으므로 다시 설명하지 않겠습니다. 소스의 다음 줄은
위에서 설명한 문제를 해결하는 네트워크 그림 및 설명 소켓.
// ================================================ ===========================
//
// 노드 0 노드 1
// +----------------+ +----------------+
// | NS-3 TCP | | NS-3 TCP |
// +----------------+ +----------------+
// | 10.1.1.1 | | 10.1.1.2 |
// +----------------+ +----------------+
// | 지점 간 | | 지점 간 |
// +----------------+ +----------------+
// | |
// +---------+
// 5Mbps, 2ms
//
//
// ns-3 TCP 혼잡 창의 변경 사항을 살펴보고자 합니다. 우리는 필요합니다
// 흐름을 시작하고 CongestionWindow 속성을 소켓에 연결합니다.
// 발신자. 일반적으로 온-오프 애플리케이션을 사용하여
// 흐름이지만 여기에는 몇 가지 문제가 있습니다. 먼저 온오프 소켓입니다.
// 애플리케이션은 애플리케이션 시작 시간까지 생성되지 않으므로 생성되지 않습니다.
// 구성 시 (이제) 소켓을 연결할 수 있습니다. 둘째, 비록 우리가
// 시작 시간 이후에 호출을 준비할 수 있습니다. 소켓은 공개되지 않으므로
// 도달할 수 없습니다.
//
// 따라서 우리는 다음 작업을 수행하는 간단한 버전의 온-오프 애플리케이션을 만들 수 있습니다.
// 우리는 원합니다. 플러스 측면에서 온-오프의 모든 복잡성이 필요하지 않습니다.
// 애플리케이션. 마이너스 측에서는 도우미가 없어서 구해야 합니다.
// 세부 사항에 좀 더 관여하지만 이는 사소한 일입니다.
//
// 먼저 소켓을 생성하고 그에 대한 연결 추적을 수행합니다. 그럼 우리는 통과
// 이 소켓은 간단한 응용 프로그램의 생성자에 연결됩니다.
// 소스 노드에 설치합니다.
// ================================================ ===========================
//
이것은 또한 자명해야 합니다.
다음 부분은 선언문이다. 마이앱 어플리케이션 우리가 함께 할 수 있도록
전에, 소켓 구성 시 생성됩니다.
클래스 MyApp : 공개 애플리케이션
{
공공의:
마이앱();
가상 ~MyApp();
무효 설정(Ptr 소켓, 주소 주소, uint32_t packetSize,
uint32_t nPackets, DataRate dataRate);
비공개 :
가상 무효 StartApplication(무효);
가상 무효 StopApplication(무효);
무효 ScheduleTx (무효);
무효 SendPacket (무효);
포인트 m_socket;
주소 m_peer;
uint32_t m_packetSize;
uint32_t m_n패킷;
데이터레이트 m_dataRate;
이벤트ID m_sendEvent;
bool m_running;
uint32_t m_packetsSent;
};
이 클래스가 NS-3 어플리케이션 수업. 보세요
src/네트워크/모델/application.h 상속받은 것에 관심이 있다면. 그만큼 마이앱
클래스는 응용 프로그램 시작 and 애플리케이션 중지 행동 양식. 이것들
메서드는 다음과 같은 경우 자동으로 호출됩니다. 마이앱 데이터 전송을 시작하고 중지하는 데 필요합니다.
시뮬레이션 중에.
시작/중지 어플리케이션
이벤트가 실제로 어떻게 시작되는지 설명하는 데 약간의 시간을 할애할 가치가 있습니다.
체계. 이것은 또 다른 상당히 깊은 설명이며, 그렇지 않은 경우 무시할 수 있습니다.
시스템의 내부로 모험을 떠날 계획입니다. 그러나 그 점에서는 유용합니다.
토론은 다음과 같은 매우 중요한 부분에 대해 다룹니다. NS-3 작업하고 일부를 노출합니다.
중요한 관용어. 새로운 모델을 구현할 계획이라면 아마도 다음을 수행하고 싶을 것입니다.
이 부분을 이해하십시오.
펌핑 이벤트를 시작하는 가장 일반적인 방법은 어플리케이션. 이는 다음과 같이 수행됩니다.
다음과 같은 (바라건대) 가족 라인의 결과 NS-3 스크립트:
ApplicationContainer 앱 = ...
apps.Start(초(1.0));
apps.Stop(초(10.0));
애플리케이션 컨테이너 코드(참조: src/네트워크/helper/application-container.h 당신이있는 경우
관심) 포함된 응용 프로그램 및 호출을 반복합니다.
앱->SetStartTime(startTime);
의 결과로 앱.시작 전화하고
앱->SetStopTime(stopTime);
의 결과로 앱.중지 요구.
이러한 호출의 궁극적인 결과는 시뮬레이터를 자동으로 갖기를 원한다는 것입니다.
우리에게 전화를 걸어 어플리케이션 언제 시작하고 멈출지 알려줍니다. 의 경우
마이앱, 클래스에서 상속 어플리케이션 그리고 재정의 응용 프로그램 시작및
애플리케이션 중지. 다음은 시뮬레이터에서 호출할 함수입니다.
적절한 시간. 의 경우 마이앱 당신은 그것을 찾을 것입니다 MyApp::시작 응용 프로그램 하지
초기 바인더및 연결하기 소켓에서 다음을 호출하여 데이터 흐름을 시작합니다.
MyApp::SendPacket. MyApp::중지응용프로그램 취소하여 패킷 생성을 중지합니다.
보류 중인 보내기 이벤트는 소켓을 닫습니다.
좋은 점 중 하나는 NS-3 구현을 완전히 무시할 수 있다는 것입니다
당신의 방법에 대한 세부 사항 어플리케이션 올바른 위치에서 시뮬레이터에 의해 "자동으로" 호출됩니다.
시간. 그러나 우리는 이미 깊이 파고들었기 때문에 NS-3 이미, 그것을 위해 가자.
당신이 보면 src/네트워크/모델/application.cc 당신은 시작 시간 설정 방법
의 어플리케이션 그냥 멤버 변수를 설정 m_startTime 그리고 정지 시간 설정 방법
그냥 설정 m_stopTime. 거기에서 힌트가 없으면 아마도 트레일이 끝날 것입니다.
트레일을 다시 선택하는 열쇠는 모든 트랙의 글로벌 목록이 있다는 것을 아는 것입니다.
시스템의 노드. 시뮬레이션에서 노드를 생성할 때마다 해당 노드에 대한 포인터
전역에 추가됩니다 노드 목록.
살펴 src/네트워크/모델/node-list.cc 및 검색 노드목록::추가. 공개
정적 구현은 다음과 같은 개인 구현을 호출합니다. NodeListPriv::추가. 이
에서 비교적 흔한 이담이다. NS-3. 그러니 한번 살펴보세요 NodeListPriv::추가. 거기 당신
찾을 것이다,
Simulator::ScheduleWithContext(인덱스, TimeStep(0), &Node::Initialize, 노드);
이는 시뮬레이션에서 노드가 생성될 때마다 부작용으로 호출이 발생함을 알려줍니다.
해당 노드에 초기화 시간 XNUMX에 발생하는 방법이 예정되어 있습니다. 하지 않다
아직 그 이름에 대해 너무 많은 내용을 읽었습니다. 이는 노드가 작업을 시작한다는 의미는 아닙니다.
무엇이든 노드에 대한 정보 호출로 해석될 수 있습니다.
노드에 작업을 시작하라고 지시하는 작업이 아닌 시뮬레이션이 시작되었습니다.
그래서, 노드목록::추가 간접적으로 호출을 예약합니다. 노드::초기화 XNUMX시에 조언을 하기 위해
시뮬레이션이 시작된 새 노드입니다. 들여다보면 src/네트워크/모델/node.h 의견을 듣고 싶습니다.
그러나 다음과 같은 메소드를 찾지 못할 것입니다. 노드::초기화. 그것은
초기화 메소드는 클래스에서 상속됩니다. 목적. 시스템의 모든 객체는
시뮬레이션이 시작될 때 알림을 받고 Node 클래스의 객체는 그 중 한 종류일 뿐입니다.
사물.
살펴 src/코어/모델/object.cc 다음으로 검색해 보세요. 객체::초기화. 이 코드
예상했던 것만큼 간단하지 않습니다. NS-3 사물 SUPPORT
집합. 의 코드 객체::초기화 그런 다음 해당 개체를 모두 반복합니다.
함께 집계되어 호출됩니다. 초기화를 하세요 방법. 이것은 또 다른 관용구입니다
그것은 매우 일반적입니다 NS-3, 때로는 "템플릿 디자인 패턴"이라고도 합니다.: 공개
구현 전반에 걸쳐 일정하게 유지되고
서브 클래스에 의해 상속되고 구현되는 개인 가상 구현 방법.
이름은 일반적으로 다음과 같습니다. 방법명 공개 API의 경우 방법 이름 for
프라이빗 API.
이는 우리가 다음을 찾아야 함을 알려줍니다. 노드::DoInitialize 방법
src/네트워크/모델/node.cc 우리의 흔적을 계속할 방법을 위해. 위치를 찾으면
코드를 사용하면 노드의 모든 장치를 반복하는 메서드를 찾은 다음
노드 호출의 모든 애플리케이션 장치->초기화 and 응용프로그램->초기화
각각.
당신은 이미 그 수업을 알고있을 것입니다 장치 and 어플리케이션 둘 다 클래스에서 상속 목적
그래서 다음 단계는 응용 프로그램::초기화 is
라고 불리는. 보세요 src/네트워크/모델/application.cc 그러면 다음을 찾을 수 있습니다:
무효화
응용 프로그램::DoInitialize(무효)
{
m_startEvent = 시뮬레이터::Schedule(m_startTime, &Application::StartApplication, this);
if (m_stopTime != TimeStep(0))
{
m_stopEvent = 시뮬레이터::Schedule(m_stopTime, &Application::StopApplication, this);
}
객체::DoInitialize ();
}
이제 드디어 길이 끝나는 지점에 이르렀습니다. 모든 것을 똑바로 유지했다면,
구현하다 NS-3 어플리케이션, 새 애플리케이션은 클래스에서 상속됩니다. 어플리케이션. 당신
재정의 응용 프로그램 시작 and 애플리케이션 중지 방법을 제공하고 메커니즘을 제공합니다.
새 데이터 흐름 시작 및 중지 어플리케이션. 노드가 있을 때
시뮬레이션에서 생성되면 전역에 추가됩니다. 노드 목록. 노드를 추가하는 행위
이 노드 목록 시뮬레이터 이벤트를 호출하는 시간 XNUMX으로 예약되도록 합니다.
노드::초기화 시뮬레이션 시작 시 호출될 새로 추가된 Node의 메서드입니다.
노드는 목적, 이는 다음을 호출합니다. 객체::초기화 노드의 메소드
이는 차례로 다음을 호출합니다. 초기화를 하세요 모든 방법에 대한 사물 에 집계
노드(이동성 모델 생각). 노드 이후 목적 재정의되었습니다 초기화를 하세요그
메서드는 시뮬레이션이 시작될 때 호출됩니다. 그만큼 노드::DoInitialize 메소드는
초기화 모든 방법의 어플리케이션 노드에서. 부터 어플리케이션 도 있습니다
사물, 이로 인해 응용 프로그램::초기화 불릴. 언제
응용 프로그램::초기화 호출되면 다음에 대한 이벤트를 예약합니다. 응용 프로그램 시작 and
애플리케이션 중지 에 전화 어플리케이션. 이러한 호출은 다음을 시작하고 중지하도록 설계되었습니다.
데이터의 흐름 어플리케이션
이것은 꽤 긴 여정이었지만 한 번만 수행하면 됩니다.
또 다른 매우 깊은 부분을 이해하십시오 NS-3.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 마이앱 어플리케이션
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 마이앱 어플리케이션 물론 생성자와 소멸자가 필요합니다.
내앱::내앱 ()
: m_socket (0),
m_피어(),
m_packetSize (0),
m_n패킷 (0),
m_dataRate (0),
m_sendEvent(),
m_running (거짓),
m_packets전송됨 (0)
{
}
내앱::~내앱()
{
m_socket = 0;
}
다음 코드 비트의 존재가 우리가 이것을 작성한 전체 이유입니다. 어플리케이션 in
첫 번째 장소.
무효화
MyApp::설정(Ptr 소켓, 주소 주소, uint32_t packetSize,
uint32_t nPackets, DataRate dataRate)
{
m_socket = 소켓;
m_peer = 주소;
m_packetSize = 패킷 크기;
m_nPackets = n패킷;
m_dataRate = dataRate;
}
이 코드는 설명이 매우 간단해야 합니다. 우리는 멤버 변수를 초기화하고 있습니다.
추적의 관점에서 중요한 것은 포인트 소켓 우리는
구성 시간 동안 애플리케이션에 제공해야 합니다. 우리가 간다는 걸 기억해
창조하기 소켓 등 Tcp소켓 (이는 다음과 같이 구현됩니다. TcpNewReno) 그리고 후크
"CongestionWindow" 추적 소스를 전달하기 전에 설정 방법.
무효화
MyApp::StartApplication(무효)
{
m_running = 사실;
m_packetsSent = 0;
m_socket->바인드();
m_socket->연결(m_peer);
SendPacket();
}
위의 코드는 재정의된 구현입니다. 응용 프로그램::시작 응용 프로그램 그럴거야.
시뮬레이터에서 자동으로 호출하여 어플리케이션 적절한 위치에서 실행
시간. 당신은 그것이하는 것을 볼 수 있습니다 소켓 바인더 작업. 당신이 익숙하다면
버클리 소켓(Berkeley Sockets) 이것은 놀라운 일이 아닙니다. 로컬에서 필요한 작업을 수행합니다.
예상대로 연결의 측면. 다음과 같은 연결하기 무엇을 할 것인가
TCP와의 연결을 설정하는 데 필요합니다. 주소 m_peer. 이제 분명해졌을 겁니다
왜 우리는 이 많은 부분을 시뮬레이션 시간으로 연기해야 합니까? 연결하기 필요할 것이다
완벽하게 작동하는 네트워크를 완성합니다. 후 연결하기Walk Through California 프로그램, 어플리케이션 그런 다음 시작
호출하여 시뮬레이션 이벤트 생성 SendPacket.
다음 코드 비트는 어플리케이션 시뮬레이션 이벤트 생성을 중지하는 방법.
무효화
MyApp::StopApplication(무효)
{
m_running = 거짓;
if (m_sendEvent.IsRunning())
{
시뮬레이터::취소(m_sendEvent);
}
if (m_소켓)
{
m_socket->닫기();
}
}
시뮬레이션 이벤트가 예정될 때마다 이벤트 생성됩니다. 만약 이벤트 보류 중
실행 또는 실행, 그 방법 실행 중 돌아올거야. 참된. 이 코드에서 만약
실행중() true를 반환합니다. 우리는 취소 시뮬레이터 이벤트에서 제거하는 이벤트
대기줄. 이를 통해 우리는 사건의 연쇄를 끊습니다. 어플리케이션 유지하는 데 사용하고 있습니다
보내는 중 패킷 그리고 어플리케이션 조용히 간다. 우리가 조용히 한 후 어플리케이션 we
닫기 TCP 연결을 끊는 소켓.
소켓은 실제로 소멸자에서 삭제됩니다. m_socket = 0 실행됩니다. 이것
기본 Ptr에 대한 마지막 참조를 제거합니다. 소멸자를 유발하는
호출할 개체입니다.
리콜 응용 프로그램 시작 라는 SendPacket 설명하는 일련의 이벤트를 시작합니다.
전에, 어플리케이션 행동.
무효화
MyApp::SendPacket(무효)
{
포인트 패킷 = 생성 (m_packetSize);
m_socket->보내기(패킷);
if (++m_packetsSent < m_nPackets)
{
ScheduleTx();
}
}
저기, 그거 보이시죠 SendPacket 그렇게 합니다. 그것은 생성 패킷 그런 다음 전송
Berkeley Sockets를 알고 있다면 아마도 예상했던 바로 그 모습일 것입니다.
의 책임입니다. 어플리케이션 일련의 이벤트 일정을 계속 계획하기 위해
다음 회선 전화 ScheduleTx 다른 전송 이벤트를 예약하려면(a SendPacket) 까지
어플리케이션 충분히 보냈다고 판단합니다.
무효화
MyApp::ScheduleTx(무효)
{
경우 (m_running)
{
시간 tNext(초(m_packetSize * 8 / static_cast (m_dataRate.GetBitRate ())));
m_sendEvent = 시뮬레이터::Schedule(tNext, &MyApp::SendPacket, this);
}
}
저기, 그거 보이시죠 ScheduleTx 바로 그런 일을 합니다. 만약 어플리케이션 실행 중입니다(만약
애플리케이션 중지 호출되지 않음) 호출되는 새 이벤트를 예약합니다. SendPacket
다시. 경고를 읽는 사람은 새로운 사용자에게도 걸림돌이 되는 것을 발견할 것입니다. 데이터 속도
의 어플리케이션 바로 그것입니다. 기본 데이터 속도와 관련이 없습니다.
채널. 이는 어플리케이션 비트를 생산합니다. 그것은 받아들이지 않는다
전송하는 데 사용하는 다양한 프로토콜이나 채널에 대한 오버헤드를 고려합니다.
데이터. 데이터 속도를 설정하면 어플리케이션 기본 데이터와 동일한 데이터 속도로
채널 결국 버퍼 오버플로가 발생합니다.
더듬다 싱크
이 연습의 요점은 TCP에서 추적 콜백을 가져오는 것입니다.
혼잡 기간이 업데이트되었습니다. 다음 코드 조각은 해당
추적 싱크:
정적 공극
CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (시뮬레이터::Now ().GetSeconds () << "\t" << newCwnd);
}
이것은 이제 여러분에게 매우 친숙할 것이므로 자세한 내용은 다루지 않겠습니다. 이 기능
현재 시뮬레이션 시간과 정체 창의 새 값을 매일 기록합니다.
시간이 변경됩니다. 결과 출력을 로드할 수 있다고 상상할 수 있습니다.
그래픽 프로그램(gnuplot 또는 Excel)에 입력하고 즉시 멋진 그래프를 볼 수 있습니다.
시간 경과에 따른 혼잡 창 동작.
패킷이 드롭되는 위치를 표시하기 위해 새로운 트레이스 싱크를 추가했습니다. 오류를 추가하겠습니다.
이 코드에도 적용할 수 있으므로 이 작업을 시연하고 싶었습니다.
정적 공극
RxDrop(Ptr 피)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
}
이 트레이스 싱크는 포인트 투 포인트의 "PhyRxDrop" 트레이스 소스에 연결됩니다.
NetDevice. 이 추적 소스는 네트워크의 물리적 계층에서 패킷이 삭제될 때 실행됩니다.
NetDevice. 소스를 조금만 우회하면
(src/점대점/모델/점대점-net-device.cc) 이 추적이
출처는 참조 PointToPointNetDevice::m_phyRxDropTrace. 그럼 들여다보면
src/점대점/모델/점대점-net-device.h 이 멤버 변수에 대해
로 선언되어 있음을 알 수 있습니다. 추적 콜백 패킷> >. 이것은 당신에게 말해야합니다
콜백 대상은 void를 반환하고 단일
파라미터는 포인트 패킷> (우리가 사용한다고 가정 컨텍스트 없이 연결) -- 단지
우리가 위에 있는 것.
본관 프로그램
다음 코드는 이제 매우 친숙할 것입니다.
INT
메인(int argc, char *argv[])
{
NodeContainer 노드;
노드.만들기(2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
pointToPoint.SetChannelAttribute("지연", StringValue("2ms"));
NetDeviceContainer 장치;
장치 = pointToPoint.Install(노드);
이렇게 하면 그림과 같이 두 노드 사이에 점대점 채널이 있는 두 개의 노드가 생성됩니다.
파일 시작 부분의 그림.
다음 몇 줄의 코드는 새로운 것을 보여줍니다. 동작하는 연결을 추적하면
완벽하게, 우리는 단조롭게 증가하는 혼잡 창으로 끝날 것입니다. 무엇이든 보려면
흥미로운 행동, 우리는 정말로 패킷을 떨어뜨리는 링크 오류를 도입하고 싶습니다.
중복 ACK를 발생시키고 혼잡 창의 보다 흥미로운 동작을 트리거합니다.
NS-3 제공 오류모델 붙일 수 있는 물건 채널. 우리는
비율 오류 모델 이는 우리가 오류를 채널 주어진 시간에 율.
Ptr em = CreateObject ();
em->SetAttribute ("ErrorRate", DoubleValue (0.00001));
devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
위의 코드는 비율 오류 모델 객체, "ErrorRate"를 설정합니다. 속성
원하는 값으로. 그런 다음 인스턴스화된 결과를 설정합니다. 비율 오류 모델 오류로
point-to-point에서 사용하는 모델 NetDevice. 이것은 우리에게 약간의 재전송을 제공하고
플롯을 좀 더 흥미롭게 만듭니다.
InternetStackHelper 스택;
stack.Install(노드);
Ipv4AddressHelper 주소;
address.SetBase("10.1.1.0", "255.255.255.252");
Ipv4InterfaceContainer 인터페이스 = address.Assign(장치);
위의 코드는 익숙할 것입니다. 두 노드에 인터넷 스택을 설치하고
인터페이스를 생성하고 지점 간 장치에 대한 IP 주소를 할당합니다.
TCP를 사용하고 있으므로 TCP를 수신하려면 대상 노드에 무언가가 필요합니다.
연결 및 데이터. 그만큼 패킷싱크 어플리케이션 에서 일반적으로 사용되는 NS-3 그에 대한
목적.
uint16_t 싱크포트 = 8080;
주소 sinkAddress(InetSocketAddress(interfaces.GetAddress(1), sinkPort));
PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory",
InetSocketAddress(Ipv4Address::GetAny(), 싱크포트));
ApplicationContainer sinkApps = packetSinkHelper.Install(nodes.Get(1));
sinkApps.Start(초(0.));
sinkApps.Stop(초(20.));
다음을 제외하고 모두 친숙해야 합니다.
PacketSinkHelper packetSinkHelper("ns3::TcpSocketFactory",
InetSocketAddress(Ipv4Address::GetAny(), 싱크포트));
이 코드는 패킷 싱크 도우미 클래스를 사용하여 소켓을 생성하도록 지시합니다.
ns3::TcpSocketFactory. 이 클래스는 "객체 팩토리"라는 디자인 패턴을 구현합니다.
이는 객체를 생성하는 데 사용되는 클래스를 지정하기 위해 일반적으로 사용되는 메커니즘입니다.
추상적인 방법. 여기서 객체 자체를 생성하는 대신 다음을 제공합니다.
패킷 싱크 도우미 를 지정하는 문자열 유형 ID 객체를 생성하는 데 사용되는 문자열
그런 다음 팩토리에서 생성된 객체의 인스턴스를 생성하는 데 사용할 수 있습니다.
나머지 매개변수는 어플리케이션 어떤 주소와 포트가 바인더 에.
다음 두 줄의 코드는 소켓을 만들고 추적 소스를 연결합니다.
Ptr ns3TcpSocket = 소켓::CreateSocket(nodes.Get(0),
TcpSocketFactory::GetTypeId ());
ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow",
MakeCallback(&CwndChange));
첫 번째 문은 정적 멤버 함수를 호출합니다. 소켓::CreateSocket 제공합니다
노드 및 명시적 유형 ID 소켓을 만드는 데 사용되는 개체 팩터리에 대해. 이것은
콜보다 약간 낮은 레벨 패킷 싱크 도우미 위의 호출 및 명시적 C++ 사용
문자열이 참조하는 유형 대신 유형. 그렇지 않으면 개념적으로 동일합니다.
맡은 일.
한 번 Tcp소켓 생성되어 노드에 연결되면 사용할 수 있습니다.
TraceConnectWithoutContext CongestionWindow 추적 소스를 추적 싱크에 연결합니다.
우리가 어플리케이션 그래서 우리는 그것을 취할 수 소켓 우리는 방금 (동안
구성 시간) 시뮬레이션 시간에 사용하십시오. 이제 인스턴스화해야 합니다.
어플리케이션. 우리는 어플리케이션 so
"수동으로" 만들고 설치해야 합니다. 이것은 실제로 매우 쉽습니다.
Ptr 앱 = CreateObject ();
앱->설정(ns3TcpSocket, sinkAddress, 1040, 1000, DataRate("1Mbps"));
nodes.Get (0)->AddApplication(앱);
앱->시작(초(1.));
앱->중지(초(20.));
첫 번째 줄은 목적 유형의 마이앱 -- 우리의 어플리케이션. 두 번째 줄이 알려줍니다.
전에, 어플리케이션 뭐 소켓 사용할 주소, 연결할 주소, 전송할 데이터 양
각 전송 이벤트, 생성할 전송 이벤트 수 및 데이터 생성 속도
그 사건들로부터.
다음으로 수동으로 추가합니다. 마이앱 어플리케이션 소스 노드에 명시적으로
스타트 and 중지 에 대한 방법 어플리케이션 작업을 시작하고 중지할 때를 알려줍니다.
맡은 일.
실제로 리시버 지점 간 연결을 수행해야 합니다. NetDevice 드롭 이벤트
우리에게 RxDrop 지금 콜백하세요.
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));
이제 우리가 수신에 대한 참조를 얻고 있다는 것이 분명해야 합니다. 노드 NetDevice
컨테이너에서 "PhyRxDrop" 속성으로 정의된 추적 소스를 연결합니다.
추적 싱크에 해당 장치 RxDrop.
마지막으로 시뮬레이터에 모든 것을 재정의하도록 지시합니다. 어플리케이션 그냥 처리를 중지
시뮬레이션으로 20초의 이벤트.
시뮬레이터::중지(초(삼));
시뮬레이터::실행();
시뮬레이터::파괴();
0가 돌아;
}
일단 기억해 시뮬레이터::실행 호출되고 구성 시간이 종료되고 시뮬레이션
시간이 시작됩니다. 우리가 만든 모든 작업은 어플리케이션 그리고 그것을 가르치는
데이터를 연결하고 보내는 방법은 실제로 이 함수 호출 중에 발생합니다.
자마자 시뮬레이터::실행 돌아오면 시뮬레이션이 완료되고 분해에 들어갑니다.
단계. 이 경우, 시뮬레이터::파괴 피투성이의 세부 사항을 처리하고 우리는 그냥 돌아갑니다
완료 후 성공 코드.
달리는 다섯번째.cc
파일을 제공했기 때문에 다섯번째.cc 배포판을 구축한 경우(in
사용하기 때문에 디버그 모드 NS_LOG -- 최적화된 빌드가 최적화됨을 기억하십시오. NS_LOG) 그것
달려갈 당신을 기다리고 있을 것입니다.
$ ./waf --다섯 번째 실행
Waf: `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' 디렉토리 입력 중
Waf: `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' 디렉토리에서 나가기
'빌드'가 성공적으로 완료되었습니다(0.684초).
1 536
1.0093 1072
1.01528 1608
1.02167 2144
...
1.11319 8040
1.12151 8576
1.12983 9112
1.13696에서 RxDrop
...
트레이스에서 모든 종류의 인쇄물을 사용하는 것의 단점을 즉시 알 수 있습니다.
흥미로운 정보 전체에 인쇄된 관련 없는 WAF 메시지를 얻습니다.
그 RxDrop 메시지와 함께. 우리는 곧 그것을 고칠 것이지만 나는 당신이 보고 싶어 기다릴 수 없다고 확신
이 모든 작업의 결과. 해당 출력을 다음 파일로 리디렉션하겠습니다. cwnd.dat:
$ ./waf -- 다섯 번째 실행 > cwnd.dat 2>&1
이제 좋아하는 편집기에서 "cwnd.dat"를 편집하고 waf 빌드 상태를 제거하고 드롭합니다.
추적된 데이터만 남기고 라인을 주석 처리할 수도 있습니다.
TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&Rx드롭)); 없애기 위해 스크립트에서
방울이 쉽게 인쇄됩니다.
이제 gnuplot을 실행하고(설치된 경우) 예쁜 파일을 생성하도록 지시할 수 있습니다.
영화:
$ gnuplot
gnuplot> 터미널 png 크기 640,480 설정
gnuplot> 출력 "cwnd.png" 설정
gnuplot> 라인 포인트가 있는 1:2 제목 '혼잡 창'을 사용하여 "cwnd.dat" 플롯
gnuplot> 종료
이제 혼잡 창 대 파일에 앉아 있는 시간의 그래프가 있어야 합니다.
"cwnd.png" loading="lazy"는 다음과 같습니다.
[이미지]
사용 중간 수준 도우미
이전 섹션에서 우리는 추적 소스를 후킹하고 희망적으로 얻는 방법을 보여주었습니다.
시뮬레이션에서 나온 흥미로운 정보. 아마도 당신은 우리가 전화했던 것을 기억할 것입니다.
다음을 사용하여 표준 출력에 로깅 표준::컷 이보다 훨씬 앞선 "무뚝뚝한 도구"
장. 또한 로그 출력을 순서대로 구문 분석해야 하는 문제에 대해서도 썼습니다.
흥미로운 정보를 분리합니다. 우리가 방금 많은 돈을 썼다는 생각이 들었을 수도 있습니다.
우리가 해결하려는 모든 문제를 보여주는 예제를 구현하는 시간
전에, NS-3 추적 시스템! 당신 말이 맞을 것입니다. 하지만 참아주세요. 아직 끝나지 않았습니다.
우리가 하고 싶은 가장 중요한 일 중 하나는 쉽게 할 수 있는 능력을 갖는 것입니다.
시뮬레이션에서 나오는 출력의 양을 제어합니다. 그리고 우리는 또한 그것들을 저장하고 싶습니다
나중에 다시 참조할 수 있도록 데이터를 파일로 저장합니다. 중간 수준의 추적 도우미를 사용할 수 있습니다.
제공 NS-3 그냥 그렇게하고 그림을 완성합니다.
예제에서 개발한 cwnd change 및 drop 이벤트를 작성하는 스크립트를 제공합니다.
다섯번째.cc 별도의 파일로 디스크에 저장합니다. cwnd 변경 사항은 탭으로 구분된 ASCII 형식으로 저장됩니다.
파일과 삭제 이벤트는 PCAP 파일에 저장됩니다. 이를 실현하기 위한 변경 사항은 다음과 같습니다.
꽤 작은.
연습 : 여섯번째.cc
에서 이동하는 데 필요한 변경 사항을 살펴보겠습니다. 다섯번째.cc 에 여섯번째.cc. 열다
예제/튜토리얼/sixth.cc 좋아하는 편집기에서. 당신은 첫 번째 변화를 볼 수 있습니다
CwndChange를 검색합니다. 추적에 대한 서명이 변경되었음을 알 수 있습니다.
싱크하고 추적된 정보를
파일을 나타내는 스트림.
정적 공극
CwndChange(Ptr 스트림, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (시뮬레이터::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}
정적 공극
RxDrop(Ptr 파일, 태평양 표준시 피)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
file->Write(Simulator::Now(), p);
}
"stream" 매개변수를 추가했습니다. CwndChange 추적 싱크. 이것은 개체입니다
C++ 출력 스트림을 보유(안전하게 유지)합니다. 이것은 매우 간단하다는 것이 밝혀졌습니다.
개체이지만 스트림의 수명 문제를 관리하고 문제를 해결하는 개체입니다.
숙련된 C++ 사용자가 실행합니다. 에 대한 복사 생성자가 표준::ostream
비공개로 표시됩니다. 이것은 std::ostream 값 의미론을 따르지 않고 할 수 없습니다.
스트림을 복사해야 하는 모든 메커니즘에서 사용할 수 있습니다. 여기에는 NS-3
기억할 수 있는 콜백 시스템에는 값 의미 체계를 따르는 개체가 필요합니다.
다음 줄을 추가했습니다. CwndChange 트레이스 싱크
이행:
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
교체하면 매우 친숙한 코드가 됩니다. *stream->GetStream () 과 표준::컷, 같이
에서:
std::cout << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
이것은 Ptr 정말 그냥 들고 다니고
표준::스트림 당신을 위해 여기에서 다른 출력 스트림처럼 사용할 수 있습니다.
에서도 비슷한 상황이 발생합니다. RxDrop 전달되는 개체를 제외하고 (a
Ptr)은 PCAP 파일을 나타냅니다. 추적 싱크에 한 줄짜리가 있습니다.
드롭되는 패킷의 타임스탬프와 내용을 PCAP 파일에 기록합니다.
file->Write(Simulator::Now(), p);
물론 두 파일을 나타내는 개체가 있으면 어딘가에 만들어야 합니다.
또한 추적 싱크로 전달되도록 합니다. 에서 보면 본관 기능,
이를 수행하는 새 코드를 찾을 수 있습니다.
AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow", MakeBoundCallback(&CwndChange, 스트림));
...
PcapHelper pcapHelper;
Ptr file = pcapHelper.CreateFile("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP);
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, 파일));
위 코드 스니펫의 첫 번째 섹션에서 ASCII 추적 파일을 생성합니다.
그것을 관리하고 콜백의 변형을 사용하는 객체 생성
개체가 싱크로 전달되도록 정렬하는 생성 기능. ASCII 추적
도우미는 텍스트(ASCII) 파일을 쉽게 사용할 수 있도록 다양한 기능을 제공합니다. 우리는
여기서는 파일 스트림 생성 기능의 사용을 설명하겠습니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 파일스트림 생성 함수는 기본적으로 표준::스트림 개체 및
새 파일을 생성하거나 기존 파일을 자릅니다. 이것 표준::스트림 에 포장되어 있습니다
NS-3 수명 관리 및 복사 생성자 문제 해결을 위한 개체입니다.
그러면 우리는 이것을 NS-3 파일을 나타내는 객체를 전달합니다. MakeBoundCallback().
이 함수는 다음과 같이 콜백을 생성합니다. 메이크콜백()하지만 새 값을 다음에 "바인딩"합니다.
콜백. 이 값은 콜백이 실행되기 전에 첫 번째 인수로 추가됩니다.
전화했다.
기본적으로, MakeBoundCallback(&CwndChange, 개울) 추적 소스가
호출하기 전에 공식 매개변수 목록 앞에 추가 "stream" 매개변수
콜백. 이렇게 하면 필요한 서명이 변경됩니다. CwndChange 하나에 맞게 싱크대
위에 표시된 "extra" 매개변수 포함 Ptr 흐름.
위 스니펫 코드의 두 번째 섹션에서 PcapHelper 을 할 수
PCAP 추적 파일에 대해 동일한 작업을 수행했습니다. AsciiTraceHelper. 의 라인
코드
Ptr 파일 = pcapHelper.CreateFile("sixth.pcap",
"w", PcapHelper::DLT_PPP);
파일 모드가 "w"인 "sixth.pcap"이라는 PCAP 파일을 생성합니다. 즉, 새 파일
해당 이름을 가진 기존 파일이 발견되면 잘립니다(내용 삭제). 마지막
매개변수는 새 PCAP 파일의 "데이터 링크 유형"입니다. 이들은 PCAP와 동일합니다.
다음에 정의된 라이브러리 데이터 링크 유형 bpf.h PCAP에 익숙한 경우. 이 경우,
DLT_PPP PCAP 파일이 가리키는 접두사가 붙은 패킷을 포함할 것임을 나타냅니다.
포인트 헤더. 패킷이 지점 간 장치에서 오기 때문에 이것은 사실입니다.
운전사. 다른 일반적인 데이터 링크 유형은 csma에 적합한 DLT_EN10MB(10MB 이더넷)입니다.
Wi-Fi 장치에 적합한 장치 및 DLT_IEEE802_11(IEEE 802.11). 이들은 정의됩니다
in src/네트워크/helper/trace-helper.h 당신이 목록을 보는 데 관심이 있다면. 그만큼
목록의 항목은 bpf.h 그러나 PCAP 소스를 피하기 위해 복제합니다.
의존.
A NS-3 PCAP 파일을 나타내는 개체는 다음에서 반환됩니다. CreateFile 바운드에서 사용
콜백은 ASCII 경우와 동일합니다.
중요한 우회로: 이 두 개체가 모두
매우 유사한 방식으로 선언했습니다.
Ptr 파일 ...
Ptr 개울 ...
기본 개체는 완전히 다릅니다. 예를 들어, Ptr 하는
에 대한 스마트 포인터 NS-3 지지하는 상당히 무거운 물체
속성 및 구성 시스템에 통합됩니다. 그만큼 Ptr,에
반면에 매우 가벼운 참조 카운트 객체에 대한 스마트 포인터입니다.
물건. 어떤 가정을 하기 전에 참조하는 개체를 확인해야 합니다.
개체가 가질 수 있는 "권한"에 대해.
예를 들어 src/네트워크/utils/pcap-file-wrapper.h 유통 및
알아 채다,
클래스 PcapFileWrapper : 공용 개체
그 수업 Pcap파일래퍼 는 Teledyne LeCroy 오실로스코프 및 LSA-XNUMX 시리즈 임베디드 신호 분석기가 NS-3 상속 덕분에 객체. 그럼 봐
src/네트워크/모델/output-stream-wrapper.h 그리고 주목,
클래스 OutputStreamWrapper : 공개
SimpleRefCount
이 개체가 NS-3 개체는 "단순히" C++ 개체입니다.
침입 참조 카운팅을 지원합니다.
여기서 요점은 당신이 읽기 때문에 Ptr 반드시 그런 뜻은 아니다
그 무언가 는 Teledyne LeCroy 오실로스코프 및 LSA-XNUMX 시리즈 임베디드 신호 분석기가 NS-3 걸 수 있는 물건 NS-3 예를 들어 속성.
이제 예로 돌아가겠습니다. 이 예제를 빌드하고 실행하면,
$ ./waf --XNUMX번째 실행
"fifth"를 실행했을 때와 동일한 메시지가 표시되지만 두 개의 새 파일이
최상위 디렉토리에 나타납니다. NS-3 유통.
여섯 번째.cwnd 여섯 번째.pcap
"sixth.cwnd"는 ASCII 텍스트 파일이므로 다음과 같이 볼 수 있습니다. 방법 또는 좋아하는 파일
뷰어.
+ 1 0 536
+ 1.0093 536 1072
+ 1.01528 1072 1608
+ 1.02167 1608 2144
...
+ 9.69256 5149 5204
+ 9.89311 5204 5259
타임스탬프가 있는 탭으로 구분된 파일, 이전 정체 기간 및 새
플롯 프로그램으로 직접 가져오기에 적합한 혼잡 창. 없다
파일의 관련 없는 인쇄, 구문 분석 또는 편집이 필요하지 않습니다.
"sixth.pcap"은 PCAP 파일이므로 TCP 덤프.
파일 six.pcap에서 읽기, 링크 유형 PPP(PPP)
1.136956 IP 10.1.1.1.49153 > 10.1.1.2.8080: 플래그 [.], 시퀀스 17177:17681, ack 1, win 32768, 옵션 [TS val 1133 ecr 1127,eol], 길이 504
1.403196 IP 10.1.1.1.49153 > 10.1.1.2.8080: 플래그 [.], 시퀀스 33280:33784, ack 1, win 32768, 옵션 [TS val 1399 ecr 1394,eol], 길이 504
...
7.426220 IP 10.1.1.1.49153 > 10.1.1.2.8080: 플래그 [.], 시퀀스 785704:786240, ack 1, win 32768, 옵션 [TS val 7423 ecr 7421,eol], 길이 536
9.630693 IP 10.1.1.1.49153 > 10.1.1.2.8080: 플래그 [.], 시퀀스 882688:883224, ack 1, win 32768, 옵션 [TS val 9620 ecr 9618,eol], 길이 536
시뮬레이션에서 삭제된 패킷이 포함된 PCAP 파일이 있습니다. 없다
파일에 다른 패킷이 존재하며 생명을 유지하기 위해 존재하는 다른 것은 없습니다.
어려운.
긴 여정이었지만 이제 우리는 NS-3
추적 시스템. TCP 구현 중간에서 중요한 이벤트를 제거했습니다.
그리고 장치 드라이버. 우리는 이러한 이벤트를 일반적으로 알려진 파일에 직접 저장했습니다.
도구. 관련된 핵심 코드를 수정하지 않고 이 작업을 수행했습니다.
단 18줄의 코드:
정적 공극
CwndChange(Ptr 스트림, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (시뮬레이터::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}
...
AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext("CongestionWindow", MakeBoundCallback(&CwndChange, 스트림));
...
정적 공극
RxDrop(Ptr 파일, 태평양 표준시 피)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
file->Write(Simulator::Now(), p);
}
...
PcapHelper pcapHelper;
Ptr 파일 = pcapHelper.CreateFile("sixth.pcap", "w", PcapHelper::DLT_PPP);
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, 파일));
더듬다 도우미
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 추적 도우미는 다양한 구성 및 선택을 위한 풍부한 환경을 제공합니다.
이벤트를 추적하고 파일에 씁니다. 이전 섹션에서는 주로
BuildingTopologies, 우리는 여러 종류의 추적 도우미 메서드가 설계된 것을 보았습니다.
다른 (장치) 도우미 내부에서 사용하기 위해.
아마도 다음과 같은 변형 중 일부를 본 것을 기억할 것입니다.
pointToPoint.EnablePcapAll("초");
pointToPoint.EnablePcap("초", p2pNodes.Get(0)->GetId(), 0);
csma.EnablePcap("제0", csmaDevices.Get(XNUMX), true);
pointToPoint.EnableAsciiAll(ascii.CreateFileStream("myfirst.tr"));
그러나 분명하지 않은 것은 모든 분야에 일관된 모델이 있다는 것입니다.
시스템에서 찾은 추적 관련 메서드입니다. 이제 잠시 시간을 내어 살펴보겠습니다.
"큰 그림"에서.
현재 추적 도우미의 두 가지 기본 사용 사례가 있습니다. NS-3: 장치 도우미
및 프로토콜 도우미. 장치 헬퍼는 추적을 지정하는 문제를 살펴봅니다.
(노드, 장치) 쌍을 통해 활성화되어야 합니다. 예를 들어 다음을 지정할 수 있습니다.
PCAP 추적은 특정 노드의 특정 장치에서 활성화되어야 합니다. 이것
에서 다음과 같습니다 NS-3 장치 개념 모델 및 장치의 개념 모델
다양한 장치 도우미. 이에 따라 자연스럽게 생성되는 파일은
- - 명명 규칙.
프로토콜 도우미는 다음을 통해 활성화해야 하는 추적을 지정하는 문제를 살펴봅니다.
프로토콜과 인터페이스 쌍. 이는 다음과 같습니다. NS-3 프로토콜 스택 개념
모델 및 인터넷 스택 헬퍼의 개념적 모델. 자연스럽게 그 흔적
파일은 - - 명명 규칙.
따라서 추적 도우미는 자연스럽게 XNUMX차원 분류 체계에 속하게 됩니다. 있다
네 가지 클래스가 모두 동일하게 행동하는 것을 방해하는 미묘한 점들이 있지만 우리는 그렇게 하기 위해 노력합니다.
가능한 한 모두 유사하게 작동하도록 하십시오. 그리고 가능할 때마다 다음과 같은 유사점이 있습니다.
모든 클래스의 모든 메소드.
┌────────────────┬──────┬───────┐
│ │ PCAP │ ASCII │
└────────────────┴──────┴───────┘
│장치 도우미 │ │ │
├────────────────┼──────┼───────┤
│프로토콜 도우미 │ │ │
└────────────────┴──────┴───────┘
라는 접근 방식을 사용합니다. 믹스 인 도우미 클래스에 추적 기능을 추가합니다. ㅏ
믹스 인 하위 클래스에 의해 상속될 때 기능을 제공하는 클래스입니다.
mixin에서 상속하는 것은 전문화의 한 형태로 간주되지 않지만 실제로는
기능을 수집합니다.
이 네 가지 사례 모두와 각각의 사례를 간단히 살펴보겠습니다. 믹스 인.
장치 도우미
PCAP
이러한 도우미의 목표는 일관된 PCAP 추적 기능을
NS-3 장치. 우리는 다양한 종류의 PCAP 추적이 모두 동일하게 작동하기를 원합니다.
모든 장치이므로 이러한 헬퍼의 메서드는 장치 헬퍼에 의해 상속됩니다. 구경하다
at src/네트워크/helper/trace-helper.h 보면서 토론을 따라가고 싶다면
실제 코드.
클래스 PcapHelperForDevice 하는 믹스 인 사용하기 위한 높은 수준의 기능을 제공합니다.
PCAP 추적 NS-3 장치. 모든 장치는 단일 가상 메서드를 구현해야 합니다.
이 클래스에서 상속됩니다.
가상 무효 EnablePcapInternal (std::string 접두사, Ptr nd, 부울 무차별, 부울 명시적 파일 이름) = 0;
이 방법의 시그니처는 현재 상황에 대한 장치 중심적 관점을 반영합니다.
수준. 클래스에서 상속된 모든 공개 메소드 PcapUserHelperForDevice 로 줄이다
이 단일 장치 종속 구현 방법을 호출합니다. 예를 들어, 가장 낮은 수준
PCAP 방법,
void EnablePcap(std::string 접두사, Ptr nd, bool promiscuous = false, boolexplicitFilename = false);
다음의 장치 구현을 호출합니다. Pcap내부 활성화 곧장. 기타 모든 공용 PCAP
추적 방법은 이 구현을 기반으로 구축되어 추가 사용자 수준을 제공합니다.
기능. 이것이 사용자에게 의미하는 바는 시스템의 모든 장치 도우미가
모든 PCAP 추적 방법을 사용할 수 있습니다. 이러한 방법은 모두 동일한
기기가 구현하는 경우 여러 기기에 걸쳐 Pcap내부 활성화 바르게.
행동 양식
void EnablePcap(std::string 접두사, Ptr nd, bool promiscuous = false, boolexplicitFilename = false);
void EnablePcap(std::string 접두사, std::string ndName, bool promiscuous = false, boollicitFilename = false);
무효 EnablePcap(std::문자열 접두사, NetDeviceContainer d, 부울 무차별 = 거짓);
무효 EnablePcap(std::string 접두사, NodeContainer n, bool promiscuous = false);
무효 EnablePcap(std::문자열 접두사, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
void EnablePcapAll (std::string 접두사, bool promiscuous = false);
위에 표시된 각 메소드에는 다음과 같은 기본 매개변수가 있습니다. 난잡한 그
기본값은 그릇된. 이 매개변수는 추적이 수집되지 않아야 함을 나타냅니다.
무차별 모드. 장치에서 본 모든 트래픽을 추적에 포함시키려는 경우
(그리고 장치가 무차별 모드를 지원하는 경우) 다음 중 하나에 실제 매개변수를 추가하기만 하면 됩니다.
위의 전화. 예를 들어,
Ptr 차;
...
helper.EnablePcap("접두사", nd, true);
무차별 모드 캡처를 활성화합니다. NetDevice 에 의해 지정된 nd.
처음 두 메서드에는 다음과 같은 기본 매개 변수도 포함됩니다. 명시적 파일 이름 그럴거야.
아래에서 논의됩니다.
클래스에 대한 API 문서를 정독하는 것이 좋습니다. PcapHelperForDevice 찾는 방법
이러한 방법의 세부 사항; 그러나 요약하자면 ...
· 다음을 제공하여 특정 노드/네트-장치 쌍에서 PCAP 추적을 활성화할 수 있습니다.
포인트 에 Pcap 활성화 방법. 그만큼 Ptr net 장치 이후로 암시적입니다.
정확히 하나의 노드에 속해야 합니다. 예를 들어,
Ptr 차;
...
helper.EnablePcap("접두사", nd);
· 다음을 제공하여 특정 노드/네트-장치 쌍에서 PCAP 추적을 활성화할 수 있습니다.
표준::문자열 객체 이름 서비스 문자열을 Pcap 활성화 방법. 그만큼
포인트 이름 문자열에서 조회됩니다. 다시 말하지만, 이후로 암시적이다
명명된 네트 장치는 정확히 하나의 노드에 속해야 합니다. 예를 들어,
이름::추가("서버" ...);
이름::추가("서버/eth0" ...);
...
helper.EnablePcap ("접두사", "서버/ath0");
· 다음을 제공하여 노드/네트-장치 쌍 모음에서 PCAP 추적을 활성화할 수 있습니다.
NetDevice컨테이너. 각각 NetDevice 컨테이너에서 유형이 확인됩니다. 각각
적절한 유형의 장치(장치 도우미가 관리하는 것과 동일한 유형), 추적은
활성화되었습니다. 다시 말하지만, 발견된 넷 장치가 다음에 속해야 하므로 암시적입니다.
정확히 하나의 노드. 예를 들어,
NetDeviceContainer d = ...;
...
helper.EnablePcap("접두사", d);
· 다음을 제공하여 노드/네트-장치 쌍 모음에서 PCAP 추적을 활성화할 수 있습니다.
노드컨테이너. 각 노드에 대해 노드컨테이너 붙어있어 NetDevices 반복됩니다.
각각 NetDevice 컨테이너의 각 노드에 연결된 경우 해당 장치의 유형은 다음과 같습니다.
확인. 적절한 유형의 각 장치에 대해(장치에서 관리하는 것과 동일한 유형
도우미), 추적이 활성화됩니다.
NodeContainern;
...
helper.EnablePcap("접두사", n);
· 노드 ID 및 장치 ID를 기반으로 PCAP 추적을 활성화할 수 있습니다.
명백한 Ptr. 시스템의 각 노드에는 정수 노드 ID와 연결된 각 장치가 있습니다.
노드에 정수 장치 ID가 있습니다.
helper.EnablePcap("접두사", 21, 1);
· 마지막으로 시스템의 모든 장치에 대해 동일한 유형의 PCAP 추적을 활성화할 수 있습니다.
장치 도우미에서 관리하는 것으로.
helper.EnablePcapAll("접두사");
파일명
위의 방법 설명에 내포된 것은 다음과 같은 방법으로 완전한 파일 이름을 구성하는 것입니다.
구현 방법. 규칙에 따라 PCAP 추적은 NS-3 시스템은 다음과 같은 형태입니다.
- 아이디>- 아이디>.pcap
앞에서 언급했듯이 시스템의 모든 노드에는 시스템 할당 노드 ID가 있습니다. 그리고
모든 장치에는 노드와 관련된 인터페이스 인덱스(장치 ID라고도 함)가 있습니다.
기본적으로 첫 번째에서 추적을 활성화한 결과로 생성된 PCAP 추적 파일은
접두사 "접두사"를 사용하는 노드 21의 장치는 접두사-21-1.pcap.
항상 사용할 수 있습니다 NS-3 이것을 더 명확하게 하기 위해 객체 이름 서비스. 예를 들어,
개체 이름 서비스를 사용하여 노드 21에 "서버"라는 이름을 할당하면 결과 PCAP가 생성됩니다.
추적 파일 이름은 자동으로 다음과 같이 됩니다. 접두사-서버-1.pcap 또한
장치에 "eth0"이라는 이름을 지정하면 PCAP 파일 이름이 자동으로 선택되어
라는 접두사-서버-eth0.pcap.
마지막으로 위에 표시된 두 가지 방법,
void EnablePcap(std::string 접두사, Ptr nd, bool promiscuous = false, boolexplicitFilename = false);
void EnablePcap(std::string 접두사, std::string ndName, bool promiscuous = false, boollicitFilename = false);
라는 기본 매개변수가 있습니다. 명시적 파일 이름. true로 설정하면 이 매개변수는
자동 파일 이름 완성 메커니즘을 비활성화하고 명시적인 파일 이름을 생성할 수 있습니다.
파일 이름. 이 옵션은 컴퓨터에서 PCAP 추적을 활성화하는 방법에서만 사용할 수 있습니다.
단일 장치.
예를 들어 장치 도우미가 하나의 난잡한 PCAP를 생성하도록 준비하려면
특정 이름의 캡처 파일 내-pcap-file.pcap 주어진 장치에서 다음을 수행할 수 있습니다.
Ptr 차;
...
helper.EnablePcap("my-pcap-file.pcap", nd, true, true);
처음으로 참된 매개변수는 무차별 모드 추적을 활성화하고 두 번째 매개변수는 도우미에게 알려줍니다.
해석하다 접두사 매개변수를 완전한 파일 이름으로 사용합니다.
ASCII
ASCII 추적 도우미의 동작 믹스 인 PCAP 버전과 실질적으로 유사합니다.
살펴 src/네트워크/helper/trace-helper.h 토론을 팔로우하고 싶다면
실제 코드를 보면서.
클래스 AsciiTraceHelperForDevice ASCII 사용을 위한 높은 수준의 기능 추가
장치 도우미 클래스를 추적합니다. PCAP의 경우와 마찬가지로 모든 장치는 다음을 구현해야 합니다.
ASCII 추적에서 상속된 단일 가상 메서드 믹스 인.
가상 무효 EnableAsciiInternal(Ptr 개울,
std::문자열 접두사,
Ptr 차,
부울 명시적 파일 이름) = 0;
이 방법의 시그니처는 현재 상황에 대한 장치 중심적 관점을 반영합니다.
수준; 또한 도우미가 공유 출력 스트림에 쓸 수 있다는 사실도 있습니다. 모든
클래스에서 상속된 공용 ASCII 추적 관련 메서드 AsciiTraceHelperForDevice
이 단일 장치 종속 구현 방법을 호출하는 것으로 줄입니다. 예를 들어,
최하위 수준의 ASCII 추적 방법,
무효 EnableAscii(std::string 접두사, Ptr nd, bool 명시적 파일 이름 = false);
무효 EnableAscii(Ptr 스트림, PTR 차);
다음의 장치 구현을 호출합니다. Ascii내부 활성화 직접,
유효한 접두사 또는 스트림. 다른 모든 공용 ASCII 추적 방법은 다음을 기반으로 합니다.
추가 사용자 수준 기능을 제공하는 저수준 기능. 이것이 의미하는 바
사용자는 시스템의 모든 장치 도우미가 모든 ASCII 추적 방법을 갖게 된다는 것입니다.
사용 가능; 이러한 방법은 장치가 다음과 같은 경우 모든 장치에서 동일한 방식으로 작동합니다.
구현 EnablAscii내부 바르게.
행동 양식
무효 EnableAscii(std::string 접두사, Ptr nd, bool 명시적 파일 이름 = false);
무효 EnableAscii(Ptr 스트림, PTR 차);
무효 EnableAscii(std::문자열 접두사, std::문자열 ndName, 부울 명시적 파일 이름 = false);
무효 EnableAscii(Ptr 스트림, std::string ndName);
무효 EnableAscii(std::문자열 접두사, NetDeviceContainer d);
무효 EnableAscii(Ptr 스트림, NetDeviceContainer d);
void EnableAscii(std::string 접두사, NodeContainer n);
무효 EnableAscii(Ptr 스트림, NodeContainer n);
무효 EnableAsciiAll(std::문자열 접두사);
무효 EnableAsciiAll(Ptr 개울);
무효 EnableAscii(std::string 접두사, uint32_t nodeid, uint32_t deviceid, bool 명시적 파일 이름);
무효 EnableAscii(Ptr 스트림, uint32_t nodeid, uint32_t deviceid);
클래스에 대한 API 문서를 정독하는 것이 좋습니다. AsciiTraceHelperForDevice 에
이러한 방법의 세부 사항을 찾으십시오. 그러나 요약하자면 ...
· ASCII 추적에 사용할 수 있는 방법이 PCAP보다 두 배 더 많습니다.
트레이싱. 이것은 PCAP 스타일 모델 외에도 각각의 추적이 있기 때문입니다.
고유한 노드/장치 쌍이 고유한 파일에 기록되므로 추적하는 모델을 지원합니다.
많은 노드/장치 쌍에 대한 정보가 공통 파일에 기록됩니다. 이는
- - 파일 이름 생성 메커니즘은 다음 메커니즘으로 대체됩니다.
공통 파일을 참조하십시오. 모든 API 메소드를 허용하기 위해 API 메소드 수가 두 배로 늘어났습니다.
조합.
· PCAP 추적에서와 마찬가지로 특정(노드, net-device)에서 ASCII 추적을 활성화할 수 있습니다.
제공하여 쌍 포인트 에 Ascii 활성화 방법. 그만큼 Ptr 암시적이다
네트 장치는 정확히 하나의 노드에 속해야 하기 때문입니다. 예를 들어,
Ptr 차;
...
helper.EnableAscii("접두사", nd);
· 처음 네 가지 방법에는 다음과 같은 기본 매개변수도 포함됩니다. 명시적 파일 이름 그
PCAP의 경우 등가 매개변수와 유사하게 작동합니다.
이 경우 ASCII 추적 파일에 추적 컨텍스트가 기록되지 않습니다.
불필요한. 시스템은 다음과 동일한 규칙을 사용하여 생성할 파일 이름을 선택합니다.
파일에 접미사가 있다는 점을 제외하고 PCAP 섹션에 설명되어 있습니다. .tr 대신
.pcap.
· 둘 이상의 네트 장치에서 ASCII 추적을 활성화하고 모든 추적을 전송하려는 경우
단일 파일에 대해 개체를 사용하여 단일 파일을 참조하는 방식으로도 그렇게 할 수 있습니다.
우리는 이미 위의 "cwnd" 예제에서 이것을 보았습니다:
Ptr nd1;
Ptr nd2;
...
Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr");
...
helper.EnableAscii(스트림, nd1);
helper.EnableAscii(스트림, nd2);
이 경우 추적 컨텍스트 are 필요하므로 ASCII 추적 파일에 기록됨
두 장치에서 추적을 명확하게 합니다. 사용자가 완전히
파일 이름을 지정하면 문자열에 다음이 포함되어야 합니다. ,tr 일관성을 위한 접미사.
· 다음을 제공하여 특정(노드, 넷-장치) 쌍에서 ASCII 추적을 활성화할 수 있습니다.
표준::문자열 객체 이름 서비스 문자열을 Pcap 활성화 방법. 그만큼
포인트 이름 문자열에서 조회됩니다. 다시 말하지만, 이후로 암시적이다
명명된 네트 장치는 정확히 하나의 노드에 속해야 합니다. 예를 들어,
이름::추가("클라이언트" ...);
이름::추가("클라이언트/eth0" ...);
이름::추가("서버" ...);
이름::추가("서버/eth0" ...);
...
helper.EnableAscii("접두사", "클라이언트/eth0");
helper.EnableAscii("접두사", "서버/eth0");
이렇게 하면 ``prefix-client-eth0.tr``이라는 두 개의 파일이 생성되고
``prefix-server-eth0.tr``에 있는 각 장치에 대한 추적
각각의 추적 파일. 모든 ``EnableAscii`` 기능이
스트림 래퍼를 사용하도록 오버로드된 경우 해당 형식을 다음과 같이 사용할 수 있습니다.
잘::
이름::추가("클라이언트" ...);
이름::추가("클라이언트/eth0" ...);
이름::추가("서버" ...);
이름::추가("서버/eth0" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr");
...
helper.EnableAscii(스트림, "클라이언트/eth0");
helper.EnableAscii(스트림, "서버/eth0");
이렇게 하면 다음과 같은 단일 추적 파일이 생성됩니다. 추적 파일 이름.tr 모두 포함하는
두 장치에 대한 추적 이벤트. 이벤트는 추적 컨텍스트에 의해 명확해집니다.
문자열.
· 다음을 제공하여 (노드, 넷-장치) 쌍 모음에서 ASCII 추적을 활성화할 수 있습니다.
NetDevice컨테이너. 각각 NetDevice 컨테이너에서 유형이 확인됩니다. 각각
적절한 유형의 장치(장치 도우미가 관리하는 것과 동일한 유형), 추적은
활성화되었습니다. 다시 말하지만, 발견된 넷 장치가 다음에 속해야 하므로 암시적입니다.
정확히 하나의 노드. 예를 들어,
NetDeviceContainer d = ...;
...
helper.EnableAscii("접두사", d);
이로 인해 많은 ASCII 추적 파일이 생성됩니다.
각각은`` - - .tr``
협약.
모든 추적을 단일 파일로 결합하는 것은 예제와 유사하게 수행됩니다.
위 :
NetDeviceContainer d = ...;
...
Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr");
...
helper.EnableAscii(스트림, d);
· 다음을 제공하여 (노드, 넷-장치) 쌍 모음에서 ASCII 추적을 활성화할 수 있습니다.
노드컨테이너. 각 노드에 대해 노드컨테이너 붙어있어 NetDevices 반복됩니다.
각각 NetDevice 컨테이너의 각 노드에 연결된 경우 해당 장치의 유형은 다음과 같습니다.
확인. 적절한 유형의 각 장치에 대해(장치에서 관리하는 것과 동일한 유형
도우미), 추적이 활성화됩니다.
NodeContainern;
...
helper.EnableAscii ("접두사", n);
이로 인해 여러 ASCII 추적 파일이 생성되며 각 파일은 다음과 같습니다.
전에, - 아이디>- 아이디>.tr 협약. 모든 흔적을 하나로 결합
단일 파일은 위의 예와 유사하게 수행됩니다.
· 노드 ID 및 장치 ID를 기반으로 PCAP 추적을 활성화할 수 있습니다.
명백한 Ptr. 시스템의 각 노드에는 정수 노드 ID와 연결된 각 장치가 있습니다.
노드에 정수 장치 ID가 있습니다.
helper.EnableAscii("접두사", 21, 1);
물론, 위와 같이 추적을 단일 파일로 결합할 수 있습니다.
· 마지막으로 시스템의 모든 장치에 대해 동일한 유형의 PCAP 추적을 활성화할 수 있습니다.
장치 도우미에서 관리하는 것으로.
helper.EnableAsciiAll("접두사");
이로 인해 모든 장치에 대해 하나씩 많은 ASCII 추적 파일이 생성됩니다.
헬퍼가 관리하는 유형의 시스템에서. 이 모든 파일은 다음을 따릅니다.
- 아이디>- 아이디>.tr 협약. 모든 흔적을 하나로 결합
파일은 위의 예와 유사하게 수행됩니다.
파일명
위의 접두사 스타일 메서드 설명에 암시된 것은 완전한 구성입니다.
구현 방법에 따른 파일 이름. 규칙에 따라 ASCII 추적은 NS-3 체계
형태의 - 아이디>- 아이디>.tr
앞에서 언급했듯이 시스템의 모든 노드에는 시스템 할당 노드 ID가 있습니다. 그리고
모든 장치에는 노드와 관련된 인터페이스 인덱스(장치 ID라고도 함)가 있습니다.
기본적으로 ASCII 추적 파일은 첫 번째 추적을 활성화한 결과로 생성됩니다.
접두사 "접두사"를 사용하는 노드 21의 장치는 접두사-21-1.tr.
항상 사용할 수 있습니다 NS-3 이것을 더 명확하게 하기 위해 객체 이름 서비스. 예를 들어,
개체 이름 서비스를 사용하여 노드 21에 "server"라는 이름을 할당하면 결과
ASCII 추적 파일 이름은 자동으로 접두사-서버-1.tr 그리고 당신이 또한 할당한다면
장치에 "eth0"이라는 이름을 지정하면 ASCII 추적 파일 이름이 자동으로 선택됩니다.
그리고 부름을 받다 접두사-서버-eth0.tr.
여러 메서드에는 라는 기본 매개변수가 있습니다. 명시적 파일 이름. 설정시
true인 경우 이 매개변수는 자동 파일 이름 완성 메커니즘을 비활성화하고 다음을 허용합니다.
명시적인 파일 이름을 생성합니다. 이 옵션은 a를 취하는 메서드에서만 사용할 수 있습니다.
접두사를 지정하고 단일 장치에서 추적을 활성화합니다.
프로토콜 도우미
PCAP
이들의 목표 믹스 인 일관된 PCAP 추적 기능을 쉽게 추가할 수 있습니다.
프로토콜. 우리는 PCAP 추적의 다양한 특징이 모두 동일하게 작동하기를 원합니다.
프로토콜이므로 이러한 도우미의 메서드는 스택 도우미에 의해 상속됩니다. 보세요
src/네트워크/helper/trace-helper.h 보면서 토론을 따라가고 싶다면
실제 코드.
이 섹션에서는 프로토콜에 적용되는 방법을 설명합니다. IPv4. 에
유사한 프로토콜로 추적을 지정하려면 적절한 유형으로 대체하면 됩니다. 예를 들어,
~을 사용하다 포인트 대신에 포인트 전화 PcapIpv6 활성화 대신 PcapIpv4 활성화.
클래스 PcapHelperForIpv4 PCAP 추적을 사용하기 위한 높은 수준의 기능을 제공합니다.
인간을 IPv4 규약. 이러한 메서드를 활성화하는 각 프로토콜 도우미는 단일 메서드를 구현해야 합니다.
이 클래스에서 상속된 가상 메서드입니다. 별도의 구현이 있을 예정입니다.
IPv6, 예를 들어 메서드 이름과 서명에만 차이가 있습니다.
클래스를 명확하게 하려면 다른 메소드 이름이 필요합니다. IPv4 에 IPv6 둘 다
클래스에서 파생됨 목적, 동일한 서명을 공유하는 메소드.
가상 무효 EnablePcapIpv4Internal(std::string 접두사,
Ptr IPv4,
uint32_t 인터페이스,
부울 명시적 파일 이름) = 0;
이 메소드의 서명은 프로토콜과 인터페이스 중심 관점을 반영합니다.
이 수준의 상황입니다. 클래스에서 상속된 모든 공개 메소드 PcapHelperForIpv4
이 단일 장치 종속 구현 방법을 호출하는 것으로 줄입니다. 예를 들어,
가장 낮은 수준의 PCAP 방법,
무효 EnablePcapIpv4 (std::string 접두사, Ptr ipv4, uint4_t 인터페이스, 부울 명시적 파일 이름 = 거짓);
다음의 장치 구현을 호출합니다. PcapIpv4내부 활성화 곧장. 기타 모든 공개
PCAP 추적 방법은 이 구현을 기반으로 추가 사용자 수준을 제공합니다.
기능. 이것이 사용자에게 의미하는 바는 시스템의 모든 프로토콜 헬퍼가
모든 PCAP 추적 방법을 사용할 수 있습니다. 이러한 방법은 모두
헬퍼가 구현하는 경우 프로토콜 전체에서 동일한 방식 PcapIpv4내부 활성화 바르게.
행동 양식
이러한 방법은 노드와 일대일 대응하도록 설계되었습니다.
NetDevice- 장치 버전의 중심 버전. 노드 대신 NetDevice 쌍
제약 조건, 우리는 프로토콜 및 인터페이스 제약 조건을 사용합니다.
장치 버전과 마찬가지로 XNUMX가지 방법이 있습니다.
무효 EnablePcapIpv4 (std::string 접두사, Ptr ipv4, uint4_t 인터페이스, 부울 명시적 파일 이름 = 거짓);
무효 EnablePcapIpv4(std::문자열 접두사, std::문자열 ipv4Name, uint32_t 인터페이스, 부울 명시적 파일 이름 = 거짓);
void EnablePcapIpv4(std::string 접두사, Ipv4InterfaceContainer c);
void EnablePcapIpv4(std::string 접두사, NodeContainer n);
무효 EnablePcapIpv4(std::문자열 접두사, uint32_t nodeid, uint32_t 인터페이스, bool 명시적 파일 이름);
void EnablePcapIpv4All (std::string 접두사);
클래스에 대한 API 문서를 정독하는 것이 좋습니다. PcapHelperForIpv4 를 찾는 방법
이러한 방법의 세부사항; 하지만 요약하자면 ...
· 다음을 제공하여 특정 프로토콜/인터페이스 쌍에서 PCAP 추적을 활성화할 수 있습니다.
포인트 and 인터페이스 에 Pcap 활성화 방법. 예를 들어,
포인트 ipv4 = 노드->GetObject ();
...
helper.EnablePcapIpv4("접두사", ipv4, 0);
· 다음을 제공하여 특정 노드/네트-장치 쌍에서 PCAP 추적을 활성화할 수 있습니다.
표준::문자열 객체 이름 서비스 문자열을 Pcap 활성화 방법. 그만큼
포인트 이름 문자열에서 조회됩니다. 예를 들어,
이름::추가("serverIPv4" ...);
...
helper.EnablePcapIpv4("접두사", "serverIpv4", 1);
· 다음을 제공하여 프로토콜/인터페이스 쌍 모음에서 PCAP 추적을 활성화할 수 있습니다.
IPv4인터페이스 컨테이너. 각각 IPv4 /컨테이너 프로토콜의 인터페이스 쌍
유형이 체크되어 있습니다. 적절한 유형의 각 프로토콜에 대해
장치 도우미), 해당 인터페이스에 대해 추적이 활성화됩니다. 예를 들어,
NodeContainer 노드;
...
NetDeviceContainer 장치 = deviceHelper.Install(노드);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer 인터페이스 = ipv4.Assign(장치);
...
helper.EnablePcapIpv4("접두사", 인터페이스);
· 다음을 제공하여 프로토콜/인터페이스 쌍 모음에서 PCAP 추적을 활성화할 수 있습니다.
노드컨테이너. 각 노드에 대해 노드컨테이너 적절한 프로토콜을 찾았습니다.
각 프로토콜에 대해 해당 인터페이스가 열거되고 결과에서 추적이 활성화됩니다.
한 쌍. 예를 들어,
NodeContainern;
...
helper.EnablePcapIpv4("접두사", n);
· 노드 ID 및 인터페이스를 기반으로 PCAP 추적을 활성화할 수도 있습니다. 이에
이 경우 node-id는 다음으로 변환됩니다. Ptr 적절한 프로토콜이 조회됩니다.
노드에서. 결과 프로토콜 및 인터페이스는 결과를 지정하는 데 사용됩니다.
추적 소스.
helper.EnablePcapIpv4("접두사", 21, 1);
· 마지막으로 시스템의 모든 인터페이스에 대해 PCAP 추적을 활성화할 수 있습니다.
프로토콜은 장치 도우미에서 관리하는 것과 동일한 유형입니다.
helper.EnablePcapIpv4All("접두사");
파일명
위의 모든 메소드 설명에는 완전한 메소드 구성이 암시되어 있습니다.
구현 방법에 따른 파일 이름. 규칙에 따라 PCAP 추적은
전에, NS-3 시스템은 " - - .pcap"의 경우
프로토콜 추적에서는 프로토콜과 프로토콜 사이에 일대일 대응이 있습니다. 노드. 이
프로토콜 때문이다 사물 로 집계됩니다. 노드 사물. 글로벌이 없기 때문에
시스템의 프로토콜 ID, 파일 이름 지정에 해당 노드 ID를 사용합니다. 그러므로
자동으로 선택된 추적 파일 이름에서 파일 이름 충돌 가능성이 있습니다.
이러한 이유로 프로토콜 추적에 대한 파일 이름 규칙이 변경됩니다.
앞에서 언급했듯이 시스템의 모든 노드에는 시스템 할당 노드 ID가 있습니다.
프로토콜 인스턴스와 Node 인스턴스 사이에는 일대일 대응이 있기 때문에
노드 ID를 사용합니다. 각 인터페이스에는 해당 프로토콜과 관련된 인터페이스 ID가 있습니다. 우리는 사용
대회 " -N -나 추적 파일 이름 지정을 위한 .pcap"
프로토콜 도우미.
따라서 기본적으로 추적을 활성화한 결과 생성된 PCAP 추적 파일은
접두사 "접두사"를 사용하는 노드 1의 Ipv4 프로토콜 인터페이스 21은 다음과 같습니다.
"접두사-n21-i1.pcap".
항상 사용할 수 있습니다 NS-3 이것을 더 명확하게 하기 위해 객체 이름 서비스. 예를 들어,
개체 이름 서비스를 사용하여 Ptr에 "serverIpv4"라는 이름을 할당합니다. 노드에서
21, 결과 PCAP 추적 파일 이름은 자동으로
"prefix-nserverIpv4-i1.pcap".
여러 메서드에는 라는 기본 매개변수가 있습니다. 명시적 파일 이름. 설정시
true인 경우 이 매개변수는 자동 파일 이름 완성 메커니즘을 비활성화하고 다음을 허용합니다.
명시적인 파일 이름을 생성합니다. 이 옵션은 a를 취하는 메서드에서만 사용할 수 있습니다.
접두사를 지정하고 단일 장치에서 추적을 활성화합니다.
ASCII
ASCII 추적 도우미의 동작은 실질적으로 PCAP 경우와 유사합니다. 가져가
보고 src/네트워크/helper/trace-helper.h 동안 토론을 따르고 싶다면
실제 코드를 보면
이 섹션에서는 프로토콜에 적용되는 방법을 설명합니다. IPv4. 에
유사한 프로토콜로 추적을 지정하려면 적절한 유형으로 대체하면 됩니다. 예를 들어,
~을 사용하다 포인트 대신에 포인트 전화 AsciiIpv6 활성화 대신
AsciiIpv4 활성화.
클래스 AsciiTraceHelperForIpv4 ASCII 사용을 위한 높은 수준의 기능 추가
프로토콜 도우미를 추적합니다. 이러한 메서드를 활성화하는 각 프로토콜은 다음을 구현해야 합니다.
이 클래스에서 상속된 단일 가상 메서드입니다.
가상 무효 EnableAsciiIpv4Internal(Ptr 개울,
std::문자열 접두사,
Ptr IPv4,
uint32_t 인터페이스,
부울 명시적 파일 이름) = 0;
이 메소드의 서명은 프로토콜 및 인터페이스 중심의 관점을 반영합니다.
이 수준의 상황; 또한 헬퍼가 공유된
출력 스트림. 클래스에서 상속된 모든 공개 메소드
PcapAndAsciiTraceHelperForIpv4 이 단일 장치 종속 호출로 줄입니다.
구현 방법. 예를 들어, 가장 낮은 수준의 ASCII 추적 방법,
무효 EnableAsciiIpv4 (std::string 접두사, Ptr ipv4, uint4_t 인터페이스, 부울 명시적 파일 이름 = 거짓);
무효 EnableAsciiIpv4(Ptr 스트림, PTR ipv4, uint4_t 인터페이스);
다음의 장치 구현을 호출합니다. AsciiIpv4내부 활성화 직접 제공하거나
접두사 또는 스트림. 다른 모든 공용 ASCII 추적 방법은 다음을 기반으로 합니다.
추가 사용자 수준 기능을 제공하는 저수준 기능. 이것이 의미하는 바
사용자는 시스템의 모든 장치 도우미가 모든 ASCII 추적 방법을 갖게 된다는 것입니다.
사용 가능; 이러한 방법은 다음과 같은 경우 프로토콜 전체에서 모두 동일한 방식으로 작동합니다.
프로토콜 구현 EnablAsciiIpv4내부 바르게.
행동 양식
무효 EnableAsciiIpv4 (std::string 접두사, Ptr ipv4, uint4_t 인터페이스, 부울 명시적 파일 이름 = 거짓);
무효 EnableAsciiIpv4(Ptr 스트림, PTR ipv4, uint4_t 인터페이스);
무효 EnableAsciiIpv4(std::문자열 접두어, std::문자열 ipv4Name, uint32_t 인터페이스, 부울 명시적 파일 이름 = false);
무효 EnableAsciiIpv4(Ptr 스트림, std::string ipv4Name, uint32_t 인터페이스);
void EnableAsciiIpv4(std::string 접두사, Ipv4InterfaceContainer c);
무효 EnableAsciiIpv4(Ptr 스트림, Ipv4InterfaceContainer c);
void EnableAsciiIpv4(std::string 접두사, NodeContainer n);
무효 EnableAsciiIpv4(Ptr 스트림, NodeContainer n);
void EnableAsciiIpv4All(std::string 접두사);
무효화 EnableAsciiIpv4All(Ptr 개울);
무효 EnableAsciiIpv4(std::문자열 접두사, uint32_t nodeid, uint32_t deviceid, bool 명시적 파일 이름);
무효 EnableAsciiIpv4(Ptr 스트림, uint32_t nodeid, uint32_t 인터페이스);
클래스에 대한 API 문서를 정독하는 것이 좋습니다. PcapAndAsciiHelperForIpv4 에
이러한 방법의 세부 사항을 찾으십시오. 그러나 요약하자면 ...
· ASCII 추적에 사용할 수 있는 방법이 PCAP보다 두 배 더 많습니다.
트레이싱. 이것은 PCAP 스타일 모델 외에도 각각의 추적이 있기 때문입니다.
고유한 프로토콜/인터페이스 쌍이 고유한 파일에 기록되면 다음과 같은 모델을 지원합니다.
많은 프로토콜/인터페이스 쌍에 대한 추적 정보가 공통 파일에 기록됩니다. 이것
는 -N - 파일 이름 생성 메커니즘은
공통 파일을 참조하는 메커니즘으로 대체되었습니다. API 메서드의 수는
모든 조합을 허용하려면 두 배입니다.
· PCAP 추적에서와 마찬가지로 특정 프로토콜/인터페이스에서 ASCII 추적을 활성화할 수 있습니다.
제공하여 쌍 포인트 및 인터페이스 에 Ascii 활성화 방법. 예를 들어,
Ptr IPv4;
...
helper.EnableAsciiIpv4("접두사", ipv4, 1);
이 경우 ASCII 추적 파일에 추적 컨텍스트가 기록되지 않습니다.
불필요한. 시스템은 다음과 동일한 규칙을 사용하여 생성할 파일 이름을 선택합니다.
파일에 접미사 ".tr"이 대신 붙는다는 점을 제외하면 PCAP 섹션에 설명되어 있습니다.
".pcap"의.
· 둘 이상의 인터페이스에서 ASCII 추적을 활성화하고 모든 추적을 전송하려는 경우
단일 파일에 대해 개체를 사용하여 단일 파일을 참조하는 방식으로도 그렇게 할 수 있습니다.
우리는 이미 위의 "cwnd" 예제에서 이와 비슷한 것을 가지고 있습니다:
Ptr 프로토콜4 = node1->GetObject ();
Ptr 프로토콜4 = node2->GetObject ();
...
Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr");
...
helper.EnableAsciiIpv4(스트림, 프로토콜1, 1);
helper.EnableAsciiIpv4(스트림, 프로토콜2, 1);
이 경우 추적 컨텍스트는 필요하므로 ASCII 추적 파일에 기록됩니다.
두 인터페이스의 추적을 명확하게 합니다. 사용자가 완전히
파일 이름을 지정하면 일관성을 위해 문자열에 ",tr"이 포함되어야 합니다.
· 다음을 제공하여 특정 프로토콜에서 ASCII 추적을 활성화할 수 있습니다. 표준::문자열
객체 이름 서비스 문자열을 Pcap 활성화 방법. 그만큼 포인트 is
이름 문자열에서 찾아보았습니다. 그만큼 결과 파일 이름에는 암시적입니다.
프로토콜 인스턴스와 노드 사이에 일대일 대응이 있습니다. 예를 들어,
이름::추가("node1Ipv4" ...);
이름::추가("node2Ipv4" ...);
...
helper.EnableAsciiIpv4("접두사", "node1Ipv4", 1);
helper.EnableAsciiIpv4("접두사", "node2Ipv4", 1);
그러면 "prefix-nnode1Ipv4-i1.tr"이라는 두 개의 파일이 생성되고
해당 추적 파일의 각 인터페이스에 대한 추적이 포함된 "prefix-nnode2Ipv4-i1.tr"입니다.
모든 EnableAscii 함수는 스트림 래퍼를 사용하도록 오버로드되므로 다음을 수행할 수 있습니다.
해당 형식도 사용하십시오.
이름::추가("node1Ipv4" ...);
이름::추가("node2Ipv4" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr");
...
helper.EnableAsciiIpv4(스트림, "node1Ipv4", 1);
helper.EnableAsciiIpv4(스트림, "node2Ipv4", 1);
이것은 모든 것을 포함하는 "trace-file-name.tr"이라는 단일 추적 파일을 생성합니다.
두 인터페이스에 대한 추적 이벤트. 이벤트는 추적에 의해 명확해집니다.
컨텍스트 문자열.
· 다음을 제공하여 프로토콜/인터페이스 쌍 모음에서 ASCII 추적을 활성화할 수 있습니다.
IPv4인터페이스 컨테이너. 적절한 유형의 각 프로토콜에 대해
장치 헬퍼에 의해 관리됨) 해당 인터페이스에 대해 추적이 활성화됩니다.
다시 말하지만, 각 사이에 일대일 대응이 있기 때문에 암묵적입니다.
프로토콜과 그 노드. 예를 들어,
NodeContainer 노드;
...
NetDeviceContainer 장치 = deviceHelper.Install(노드);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer 인터페이스 = ipv4.Assign(장치);
...
...
helper.EnableAsciiIpv4("접두사", 인터페이스);
이로 인해 여러 ASCII 추적 파일이 생성되며 각 파일은 다음과 같습니다.
그만큼 -N -나 .tr 규칙. 모든 흔적을 하나로 결합
단일 파일은 위의 예와 유사하게 수행됩니다.
NodeContainer 노드;
...
NetDeviceContainer 장치 = deviceHelper.Install(노드);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer 인터페이스 = ipv4.Assign(장치);
...
Ptr stream = asciiTraceHelper.CreateFileStream("trace-file-name.tr");
...
helper.EnableAsciiIpv4(스트림, 인터페이스);
· 다음을 제공하여 프로토콜/인터페이스 쌍 모음에서 ASCII 추적을 활성화할 수 있습니다.
노드컨테이너. 각 노드에 대해 노드컨테이너 적절한 프로토콜을 찾았습니다.
각 프로토콜에 대해 해당 인터페이스가 열거되고 결과에서 추적이 활성화됩니다.
한 쌍. 예를 들어,
NodeContainern;
...
helper.EnableAsciiIpv4("접두사", n);
이로 인해 여러 ASCII 추적 파일이 생성되며 각 파일은 다음과 같습니다.
그만큼 - - .tr 규칙. 모든 흔적을 하나로 결합
단일 파일은 위의 예와 유사하게 수행됩니다.
· 노드 ID 및 장치 ID를 기반으로 PCAP 추적을 활성화할 수도 있습니다. 이에
이 경우 node-id는 다음으로 변환됩니다. Ptr 적절한 프로토콜이 조회됩니다.
노드에서. 결과 프로토콜 및 인터페이스는 결과를 지정하는 데 사용됩니다.
추적 소스.
helper.EnableAsciiIpv4 ("접두사", 21, 1);
물론, 위와 같이 추적을 단일 파일로 결합할 수 있습니다.
· 마지막으로 시스템의 모든 인터페이스에 대해 ASCII 추적을 활성화할 수 있습니다.
프로토콜은 장치 도우미에서 관리하는 것과 동일한 유형입니다.
helper.EnableAsciiIpv4All("접두사");
이로 인해 모든 ASCII 추적 파일이 생성됩니다.
도우미가 관리하는 유형의 프로토콜과 관련된 시스템의 인터페이스. 모든
이 파일은 다음을 따릅니다. -N -나
단일 파일에 대한 모든 추적은 위의 예와 유사하게 수행됩니다.
파일명
위의 접두사 스타일 메서드 설명에 암시된 것은 완전한 구성입니다.
구현 방법에 따른 파일 이름. 규칙에 따라 ASCII 추적은 NS-3 체계
형식이다" - - .tr"
앞에서 언급했듯이 시스템의 모든 노드에는 시스템 할당 노드 ID가 있습니다.
프로토콜과 노드 사이에 일대일 대응이 있기 때문에 node-id에 사용합니다.
프로토콜 ID를 식별합니다. 특정 프로토콜의 모든 인터페이스에는
해당 프로토콜과 관련된 인터페이스 인덱스(단순히 인터페이스라고도 함)입니다. 기본적으로,
그런 다음 첫 번째 장치에서 추적을 활성화한 결과 ASCII 추적 파일이 생성됩니다.
접두사 "prefix"를 사용하는 노드 21은 "prefix-n21-i1.tr"입니다. 접두사를 사용하여
노드당 여러 프로토콜을 명확하게 합니다.
항상 사용할 수 있습니다 NS-3 이것을 더 명확하게 하기 위해 객체 이름 서비스. 예를 들어,
개체 이름 서비스를 사용하여 노드의 프로토콜에 "serverIpv4"라는 이름을 할당합니다.
21, 또한 인터페이스 XNUMX을 지정하면 결과 ASCII 추적 파일 이름이 자동으로
"prefix-nserverIpv4-1.tr"이 됩니다.
여러 메서드에는 라는 기본 매개변수가 있습니다. 명시적 파일 이름. 설정시
true인 경우 이 매개변수는 자동 파일 이름 완성 메커니즘을 비활성화하고 다음을 허용합니다.
명시적인 파일 이름을 생성합니다. 이 옵션은 a를 취하는 메서드에서만 사용할 수 있습니다.
접두사를 지정하고 단일 장치에서 추적을 활성화합니다.
요약
NS-3 여러 수준의 사용자가 사용자 정의할 수 있는 매우 풍부한 환경을 포함합니다.
시뮬레이션에서 추출할 수 있는 정보의 종류.
사용자가 단순히 컬렉션을 제어할 수 있는 고급 도우미 기능이 있습니다.
미세한 단위로 미리 정의된 출력. 허용하는 중간 수준의 도우미 기능이 있습니다.
정보가 추출되고 저장되는 방법을 사용자 정의하는 보다 정교한 사용자 거기
전문 사용자가 시스템을 변경하여 새롭고
사용자가 즉시 액세스할 수 있는 방식으로 이전에 내보내지 않은 정보
더 높은 수준.
이것은 매우 포괄적인 시스템이며 특히 소화해야 할 것이 많다는 것을 알고 있습니다.
새로운 사용자나 C++ 및 관용구에 친숙하지 않은 사용자를 위한 것입니다. 우리는 고려
추적 시스템은 매우 중요한 부분입니다. NS-3 따라서 다음과 같이 익숙해지는 것이 좋습니다.
그것으로 가능합니다. 아마도 나머지 부분을 이해하는 경우 일 것입니다. NS-3 체계
추적 시스템을 마스터하면 매우 간단합니다.
데이터 COLLECTION
마지막 튜토리얼 챕터에서는 NS-3 버전에서
3.18이며 아직 개발 중입니다. 이 자습서 섹션은 또한
진행중인 작업.
자극
시뮬레이션 실행의 주요 포인트 중 하나는 출력 데이터를 생성하는 것입니다.
연구 목적 또는 단순히 시스템에 대해 배우기 위해. 이전 장에서 우리는
추적 하위 시스템과 예제를 소개했습니다. 여섯번째.cc. PCAP 또는 ASCII 추적에서
파일이 생성됩니다. 이러한 추적은 다양한 방법을 사용하여 데이터 분석에 유용합니다.
외부 도구 및 많은 사용자에게 이러한 출력 데이터는 선호하는 수집 수단입니다.
데이터(외부 도구에 의한 분석용).
그러나 다음을 포함하여 추적 파일 생성 이상의 사용 사례도 있습니다.
다음 :
· 비패킷과 같은 PCAP 또는 ASCII 추적에 잘 매핑되지 않는 데이터 생성
데이터(예: 프로토콜 상태 기계 전환),
· 추적 파일을 생성하기 위한 디스크 I/O 요구 사항이 다음과 같은 대규모 시뮬레이션
금지되거나 번거롭고
· 에 대한 필요성 온라인 시뮬레이션 과정에서 데이터 감소 또는 계산.
이것의 좋은 예는 시뮬레이션에 대한 종료 조건을 정의하는 것입니다.
충분히 좁은 신뢰도를 형성하기에 충분한 데이터를 수신했을 때 멈출 때
일부 매개변수의 추정치 주변의 간격.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 NS-3 데이터 수집 프레임워크는 이러한 추가 기능을 제공하도록 설계되었습니다.
추적 기반 출력 이상. 이 주제에 관심이 있는 독자는 상담을 권장합니다.
전에, NS-3 이 프레임워크를 보다 자세히 다루기 위한 매뉴얼 여기서는 다음과 같이 요약합니다.
일부 개발 기능의 예제 프로그램입니다.
예시 암호
튜토리얼 예시 예제/튜토리얼/seventh.cc 유사하다 여섯번째.cc 예 우리
몇 가지 변경 사항을 제외하고 이전에 검토했습니다. 첫째, IPv6에 대해 활성화되었습니다.
명령줄 옵션으로 지원:
커맨드라인 cmd;
cmd.AddValue ("useIpv6", "Ipv6 사용", useV6);
cmd.Parse(argc, argv);
사용자가 지정하는 경우 useIpv6, 옵션을 선택하면 프로그램이 IPv6 대신 IPv4을 사용하여 실행됩니다.
이 어플리케이션에는 XNUMXµm 및 XNUMXµm 파장에서 최대 XNUMXW의 평균 출력을 제공하는 도움 옵션, 모두 사용 가능 NS-3 CommandLine 개체를 다음과 같이 지원하는 프로그램
위에 표시된 대로 다음과 같이 호출할 수 있습니다(큰따옴표 사용에 유의하십시오).
./waf --run "일곱번째 --help"
다음을 생성합니다.
ns3-dev-seventh-debug [프로그램 인수] [일반 인수]
프로그램 인수:
--useIpv6: IPv6 사용[false]
일반적인 주장:
--PrintGlobals: 전역 목록을 인쇄합니다.
--PrintGroups: 그룹 목록을 인쇄합니다.
--PrintGroup=[그룹]: 그룹의 모든 TypeId를 인쇄합니다.
--PrintTypeIds: 모든 TypeId를 인쇄합니다.
--PrintAttributes=[typeid]: typeid의 모든 속성을 인쇄합니다.
--PrintHelp: 이 도움말 메시지를 인쇄합니다.
이 기본값(useIpv4이 false이므로 IPv6 사용)은 부울을 전환하여 변경할 수 있습니다.
값은 다음과 같습니다.
./waf --run "일곱 번째 --useIpv6=1"
다음과 같이 생성된 pcap을 살펴보십시오. TCP 덤프:
tcpdump -r XNUMX번째.pcap -nn -tt
이것은 IPv6 지원 및 명령줄에 대한 짧은 여담이었습니다.
이 자습서의 앞부분에서 소개했습니다. 명령줄 사용의 전용 예는
참조하십시오 src/core/examples/command-line-example.cc.
이제 데이터 수집으로 돌아갑니다. 에서 예제/튜토리얼/ 디렉토리에서 다음을 입력하십시오.
명령: diff -u 여섯번째.cc 일곱번째.cc, 그리고 이 diff의 새 줄 중 일부를 검사합니다.
+ std::string 프로브 유형;
+ 표준::문자열 추적 경로;
+ 경우 (useV6 == 거짓)
+ {
...
+ probeType = "ns3::Ipv4PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
+ }
+ 다른
+ {
...
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
+ }
...
+ // GnuplotHelper를 사용하여 시간 경과에 따른 패킷 바이트 수를 플로팅합니다.
+ GnuplotHelper 플롯헬퍼;
+
+ // 플롯을 구성합니다. 첫 번째 인수는 파일 이름 접두사입니다.
+ // 생성된 출력 파일용. 두 번째, 세 번째, 네 번째
+ // 인수는 각각 플롯 제목, x축 및 y축 레이블입니다.
+ plotHelper.ConfigurePlot("일곱 번째 패킷 바이트 수",
+ "패킷 바이트 수 대 시간",
+ "시간(초)",
+ "패킷 바이트 수");
+
+ // 프로브 유형, 추적 소스 경로(구성 네임스페이스에서) 및
+ // 플로팅할 출력 추적 소스("OutputBytes")를 조사합니다. 네 번째 인수
+ // 플롯의 데이터 계열 레이블 이름을 지정합니다. 마지막
+ // 인수는 키를 배치해야 하는 위치를 지정하여 플롯의 형식을 지정합니다.
+ plotHelper.PlotProbe(프로브 유형,
+ 추적 경로,
+ "출력바이트",
+ "패킷 바이트 수",
+ GnuplotAggregator::KEY_BELOW);
+
+ // FileHelper를 사용하여 시간 경과에 따른 패킷 바이트 수를 기록합니다.
+ FileHelper fileHelper;
+
+ // 쓸 파일과 출력 데이터의 형식을 구성합니다.
+ fileHelper.ConfigureFile("일곱 번째 패킷 바이트 수",
+ 파일 수집기::포맷됨);
+
+ // 이 형식화된 출력 파일의 레이블을 설정합니다.
+ fileHelper.Set2dFormat("시간(초) = %.3e\t패킷 바이트 수 = %.0f");
+
+ // 프로브 유형, 프로브 경로(구성 네임스페이스에서) 및
+ // 쓸 프로브 출력 추적 소스("OutputBytes").
+ fileHelper.WriteProbe(프로브 유형,
+ 추적 경로,
+ "출력바이트");
+
시뮬레이터::정지(초(20));
시뮬레이터::실행();
시뮬레이터::파괴();
신중한 독자라면 위의 IPv6 명령줄 속성을 테스트할 때
그 일곱번째.cc 여러 개의 새 출력 파일을 만들었습니다.
일곱 번째-패킷-바이트-카운트-0.txt
일곱 번째-패킷-바이트-카운트-1.txt
일곱 번째-패킷-바이트-count.dat
일곱 번째 패킷 바이트 수.plt
일곱 번째-패킷-바이트-카운트.png
일곱 번째-패킷-바이트-count.sh
이들은 위에 소개된 추가 진술에 의해 생성되었습니다. 특히,
GnuplotHelper 및 FileHelper. 이 데이터는 데이터 수집을 후킹하여 생성되었습니다.
에 구성 요소 NS-3 소스를 추적하고 데이터를 형식화된 그누플롯 and
형식이 지정된 텍스트 파일로. 다음 섹션에서는 이들 각각을 검토할 것입니다.
Gnuplot도우미
GnuplotHelper는 NS-3 생산을 목표로 하는 도우미 개체 그누플롯 플롯
일반적인 경우에 대해 가능한 한 적은 진술. 그것은 후크 NS-3 데이터가 있는 추적 소스
데이터 수집 시스템에서 지원하는 유형. 전부는 아니다 NS-3 추적 소스 데이터 유형은 다음과 같습니다.
지원되지만 일반 추적이 있는 TracedValues를 포함하여 많은 일반적인 추적 유형이 있습니다.
데이터(POD) 유형.
이 도우미가 생성한 출력을 살펴보겠습니다.
일곱 번째-패킷-바이트-count.dat
일곱 번째 패킷 바이트 수.plt
일곱 번째-패킷-바이트-count.sh
첫 번째는 공백으로 구분된 일련의 타임스탬프와 패킷이 포함된 gnuplot 데이터 파일입니다.
바이트 수. 이 특정 데이터 출력이 아래에서 어떻게 구성되었는지 다루겠지만
출력 파일을 계속 사용하십시오. 파일 일곱 번째 패킷 바이트 수.plt gnuplot 플롯입니다.
gnuplot 내에서 열 수 있는 파일입니다. gnuplot 구문을 이해하는 독자는
이것이 이름이 지정된 형식화된 출력 PNG 파일을 생성하는지 확인하십시오.
일곱 번째-패킷-바이트-카운트.png. 마지막으로 작은 쉘 스크립트
일곱 번째-패킷-바이트-count.sh gnuplot을 통해 이 플롯 파일을 실행하여 원하는
PNG(이미지 편집기에서 볼 수 있음) 즉, 다음 명령입니다.
sh 일곱 번째-패킷-바이트-카운트.sh
양보 할 것이다 일곱 번째-패킷-바이트-카운트.png. 이 PNG는 왜 처음에 제작되지 않았습니까?
장소? 대답은 plt 파일을 제공함으로써 사용자가 직접 구성할 수 있다는 것입니다.
PNG를 생성하기 전에 원하는 경우 결과.
PNG 이미지 제목에는 이 플롯이 "패킷 바이트 수 대 시간"의 플롯이라고 나와 있습니다.
추적 소스 경로에 해당하는 프로브된 데이터를 플로팅하고 있습니다.
/NodeList/*/$ns3::Ipv6L3프로토콜/Tx
추적 경로의 와일드카드에 유의하십시오. 요약하면 이 플롯이 캡처하는 것은 플롯입니다.
Ipv6L3Protocol 개체의 전송 추적 소스에서 관찰된 패킷 바이트 수;
주로 한 방향으로 596바이트 TCP 세그먼트, 다른 방향으로 60바이트 TCP 세그먼트(XNUMX개)
노드 추적 소스가 이 추적 소스와 일치함).
이것은 어떻게 구성되었습니까? 몇 가지 진술을 제공해야 합니다. 먼저 GnuplotHelper
개체를 선언하고 구성해야 합니다.
+ // GnuplotHelper를 사용하여 시간 경과에 따른 패킷 바이트 수를 플로팅합니다.
+ GnuplotHelper 플롯헬퍼;
+
+ // 플롯을 구성합니다. 첫 번째 인수는 파일 이름 접두사입니다.
+ // 생성된 출력 파일용. 두 번째, 세 번째, 네 번째
+ // 인수는 각각 플롯 제목, x축 및 y축 레이블입니다.
+ plotHelper.ConfigurePlot("일곱 번째 패킷 바이트 수",
+ "패킷 바이트 수 대 시간",
+ "시간(초)",
+ "패킷 바이트 수");
지금까지 빈 플롯이 구성되었습니다. 파일 이름 접두사가 첫 번째입니다.
인수, 플롯 제목은 두 번째, x축 레이블은 세 번째, y축 레이블은
네 번째 주장.
다음 단계는 데이터를 구성하는 것이며 여기에서 추적 소스가 연결됩니다.
먼저 프로그램에서 나중에 사용할 수 있도록 몇 가지 변수를 선언했습니다.
+ std::string 프로브 유형;
+ 표준::문자열 추적 경로;
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
여기에서 사용합니다.
+ // 프로브 유형, 추적 소스 경로(구성 네임스페이스에서) 및
+ // 플로팅할 출력 추적 소스("OutputBytes")를 조사합니다. 네 번째 인수
+ // 플롯의 데이터 계열 레이블 이름을 지정합니다. 마지막
+ // 인수는 키를 배치해야 하는 위치를 지정하여 플롯의 형식을 지정합니다.
+ plotHelper.PlotProbe(프로브 유형,
+ 추적 경로,
+ "출력바이트",
+ "패킷 바이트 수",
+ GnuplotAggregator::KEY_BELOW);
처음 두 인수는 프로브 유형의 이름과 추적 소스 경로입니다. 이것들
두 가지가 아마도 이 프레임워크를 사용하여 다른 것을 플롯하려고 할 때 결정하기 가장 어려울 것입니다.
흔적. 여기서 프로브 추적은 Tx 클래스의 추적 소스 Ipv6L3프로토콜. 언제 우리가
이 클래스 구현을 검사합니다(src/인터넷/모델/ipv6-l3-protocol.cc) 다음을 관찰할 수 있습니다.
.AddTraceSource("Tx", "나가는 인터페이스로 IPv6 패킷을 보냅니다.",
MakeTraceSourceAccessor(&Ipv6L3Protocol::m_txTrace))
이 말은 Tx 변수의 이름입니다 m_tx추적, 다음과 같은 선언이 있습니다.
/ **
* \brief TX(전송) 패킷을 추적하기 위한 콜백.
*/
추적 콜백 , Ptr , uint6_t> m_txTrace;
이 특정 추적 소스 서명은 Probe 클래스(무엇
우리는 여기에 필요합니다) 클래스 Ipv6PacketProbe. 파일 보기
src/인터넷/모델/ipv6-패킷-프로브.{h,cc}.
따라서 위의 PlotProbe 문에서 이 문이 추적을 연결하고 있음을 알 수 있습니다.
일치하는 소스(경로 문자열로 식별됨) NS-3 프로브 유형 IPv6PacketProbe. 면
우리는 이 프로브 유형(추적 소스 서명과 일치)을 지원하지 않았으므로 지원하지 않았을 수 있습니다.
이 문장을 사용했습니다(좀 더 복잡한 하위 수준 문장은
설명서에 설명된 대로 사용).
Ipv6PacketProbe는 외부에서 데이터를 추출하는 일부 추적 소스를 자체적으로 내보냅니다.
프로브된 패킷 개체:
유형 ID
Ipv6PacketProbe::GetTypeId()
{
static TypeId tid = TypeId ("ns3::Ipv6PacketProbe")
.SetParent ()
.AddConstructor ()
.AddTraceSource("출력",
"패킷과 이 프로브의 출력 역할을 하는 IPv6 개체 및 인터페이스",
MakeTraceSourceAccessor(&Ipv6PacketProbe::m_output))
.AddTraceSource("출력바이트",
"패킷의 바이트 수",
MakeTraceSourceAccessor(&Ipv6PacketProbe::m_outputBytes))
;
정시 반환;
}
PlotProbe 문의 세 번째 인수는 다음 항목에 관심이 있음을 지정합니다.
이 패킷의 바이트 수. 특히 "OutputBytes" 추적 소스는
Ipv6PacketProbe. 마지막으로 진술의 마지막 두 인수는 플롯 범례를 제공합니다.
이 데이터 계열("패킷 바이트 수") 및 선택적 gnuplot 형식 지정 문
(GnuplotAggregator::KEY_BELOW) 플롯 키가 플롯 아래에 삽입되기를 원합니다.
다른 옵션으로는 NO_KEY, KEY_INSIDE 및 KEY_ABOVE가 있습니다.
지원 더듬다 유형
다음 추적 값은 이 글을 쓰는 시점에서 프로브에서 지원됩니다.
┌─────────────────┬────────────────┬───────────── ────────────────────┐
│TracedValue 유형 │ 프로브 유형 │ 파일 │
├─────────────────┼────────────────┼────────────── ────────────────────┤
│double │ DoubleProbe │ 통계/모델/double-probe.h │
├─────────────────┼────────────────┼────────────── ────────────────────┤
│uint8_t │ Uinteger8Probe │ 통계/모델/uinteger-8-probe.h │
├─────────────────┼────────────────┼────────────── ────────────────────┤
│uint16_t │ Uinteger16Probe │ 통계/모델/uinteger-16-probe.h │
├─────────────────┼────────────────┼────────────── ────────────────────┤
│uint32_t │ Uinteger32Probe │ 통계/모델/uinteger-32-probe.h │
├─────────────────┼────────────────┼────────────── ────────────────────┤
│bool │ BooleanProbe │ 통계/모델/uinteger-16-probe.h │
├─────────────────┼────────────────┼────────────── ────────────────────┤
│ns3::Time │ TimeProbe │ stats/model/time-probe.h │
└─────────────────┴────────────────┴────────────── ────────────────────┘
다음 TraceSource 유형은 이 문서 작성 시점에 Probe에서 지원됩니다.
┌────────────────────┬──────────────────────┬─── ────────────┬───────────────────────────────────── ──────────┐
├────────────────────┼──────────────────────┼─── ────────────┼───────────────────────────────────── ──────────┤
├────────────────────┼──────────────────────┼─── ────────────┼───────────────────────────────────── ──────────┤
├────────────────────┼──────────────────────┼─── ────────────┼───────────────────────────────────── ──────────┤
├────────────────────┼──────────────────────┼─── ────────────┼───────────────────────────────────── ──────────┤
├────────────────────┼──────────────────────┼─── ────────────┼───────────────────────────────────── ──────────┤
└────────────────────┴──────────────────────┴─── ────────────┴───────────────────────────────────── ──────────┘
볼 수 있듯이 소수의 추적 소스만 지원되며 모두 다음을 지향합니다.
패킷 크기(바이트)를 출력합니다. 그러나 대부분의 기본 데이터 유형은
TracedValues로 사용 가능한 이러한 헬퍼를 통해 지원할 수 있습니다.
파일헬퍼
FileHelper 클래스는 이전 GnuplotHelper 예제의 변형일 뿐입니다. 그만큼
예제 프로그램은 다음과 같이 동일한 타임스탬프 데이터의 형식화된 출력을 제공합니다.
시간(초) = 9.312e+00 패킷 바이트 수 = 596
시간(초) = 9.312e+00 패킷 바이트 수 = 564
두 개의 파일이 제공됩니다. 하나는 노드 "0"용이고 다른 하나는 노드 "1"용입니다.
파일 이름. 코드를 하나씩 살펴보겠습니다.
+ // FileHelper를 사용하여 시간 경과에 따른 패킷 바이트 수를 기록합니다.
+ FileHelper fileHelper;
+
+ // 쓸 파일과 출력 데이터의 형식을 구성합니다.
+ fileHelper.ConfigureFile("일곱 번째 패킷 바이트 수",
+ 파일 수집기::포맷됨);
파일 도우미 파일 접두사가 첫 번째 인수이고 형식 지정자가 그 다음입니다. 일부
서식 지정을 위한 다른 옵션에는 SPACE_SEPARATED, COMMA_SEPARATED 및 TAB_SEPARATED가 있습니다.
사용자는 형식 문자열을 사용하여 형식을 변경할 수 있습니다(FORMATTED가 지정된 경우).
다음과 같이:
+
+ // 이 형식화된 출력 파일의 레이블을 설정합니다.
+ fileHelper.Set2dFormat("시간(초) = %.3e\t패킷 바이트 수 = %.0f");
마지막으로 관심 있는 추적 소스를 연결해야 합니다. 다시, probeType 및 tracePath
이 예제의 변수가 사용되며 프로브의 출력 추적 소스 "OutputBytes"는
푹:
+
+ // 프로브 유형, 추적 소스 경로(구성 네임스페이스에서) 및
+ // 쓸 프로브 출력 추적 소스("OutputBytes").
+ fileHelper.WriteProbe(프로브 유형,
+ 추적 경로,
+ "출력바이트");
+
이 추적 소스 지정자의 와일드카드 필드는 두 개의 추적 소스와 일치합니다. 달리
GnuplotHelper 예에서 두 개의 데이터 계열이 동일한 플롯에 중첩되었습니다.
별도의 파일이 디스크에 기록됩니다.
요약
데이터 수집 지원은 ns-3.18의 새로운 기능이며 시계열 제공을 위한 기본 지원입니다.
출력이 추가되었습니다. 위에서 설명한 기본 패턴은
기존 프로브 및 추적 소스의 지원 범위. 다음을 포함한 더 많은 기능
통계 처리는 향후 릴리스에 추가될 예정입니다.
결론
선물
이 문서는 살아 있는 문서입니다. 우리는 그것이 시간이 지남에 따라 성장하기를 희망하고 기대합니다
점점 더 많은 너트와 볼트를 덮기 위해 NS-3.
매뉴얼과 튜토리얼 챕터를 작성하는 것은 우리 모두가 흥분하는 일이 아닙니다.
프로젝트에 매우 중요합니다. 당신이 이 분야의 전문가라면, 제발
에 기여하는 것을 고려하다 NS-3 이 장 중 하나를 제공함으로써; 또는 다른 장
중요하다고 생각할 수 있습니다.
폐회사
NS-3 크고 복잡한 시스템입니다. 당신이 모든 것을 커버하는 것은 불가능합니다.
하나의 작은 자습서에서 알아야 합니다. 더 많은 것을 배우고 싶은 독자들은
다음 추가 문서를 읽으십시오.
· NS-3 조작
· NS-3 모델 라이브러리 문서
· NS-3 Doxygen(API 문서)
· NS-3 위키
- NS-3 개발팀.
onworks.net 서비스를 사용하여 ns-3-tutorial 온라인 사용