GoGPT Best VPN GoSearch

Favicon OnWorks

ns-3-tutorial - Dalam Talian di Awan

Jalankan ns-3-tutorial dalam penyedia pengehosan percuma OnWorks melalui Ubuntu Online, Fedora Online, emulator dalam talian Windows atau emulator dalam talian MAC OS

Ini ialah arahan ns-3-tutorial yang boleh dijalankan dalam penyedia pengehosan percuma OnWorks menggunakan salah satu daripada berbilang stesen kerja dalam talian percuma kami seperti Ubuntu Online, Fedora Online, emulator dalam talian Windows atau emulator dalam talian MAC OS.

JADUAL:

NAMA


ns-3-tutorial - ns-3 Tutorial

Ini adalah ns-3 tutorial. Dokumentasi utama untuk projek ns-3 tersedia dalam lima
borang:

· ns-3 Doksigen: Dokumentasi API awam simulator

· Tutorial (ini dokumen), Manual dan Perpustakaan Model untuk Terkini melepaskan and
pembangunan pokok

· ns-3 wiki

Dokumen ini ditulis dalam reStructuredText khususnya Sphinx dan dikekalkan dalam
dokumen/tutorial direktori kod sumber ns-3.

PENGENALAN


. ns-3 simulator ialah simulator rangkaian acara diskret yang disasarkan terutamanya untuk penyelidikan
dan penggunaan pendidikan. The ns-3 projek, bermula pada tahun 2006, ialah projek sumber terbuka
membangunkan ns-3.

Tujuan tutorial ini adalah untuk memperkenalkan yang baru ns-3 pengguna kepada sistem secara berstruktur
cara. Kadangkala sukar bagi pengguna baharu untuk mengumpul maklumat penting daripada terperinci
manual dan untuk menukar maklumat ini ke dalam simulasi kerja. Dalam tutorial ini, kami
akan membina beberapa contoh simulasi, memperkenalkan dan menerangkan konsep utama dan
ciri semasa kita pergi.

Semasa tutorial dibentangkan, kami akan memperkenalkan sepenuhnya ns-3 dokumentasi dan menyediakan
petunjuk kepada kod sumber bagi mereka yang berminat untuk mendalami cara kerja
sistem.

Beberapa perkara penting perlu diperhatikan pada permulaan:

· ns-3 adalah sumber terbuka, dan projek itu berusaha untuk mengekalkan persekitaran terbuka untuk
penyelidik untuk menyumbang dan berkongsi perisian mereka.

· ns-3 bukan sambungan yang serasi ke belakang daripada ns-2; ia adalah simulator baharu. Kedua-dua
simulator kedua-duanya ditulis dalam C++ tetapi ns-3 ialah simulator baharu yang tidak menyokong
ns-2 API. Beberapa model dari ns-2 telah pun dialihkan dari ns-2 kepada ns-3. Yang
projek akan terus diselenggara ns-2 manakala ns-3 sedang dibina, dan akan belajar
mekanisme peralihan dan integrasi.

Mengenai Kami ns-3
ns-3 telah dibangunkan untuk menyediakan platform simulasi rangkaian yang terbuka dan boleh dikembangkan, untuk
penyelidikan dan pendidikan rangkaian. Secara ringkas, ns-3 menyediakan model bagaimana data paket
rangkaian berfungsi dan melaksanakan, dan menyediakan enjin simulasi untuk dikendalikan oleh pengguna
eksperimen simulasi. Beberapa sebab untuk digunakan ns-3 termasuk untuk melaksanakan kajian yang
adalah lebih sukar atau tidak mungkin dilakukan dengan sistem sebenar, untuk mengkaji tingkah laku sistem
dalam persekitaran yang sangat terkawal, boleh dihasilkan semula, dan untuk mengetahui tentang cara rangkaian berfungsi.
Pengguna akan ambil perhatian bahawa model yang tersedia ditetapkan dalam ns-3 memberi tumpuan kepada pemodelan bagaimana Internet
protokol dan rangkaian berfungsi, tetapi ns-3 tidak terhad kepada sistem Internet; beberapa pengguna
sedang menggunakan ns-3 untuk memodelkan sistem bukan berasaskan Internet.

Banyak alat simulasi wujud untuk kajian simulasi rangkaian. Di bawah adalah beberapa
ciri yang membezakan ns-3 berbeza dengan alatan lain.

· ns-3 direka bentuk sebagai satu set perpustakaan yang boleh digabungkan bersama dan juga dengan yang lain
perpustakaan perisian luaran. Walaupun beberapa platform simulasi menyediakan pengguna dengan a
satu, persekitaran antara muka pengguna grafik bersepadu di mana semua tugas dijalankan
keluar, ns-3 adalah lebih modular dalam hal ini. Beberapa animator luaran dan analisis data
dan alat visualisasi boleh digunakan dengan ns-3. Walau bagaimanapun, pengguna harus mengharapkan untuk bekerja di
baris arahan dan dengan alat pembangunan perisian C++ dan/atau Python.

· ns-3 digunakan terutamanya pada sistem Linux, walaupun sokongan wujud untuk FreeBSD, Cygwin
(untuk Windows), dan sokongan Windows Visual Studio asli sedang dalam proses menjadi
dibangunkan.

· ns-3 bukanlah produk perisian yang disokong secara rasmi oleh mana-mana syarikat. Sokongan untuk ns-3
dilakukan atas dasar usaha terbaik pada senarai mel ns-3-users.

Untuk ns-2 pengguna
Bagi mereka yang biasa dengan ns-2 (alat popular yang mendahului ns-3), yang paling kelihatan secara luaran
berubah apabila berpindah ke ns-3 ialah pilihan bahasa skrip. Program dalam ns-2 adalah
skrip dalam OTcl dan hasil simulasi boleh divisualisasikan menggunakan Animator Rangkaian
nama Tidak mustahil untuk menjalankan simulasi dalam ns-2 semata-mata daripada C++ (iaitu, sebagai main()
program tanpa sebarang OTcl). Selain itu, beberapa komponen ns-2 ditulis dalam C++ dan
yang lain dalam OTcl. Dalam ns-3, simulator ditulis sepenuhnya dalam C++, dengan Python pilihan
pengikatan. Oleh itu, skrip simulasi boleh ditulis dalam C++ atau dalam Python. Animator baharu
dan visualizer tersedia dan dalam pembangunan semasa. Sejak ns-3 menjana pcap
fail jejak paket, utiliti lain boleh digunakan untuk menganalisis jejak juga. Di dalam ini
tutorial, kami mula-mula akan menumpukan pada skrip secara langsung dalam C++ dan mentafsir keputusan
melalui fail surih.

Tetapi terdapat persamaan juga (kedua-duanya, sebagai contoh, berdasarkan objek C++, dan beberapa
kod dari ns-2 telah pun dialihkan ke ns-3). Kami akan cuba menonjolkan perbezaan
antara ns-2 and ns-3 semasa kita meneruskan dalam tutorial ini.

Soalan yang sering kita dengar ialah “Adakah saya masih perlu menggunakan ns-2 atau berpindah ke ns-3?" Di dalam ini
pendapat pengarang, melainkan pengguna diberi hak ns-2 (sama ada berdasarkan sedia ada
keselesaan peribadi dengan dan pengetahuan tentang ns-2, atau berdasarkan model simulasi tertentu yang
hanya terdapat di ns-2), pengguna akan menjadi lebih produktif dengan ns-3 untuk perkara berikut
sebab:

· ns-3 diselenggara secara aktif dengan senarai mel pengguna yang aktif dan responsif, manakala ns-2 is
hanya diselenggara dengan ringan dan belum melihat perkembangan ketara dalam pokok kod utamanya
selama lebih satu dekad.

· ns-3 menyediakan ciri yang tidak tersedia dalam ns-2, seperti pelaksanaan kod pelaksanaan
persekitaran (membenarkan pengguna menjalankan kod pelaksanaan sebenar dalam simulator)

· ns-3 menyediakan tahap asas abstraksi yang lebih rendah berbanding dengan ns-2, membolehkannya diselaraskan
lebih baik dengan cara sistem sebenar disatukan. Beberapa had yang terdapat dalam ns-2 (seperti
menyokong pelbagai jenis antara muka pada nod dengan betul) telah diperbaiki ns-3.

ns-2 mempunyai set modul sumbangan yang lebih pelbagai daripada yang ada ns-3, kerana panjangnya
sejarah. Walau bagaimanapun, ns-3 mempunyai model yang lebih terperinci dalam beberapa bidang penyelidikan yang popular
(termasuk model LTE dan WiFi yang canggih), dan sokongannya terhadap kod pelaksanaan
mengakui spektrum model ketelitian tinggi yang sangat luas. Pengguna mungkin terkejut mengetahuinya
keseluruhan susunan rangkaian Linux boleh dirangkumkan dalam ns-3 nod, menggunakan Direct
Rangka kerja Pelaksanaan Kod (DCE). ns-2 model kadangkala boleh dialihkan ke ns-3, terutamanya
jika ia telah dilaksanakan dalam C++.

Jika ragu-ragu, garis panduan yang baik ialah melihat kedua-dua simulator (serta lain-lain
simulator), dan khususnya model yang tersedia untuk penyelidikan anda, tetapi perlu diingat
bahawa pengalaman anda mungkin lebih baik dalam menggunakan alat yang sedang dibangunkan secara aktif dan
dikekalkan (ns-3).

menyumbang
ns-3 ialah simulator penyelidikan dan pendidikan, oleh dan untuk komuniti penyelidikan. Ia akan
bergantung pada sumbangan berterusan komuniti untuk membangunkan model baharu, nyahpepijat atau
mengekalkan yang sedia ada, dan berkongsi hasil. Terdapat beberapa dasar yang kami harap akan berlaku
menggalakkan orang ramai untuk menyumbang kepada ns-3 seperti yang mereka ada untuk ns-2:

· Pelesenan sumber terbuka berdasarkan keserasian GNU GPLv2

· wiki

· Menyumbang Kod halaman, serupa dengan ns-2Kod Sumbangan yang popular halaman

· Buka pepijat tracker

Kami menyedari bahawa jika anda membaca dokumen ini, menyumbang kembali kepada projek itu adalah
mungkin bukan kebimbangan utama anda pada ketika ini, tetapi kami mahu anda menyedarinya
menyumbang adalah dalam semangat projek dan malah tindakan memberikan kami nota
tentang pengalaman awal anda dengan ns-3 (cth "bahagian tutorial ini tidak jelas..."),
laporan dokumentasi lapuk, dsb. amat dihargai.

tutorial pertubuhan
Tutorial menganggap bahawa pengguna baharu pada mulanya mungkin mengikuti laluan seperti berikut:

· Cuba muat turun dan bina salinan;

· Cuba jalankan beberapa contoh program;

· Lihat output simulasi, dan cuba laraskannya.

Akibatnya, kami telah cuba menyusun tutorial mengikut urutan luas di atas
peristiwa.

SUMBER


. web
Terdapat beberapa sumber penting yang mana mana-mana ns-3 pengguna mesti sedar. Web utama
tapak terletak di http://www.nsnam.org dan menyediakan akses kepada maklumat asas tentang
ns-3 sistem. Dokumentasi terperinci boleh didapati melalui laman web utama di
http://www.nsnam.org/documentation/. Anda juga boleh mencari dokumen yang berkaitan dengan sistem
seni bina daripada halaman ini.

Terdapat Wiki yang melengkapkan yang utama ns-3 laman web yang anda akan dapati di
http://www.nsnam.org/wiki/. Anda akan menemui Soalan Lazim pengguna dan pembangun di sana, serta
panduan penyelesaian masalah, kod sumbangan pihak ketiga, kertas kerja, dsb.

Kod sumber boleh didapati dan dilayari di http://code.nsnam.org/. Di sana anda akan dapati
pokok pembangunan semasa dalam repositori bernama ns-3-dev. Keluaran lepas dan
repositori eksperimen pembangun teras juga boleh didapati di sana.

Mercurial
Sistem perisian yang kompleks memerlukan beberapa cara untuk mengurus organisasi dan perubahan kepada
kod dan dokumentasi asas. Terdapat banyak cara untuk melaksanakan prestasi ini, dan anda boleh
telah mendengar tentang beberapa sistem yang sedang digunakan untuk melakukan ini. Yang Serentak
Sistem Versi (CVS) mungkin yang paling terkenal.

. ns-3 projek menggunakan Mercurial sebagai sistem pengurusan kod sumbernya. Walaupun anda tidak
perlu mengetahui banyak tentang Mercurial untuk melengkapkan tutorial ini, kami mengesyorkan
menjadi biasa dengan Mercurial dan menggunakannya untuk mengakses kod sumber. Mercurial mempunyai a
laman web di http://www.selenic.com/mercurial/, dari mana anda boleh mendapatkan binari atau sumber
keluaran sistem Pengurusan Konfigurasi Perisian (SCM) ini. Selenic (pembangun
of Mercurial) juga menyediakan tutorial di
http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/, dan panduan Mula Pantas di
http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/.

Anda juga boleh mendapatkan maklumat penting tentang menggunakan Mercurial dan ns-3 di utama ns-3 web
tapak.

Waf
Sebaik sahaja anda mempunyai kod sumber dimuat turun ke sistem tempatan anda, anda perlu menyusunnya
sumber untuk menghasilkan program yang boleh digunakan. Sama seperti dalam kes pengurusan kod sumber, ada
terdapat banyak alat yang tersedia untuk melaksanakan fungsi ini. Mungkin yang paling terkenal daripada ini
alatan adalah membuat. Di samping menjadi yang paling terkenal, membuat mungkin yang paling sukar
untuk digunakan dalam sistem yang sangat besar dan sangat boleh dikonfigurasikan. Kerana ini, banyak alternatif
telah dibangunkan. Baru-baru ini sistem ini telah dibangunkan menggunakan Python
bahasa.

Sistem binaan Waf digunakan pada ns-3 projek. Ia adalah salah satu daripada generasi baru
Sistem binaan berasaskan Python. Anda tidak perlu memahami sebarang Python untuk membina
sedia ada ns-3 sistem.

Bagi mereka yang berminat dengan butiran Waf, laman web utama boleh didapati di
http://code.google.com/p/waf/.

pembangunan alam Sekitar
Seperti yang dinyatakan di atas, skrip dalam ns-3 dilakukan dalam C++ atau Python. Kebanyakannya ns-3 API adalah
tersedia dalam Python, tetapi model ditulis dalam C++ dalam kedua-dua kes. A bekerja
pengetahuan tentang C++ dan konsep berorientasikan objek diandaikan dalam dokumen ini. Kami akan ambil
sedikit masa untuk menyemak beberapa konsep yang lebih maju atau mungkin bahasa yang tidak dikenali
ciri, simpulan bahasa dan corak reka bentuk seperti yang muncul. Kami tidak mahu tutorial ini
berubah menjadi tutorial C++, jadi kami mengharapkan arahan asas bahasa itu.
Terdapat bilangan sumber maklumat yang hampir tidak dapat dibayangkan mengenai C++ yang tersedia pada
web atau dalam bentuk cetakan.

Jika anda baru menggunakan C++, anda mungkin ingin mencari buku atau tapak web berasaskan tutorial atau buku masakan
dan bekerja melalui sekurang-kurangnya ciri asas bahasa sebelum meneruskan. Untuk
contohnya, ini tutorial.

. ns-3 sistem menggunakan beberapa komponen "rantai alat" GNU untuk pembangunan. A
rantai alat perisian ialah set alat pengaturcaraan yang tersedia dalam persekitaran yang diberikan. Untuk
semakan pantas tentang perkara yang disertakan dalam rantai alat GNU lihat,
http://en.wikipedia.org/wiki/GNU_toolchain. ns-3 menggunakan gcc, GNU binutils dan gdb.
Walau bagaimanapun, kami tidak menggunakan alat sistem binaan GNU, tidak membuat mahupun autotools. Kami menggunakan Waf
untuk fungsi-fungsi ini.

Biasanya an ns-3 pengarang akan bekerja dalam Linux atau persekitaran seperti Linux. Bagi mereka
berjalan di bawah Windows, terdapat persekitaran yang mensimulasikan persekitaran Linux
pelbagai darjat. The ns-3 projek pada masa lalu (tetapi tidak pada masa ini) disokong
pembangunan dalam persekitaran Cygwin untuk pengguna ini. Lihat http://www.cygwin.com/ khususnya
butiran mengenai muat turun, dan lawati laman web ns-3 wiki untuk maklumat lanjut tentang Cygwin dan
ns-3. MinGW pada masa ini tidak disokong secara rasmi. Alternatif lain untuk Cygwin ialah
pasang persekitaran mesin maya seperti pelayan VMware dan pasang maya Linux
mesin.

Soket Pengaturcaraan
Kami akan menganggap kemudahan asas dengan API Soket Berkeley dalam contoh yang digunakan dalam ini
tutorial. Jika anda baru menggunakan soket, kami mengesyorkan anda menyemak API dan beberapa penggunaan biasa
kes. Untuk gambaran keseluruhan yang baik tentang pengaturcaraan soket TCP/IP, kami mengesyorkan TCP / IP Soket in
C, Donahoo and Calvert.

Terdapat tapak web berkaitan yang menyertakan sumber untuk contoh dalam buku, yang
anda boleh dapatkan di: http://cs.baylor.edu/~donahoo/practical/CSockets/.

Jika anda memahami empat bab pertama buku (atau bagi mereka yang tidak mempunyai akses
kepada salinan buku, pelanggan gema dan pelayan yang ditunjukkan dalam tapak web di atas) anda akan
berada dalam keadaan yang baik untuk memahami tutorial. Terdapat buku serupa di Multicast
Soket, Multicast Soket, Makofske and Almeroth. yang merangkumi bahan yang mungkin anda perlukan
faham jika anda melihat contoh multicast dalam pengedaran.

MENDAPAT BERMULA


Bahagian ini bertujuan untuk membawa pengguna ke keadaan berfungsi bermula dengan mesin yang
mungkin tidak pernah ns-3 dipasang. Ia meliputi platform yang disokong, prasyarat, cara untuk
mendapatkan ns-3, cara untuk membina ns-3, dan cara untuk mengesahkan bina dan jalankan program mudah anda.

Pengenalan
ns-3 dibina sebagai sistem perpustakaan perisian yang berfungsi bersama. Program pengguna boleh
bertulis yang menghubungkan dengan (atau mengimport daripada) perpustakaan ini. Program pengguna ditulis dalam
sama ada bahasa pengaturcaraan C++ atau Python.

ns-3 diedarkan sebagai kod sumber, bermakna sistem sasaran perlu mempunyai a
persekitaran pembangunan perisian untuk membina perpustakaan dahulu, kemudian membina pengguna
program. ns-3 pada dasarnya boleh diedarkan sebagai perpustakaan pra-bina untuk dipilih
sistem, dan pada masa hadapan ia mungkin diedarkan seperti itu, tetapi pada masa ini, ramai pengguna
sebenarnya melakukan kerja mereka dengan menyunting ns-3 sendiri, jadi mempunyai kod sumber untuk membina semula
perpustakaan berguna. Jika seseorang ingin menjalankan kerja membuat pra-bina
perpustakaan dan pakej untuk sistem pengendalian, sila hubungi mel ns-developers
senarai.

Dalam perkara berikut, kami akan melihat dua cara untuk memuat turun dan membina ns-3. Yang pertama adalah
untuk memuat turun dan membina keluaran rasmi dari tapak web utama. Yang kedua ialah mengambil
dan membina salinan pembangunan ns-3. Kami akan melihat kedua-dua contoh sejak alatan
terlibat sedikit berbeza.

Memuat turun ns-3
. ns-3 sistem secara keseluruhan adalah sistem yang agak kompleks dan mempunyai beberapa kebergantungan pada
komponen lain. Bersama-sama dengan sistem yang kemungkinan besar anda akan berurusan setiap hari (the
GNU toolchain, Mercurial, editor teks) anda perlu memastikan bahawa beberapa
perpustakaan tambahan terdapat pada sistem anda sebelum meneruskan. ns-3 menyediakan wiki
halaman yang merangkumi halaman dengan banyak petunjuk dan petua berguna. Satu halaman sedemikian ialah
Halaman "Pemasangan", http://www.nsnam.org/wiki/Installation.

Bahagian "Prasyarat" halaman wiki ini menerangkan pakej yang diperlukan
sokong biasa ns-3 pilihan, dan juga menyediakan arahan yang digunakan untuk memasangnya
varian Linux biasa. Pengguna Cygwin perlu menggunakan pemasang Cygwin (jika anda seorang
Pengguna Cygwin, anda menggunakannya untuk memasang Cygwin).

Anda mungkin ingin mengambil peluang ini untuk meneroka ns-3 wiki sikit sebab memang ada
banyak maklumat di sana.

Dari sudut ini ke hadapan, kami akan menganggap bahawa pembaca bekerja di Linux atau a
Persekitaran emulasi Linux (Linux, Cygwin, dll.) dan mempunyai rantai alat GNU dipasang dan
disahkan bersama dengan prasyarat yang dinyatakan di atas. Kami juga akan menganggapnya
anda telah memasang Mercurial dan Waf dan berjalan pada sistem sasaran.

. ns-3 kod tersedia dalam repositori Mercurial pada pelayan http://code.nsnam.org.
Anda juga boleh memuat turun keluaran tarball di http://www.nsnam.org/release/, atau anda boleh bekerja
dengan repositori menggunakan Mercurial. Kami mengesyorkan menggunakan Mercurial melainkan ada kebaikan
alasan untuk tidak. Lihat penghujung bahagian ini untuk mendapatkan arahan tentang cara mendapatkan bola tar
melepaskan.

Cara paling mudah untuk mula menggunakan repositori Mercurial adalah dengan menggunakan ns-3-allinon
persekitaran. Ini ialah satu set skrip yang menguruskan muat turun dan pembinaan
pelbagai subsistem daripada ns-3 untuk awak. Kami mengesyorkan agar anda memulakan ns-3 bekerja dalam ini
persekitaran.

Satu amalan ialah membuat direktori yang dipanggil ruang kerja dalam direktori rumah seseorang di bawahnya
seseorang boleh menyimpan repositori Mercurial tempatan. Mana-mana nama direktori boleh, tetapi kami akan menganggap
Bahawa ruang kerja digunakan di sini (nota: repo juga boleh digunakan dalam beberapa dokumentasi sebagai
contoh nama direktori).

Memuat turun ns-3 Menggunakan a tarball
Tarball ialah format arkib perisian tertentu di mana berbilang fail digabungkan
bersama-sama dan arkib mungkin dimampatkan. ns-3 keluaran perisian disediakan melalui a
tarball yang boleh dimuat turun. Proses untuk memuat turun ns-3 melalui tarball adalah mudah; anda hanya
perlu memilih keluaran, muat turun dan nyahmampatnya.

Mari kita anggap bahawa anda, sebagai pengguna, ingin membina ns-3 dalam direktori tempatan yang dipanggil
ruang kerja. Jika anda menerima pakai ruang kerja pendekatan direktori, anda boleh mendapatkan salinan keluaran
dengan menaip yang berikut ke dalam shell Linux anda (gantikan nombor versi yang sesuai,
sudah tentu):

$ cd
$ ruang kerja mkdir
$ cd ruang kerja
$ wget http://www.nsnam.org/release/ns-allinone-3.22.tar.bz2
$ tar xjf ns-allinone-3.22.tar.bz2

Jika anda menukar ke dalam direktori ns-allinone-3.22 anda akan melihat beberapa fail:

$ls
pemalar bakar.py ns-3.22 README
build.py netanim-3.105 pybindgen-0.16.0.886 util.py

Anda kini bersedia untuk membina pangkalan ns-3 Pengedaran.

Memuat turun ns-3 Menggunakan Bakar
Bakar ialah alat untuk penyepaduan dan pembinaan yang diedarkan, dibangunkan untuk ns-3 projek.
Bakar boleh digunakan untuk mengambil versi pembangunan ns-3 perisian, dan untuk memuat turun dan
membina sambungan ke pangkalan ns-3 pengedaran, seperti Pelaksanaan Kod Langsung
persekitaran, Rangkaian Simulasi Cradle, keupayaan untuk mencipta pengikatan Python baharu dan lain-lain.

Sejak kebelakangan ini ns-3 keluaran, Bakar telah dimasukkan dalam tarball keluaran. Konfigurasi
fail yang disertakan dalam versi yang dikeluarkan akan membolehkan seseorang memuat turun mana-mana perisian yang ada
semasa pada masa pelepasan. Iaitu, sebagai contoh, versi Bake iaitu
diedarkan dengan ns-3.21 keluaran boleh digunakan untuk mengambil komponen untuk itu ns-3 melepaskan
atau lebih awal, tetapi tidak boleh digunakan untuk mengambil komponen untuk keluaran kemudian (melainkan
bakeconf.xml fail dikemas kini).

Anda juga boleh mendapatkan salinan terbaharu bakar dengan menaip yang berikut ke dalam Linux anda
shell (dengan andaian anda telah memasang Mercurial):

$ cd
$ ruang kerja mkdir
$ cd ruang kerja
$ hg klon http://code.nsnam.org/bake

Apabila arahan hg (Mercurial) dilaksanakan, anda akan melihat sesuatu seperti berikut
dipaparkan,

...
direktori destinasi: bakar
meminta semua perubahan
menambah set perubahan
menambah manifes
menambah perubahan fail
menambah 339 set perubahan dengan 796 perubahan kepada 63 fail
mengemas kini kepada lalai cawangan
45 fail dikemas kini, 0 fail digabungkan, 0 fail dikeluarkan, 0 fail tidak dapat diselesaikan

Selepas arahan klon selesai, anda sepatutnya mempunyai direktori yang dipanggil bakar, isi kandungan
yang sepatutnya kelihatan seperti berikut:

$ls
bakar bakeconf.xml doc generate-binary.py TODO
ujian contoh bake.py

Perhatikan bahawa anda baru sahaja memuat turun beberapa skrip Python dan modul Python yang dipanggil
bakar. Langkah seterusnya ialah menggunakan skrip tersebut untuk memuat turun dan membina fail ns-3
pengedaran pilihan anda.

Terdapat beberapa sasaran konfigurasi yang tersedia:

1. ns-3.22: modul yang sepadan dengan keluaran; ia akan memuat turun komponen yang serupa
kepada tarball pelepas.

2. ns-3-dev: modul yang serupa tetapi menggunakan pokok kod pembangunan

3. ns-allinone-3.22: modul yang merangkumi ciri pilihan lain seperti klik
penghalaan, aliran terbuka untuk ns-3, dan Buaian Simulasi Rangkaian

4. ns-3-allinon: serupa dengan versi modul allinone yang dikeluarkan, tetapi untuk
kod pembangunan.

Gambar pembangunan semasa (belum dikeluarkan) daripada ns-3 boleh didapati di
http://code.nsnam.org/ns-3-dev/. Pembangun cuba menyimpan repositori ini
keadaan yang konsisten dan berfungsi tetapi mereka berada dalam kawasan pembangunan dengan kod yang belum dikeluarkan
hadir, jadi anda mungkin ingin mempertimbangkan untuk kekal dengan keluaran rasmi jika anda tidak perlu
ciri yang baru diperkenalkan.

Anda boleh mencari versi terbaharu kod sama ada melalui pemeriksaan senarai repositori
atau dengan pergi ke "ns-3 Keluaran" halaman web dan mengklik pada pautan keluaran terkini.
Kami akan meneruskan dalam contoh tutorial ini dengan ns-3.22.

Kami kini akan menggunakan alat bakar untuk menarik ke bawah pelbagai kepingan ns-3 anda akan menjadi
menggunakan. Mula-mula, kami akan menyebut satu perkataan tentang menjalankan membakar.

bakar berfungsi dengan memuat turun pakej sumber ke dalam direktori sumber dan memasang
perpustakaan ke dalam direktori binaan. bakar boleh dijalankan dengan merujuk binari, tetapi jika satu
memilih untuk menjalankan bakar dari luar direktori yang dimuat turun ke dalamnya, adalah dinasihatkan
untuk meletakkan bakar ke laluan anda, seperti berikut (contoh cangkang bash Linux). Pertama, berubah
ke dalam direktori 'bake', dan kemudian tetapkan pembolehubah persekitaran berikut

$ eksport BAKE_HOME=`pwd`
$ eksport PATH=$PATH:$BAKE_HOME:$BAKE_HOME/build/bin
$ eksport PYTHONPATH=$PYTHONPATH:$BAKE_HOME:$BAKE_HOME/build/lib

Ini akan meletakkan program bake.py ke dalam laluan shell, dan akan membenarkan program lain
cari boleh laku dan perpustakaan yang dicipta oleh bakar. Walaupun beberapa kes penggunaan bakar tidak
memerlukan penetapan PATH dan PYTHONPATH seperti di atas, binaan penuh ns-3-allinone (dengan
pakej pilihan) biasanya dilakukan.

Langkah ke dalam direktori ruang kerja dan taip yang berikut ke dalam shell anda:

$ ./bake.py konfigurasi -e ns-3.22

Seterusnya, kami akan meminta bakar untuk menyemak sama ada kami mempunyai alatan yang mencukupi untuk memuat turun pelbagai komponen.
Jenis:

$ ./bake.py semak

Anda sepatutnya melihat sesuatu seperti berikut,

> Python - OK
> Pengkompil GNU C++ - OK
> Mercurial - OK
> CVS - OK
> GIT - OK
> Bazar - OK
> Alat tar - OK
> Nyahzip alat - OK
> Alat Unrar - tiada
> Utiliti pemampatan data 7z - OK
> Utiliti pemampatan data XZ - OK
> Buat - OK
> cMake - OK
> alat tampal - OK
> alat autoreconf - OK

> Laluan yang dicari untuk alatan: /usr/lib64/qt-3.3/bin /usr/lib64/ccache
/ usr / local / bin / bin / usr / bin / usr / tempatan / sbin / usr / sbin / sbin
/home/tomh/bin bin

Khususnya, alat muat turun seperti Mercurial, CVS, GIT dan Bazaar adalah prinsipal kami
kebimbangan pada ketika ini, kerana ia membenarkan kami mengambil kod tersebut. Sila pasang tiada
alat pada peringkat ini, dengan cara biasa untuk sistem anda (jika anda boleh), atau hubungi
pentadbir sistem anda seperti yang diperlukan untuk memasang alat ini.

Seterusnya, cuba muat turun perisian:

$ ./bake.py muat turun

harus menghasilkan sesuatu seperti:

>> Mencari pygoocanvas pergantungan sistem - OK
>> Mencari pergantungan sistem python-dev - OK
>> Mencari pygraphviz pergantungan sistem - OK
>> Memuat turun pybindgen-0.16.0.886 - OK
>> Mencari pergantungan sistem g++ - OK
>> Mencari pergantungan sistem qt4 - OK
>> Memuat turun netanim-3.105 - OK
>> Memuat turun ns-3.22 - OK

Di atas menunjukkan bahawa tiga sumber telah dimuat turun. Semak sumber direktori
sekarang dan taip ls; seseorang harus melihat:

$ls
netanim-3.105 ns-3.22 pybindgen-0.16.0.886

Anda kini bersedia untuk membina ns-3 Pengedaran.

Bangunan ns-3
Bangunan bersama build.py
Apabila bekerja dari tarball yang dilepaskan, kali pertama anda membina ns-3 projek anda boleh
membina menggunakan program kemudahan yang terdapat dalam allinone direktori. Program ini dipanggil
build.py. Program ini akan membuat projek dikonfigurasikan untuk anda dengan cara yang paling biasa
cara yang berguna. Walau bagaimanapun, sila ambil perhatian bahawa konfigurasi yang lebih maju dan berfungsi dengan ns-3 akan
biasanya melibatkan penggunaan asli ns-3 membina sistem, Waf, yang akan diperkenalkan kemudian dalam ini
tutorial.

Jika anda memuat turun menggunakan tarball anda sepatutnya mempunyai direktori yang dipanggil sesuatu seperti
ns-allinone-3.22 di bawah anda ~/ruang kerja direktori. Taip yang berikut:

$ ./build.py --enable-examples --enable-tests

Kerana kami bekerja dengan contoh dan ujian dalam tutorial ini, dan kerana mereka tidak
dibina secara lalai dalam ns-3, hujah untuk build.py memberitahunya untuk membinanya untuk kita. The
program juga lalai untuk membina semua modul yang tersedia. Nanti boleh bina ns-3
tanpa contoh dan ujian, atau hapuskan modul yang tidak diperlukan untuk kerja anda,
jika anda ingin.

Anda akan melihat banyak mesej output pengkompil biasa dipaparkan semasa skrip binaan dibina
pelbagai bahagian yang anda muat turun. Akhirnya anda akan melihat perkara berikut:

Waf: Meninggalkan direktori `/path/to/workspace/ns-allinone-3.22/ns-3.22/build'
'bina' berjaya diselesaikan (6m25.032s)

Modul dibina:
aplikasi antena aodv
kedai konfigurasi bangunan jambatan
core csma csma-layout
tenaga dsdv dsr
fd-net-device-flow-monitor internet
lr-wpan lte mesh
mobiliti mpi netanim (tiada Python)
rangkaian nix-vector-routing olsr
perambatan susun atur titik ke titik
statistik spektrum sixlowpan
ujian tap-bridge (tiada Python) topologi-baca
gelombang peranti-jaring maya uan
wifi wimax

Modul tidak dibina (lihat tutorial ns-3 untuk penjelasan):
brite klik aliran terbuka
visualizer

Meninggalkan direktori `./ns-3.22'

Mengenai bahagian tentang modul yang tidak dibina:

Modul tidak dibina (lihat tutorial ns-3 untuk penjelasan):
brite klik aliran terbuka
visualizer

Ini hanya bermakna bahawa beberapa ns-3 modul yang mempunyai kebergantungan pada perpustakaan luar mungkin tidak
telah dibina, atau konfigurasi secara khusus meminta untuk tidak membinanya. Ia berlaku
tidak bermakna bahawa simulator tidak berjaya membina atau ia akan memberikan yang salah
keputusan untuk modul yang disenaraikan sebagai dibina.

Bangunan bersama bakar
Jika anda menggunakan bakar di atas untuk mengambil kod sumber daripada repositori projek, anda boleh meneruskan
menggunakannya untuk membina ns-3. jenis

$ ./bake.py bina

dan anda sepatutnya melihat sesuatu seperti:

>> Membina pybindgen-0.16.0.886 - OK
>> Bangunan netanim-3.105 - OK
>> Bangunan ns-3.22 - OK

Petunjuk: anda boleh Juga melaksanakan kedua-dua langkah-langkah, muat turun and membina by memanggil 'bake.py kerahkan'.

Jika berlaku kegagalan, sila lihat apa yang diberitahu oleh arahan berikut
awak; ia mungkin memberi petunjuk tentang pergantungan yang hilang:

$ ./bake.py rancangan

Ini akan menyenaraikan pelbagai kebergantungan pakej yang anda cuba bina.

Bangunan bersama Waf
Sehingga tahap ini, kami telah menggunakan sama ada build.py skrip, atau bakar alat, untuk mendapatkan
bermula dengan membina ns-3. Alat ini berguna untuk membina ns-3 dan menyokong
perpustakaan, dan mereka memanggil ke ns-3 direktori untuk memanggil alat bina Waf untuk melakukan
bangunan sebenar. Kebanyakan pengguna dengan cepat beralih kepada menggunakan Waf secara langsung untuk mengkonfigurasi dan
membina ns-3. Jadi, untuk meneruskan, sila tukar direktori kerja anda kepada ns-3 direktori
yang anda telah bina pada mulanya.

Ia tidak diperlukan sepenuhnya pada ketika ini, tetapi ia akan bernilai untuk mengambil lencongan sedikit
dan lihat cara membuat perubahan pada konfigurasi projek. Mungkin yang paling banyak
perubahan konfigurasi berguna yang boleh anda lakukan ialah membina versi yang dioptimumkan
kod. Secara lalai anda telah mengkonfigurasi projek anda untuk membina versi nyahpepijat. Mari kita beritahu
projek untuk membuat binaan yang dioptimumkan. Untuk menerangkan kepada Waf bahawa ia harus dioptimumkan
binaan yang merangkumi contoh dan ujian, anda perlu melaksanakan perkara berikut
arahan:

$ ./waf bersih
$ ./waf --build-profile=optimized --enable-examples --enable-tests configure

Ini menyebabkan Waf keluar dari direktori tempatan (yang disediakan sebagai kemudahan untuk anda).
Perintah pertama untuk membersihkan binaan sebelumnya biasanya tidak diperlukan tetapi
adalah amalan yang baik (tetapi lihat Membina Profil, di bawah); ia akan mengalih keluar yang dibina sebelum ini
perpustakaan dan fail objek yang terdapat dalam direktori membina /. Apabila projek dikonfigurasikan semula
dan sistem binaan menyemak pelbagai kebergantungan, anda harus melihat output yang kelihatan
serupa seperti berikut:

Tetapan atas kepada : .
Menetap untuk : membina
Menyemak 'gcc' (c compiler): /usr/bin/gcc
Menyemak versi cc : 4.2.1
Menyemak 'g++' (pengkompil c++): /usr/bin/g++
Memeriksa rangsangan termasuk : 1_46_1
Menyemak libs rangsangan : ok
Menyemak pautan rangsangan : ok
Menyemak lokasi klik : tidak dijumpai
Menyemak program pkg-config : /sw/bin/pkg-config
Menyemak 'gtk+-2.0' >= 2.12 : ya
Menyemak 'libxml-2.0' >= 2.7 : ya
Menyemak jenis uint128_t : tidak dijumpai
Menyemak jenis __uint128_t : ya
Menyemak pelaksanaan ketepatan tinggi : integer 128-bit (lalai)
Menyemak pengepala stdint.h : ya
Menyemak inttypes.h pengepala : ya
Menyemak pengepala sys/inttypes.h : tidak ditemui
Menyemak pengepala sys/types.h : ya
Menyemak pengepala sys/stat.h : ya
Menyemak tajuk dirent.h : ya
Menyemak pengepala stdlib.h : ya
Menyemak isyarat pengepala.h : ya
Menyemak tajuk pthread.h : ya
Menyemak pengepala stdint.h : ya
Menyemak inttypes.h pengepala : ya
Menyemak pengepala sys/inttypes.h : tidak ditemui
Menyemak perpustakaan rt : tidak dijumpai
Menyemak pengepala netpacket/packet.h : tidak ditemui
Menyemak pengepala sys/ioctl.h : ya
Menyemak jaring pengepala/if.h : tidak ditemui
Menyemak header net/ethernet.h : ya
Menyemak pengepala linux/if_tun.h : tidak dijumpai
Menyemak pengepala netpacket/packet.h : tidak ditemui
Menyemak lokasi NSC : tidak dijumpai
Menyemak 'mpic++' : ya
Menyemak 'sqlite3' : ya
Menyemak pengepala linux/if_tun.h : tidak dijumpai
Menyemak program sudo : /usr/bin/sudo
Menyemak program valgrind : /sw/bin/valgrind
Menyemak 'gsl' : ya
Menyemak bendera kompilasi -Wno-error=deprecated-d... sokongan : ok
Menyemak bendera kompilasi -Wno-error=deprecated-d... sokongan : ok
Menyemak kompilasi bendera -fstrict-aliasing... sokongan : ok
Menyemak kompilasi bendera -fstrict-aliasing... sokongan : ok
Menyemak bendera kompilasi -Wstrict-aliasing... sokongan : ok
Menyemak bendera kompilasi -Wstrict-aliasing... sokongan : ok
Menyemak program doxygen : /usr/local/bin/doxygen
---- Ringkasan ciri NS-3 pilihan:
Bina profil : nyahpepijat
Bina direktori : build
Python Bindings : didayakan
Integrasi BRITE : tidak didayakan (BRITE tidak didayakan (lihat pilihan --dengan-brite))
Integrasi Klik NS-3 : tidak didayakan (nsclick tidak didayakan (lihat pilihan --dengan-nsclick))
GtkConfigStore : didayakan
XmlIo : didayakan
Primitif Threading : didayakan
Simulator Masa Nyata : didayakan (librt tidak tersedia)
Peranti Bersih Ditiru : didayakan ( termasuk tidak dikesan)
Deskriptor fail NetDevice : didayakan
Ketik FdNetDevice : tidak didayakan (memerlukan linux/if_tun.h)
Emulasi FdNetDevice : tidak didayakan (memerlukan netpacket/packet.h)
PlanetLab FdNetDevice : tidak didayakan (sistem pengendalian PlanetLab tidak dikesan (lihat pilihan --force-planetlab))
Rangkaian Simulasi Cradle : tidak didayakan (NSC tidak ditemui (lihat pilihan --dengan-nsc))
Sokongan MPI : didayakan
Integrasi OpenFlow NS-3 : tidak didayakan (Pustaka rangsangan yang diperlukan tidak ditemui, tiada: sistem, isyarat, sistem fail)
Output data statistik SQlite : didayakan
Ketik Jambatan : tidak didayakan ( termasuk tidak dikesan)
Visualizer PyViz : didayakan
Gunakan sudo untuk menetapkan suid bit : not enabled (option --enable-sudo not selected)
Ujian binaan : didayakan
Contoh binaan : didayakan
Perpustakaan Saintifik GNU (GSL) : didayakan
'configure' berjaya diselesaikan (1.944s)

Perhatikan bahagian terakhir output di atas. Beberapa ns-3 pilihan tidak didayakan secara lalai atau
memerlukan sokongan daripada sistem asas untuk berfungsi dengan baik. Sebagai contoh, untuk membolehkan
XmlTo, perpustakaan libxml-2.0 mesti ditemui pada sistem. Jika perpustakaan ini tidak
didapati, yang sepadan ns-3 ciri tidak akan didayakan dan mesej akan didayakan
dipaparkan. Ambil perhatian lebih lanjut bahawa terdapat ciri untuk menggunakan program ini sudo untuk menetapkan suid
sedikit program tertentu. Ini tidak didayakan secara lalai dan oleh itu ciri ini dilaporkan
sebagai "tidak didayakan."

Sekarang teruskan dan beralih kembali kepada binaan nyahpepijat yang merangkumi contoh dan ujian.

$ ./waf bersih
$ ./waf --build-profile=debug --enable-examples --enable-tests configure

Sistem binaan kini dikonfigurasikan dan anda boleh membina versi nyahpepijat bagi ns-3
program dengan hanya menaip

$ ./waf

Okey, maaf, saya menyuruh awak membinanya ns-3 sebahagian daripada sistem dua kali, tetapi kini anda tahu bagaimana untuk
tukar konfigurasi dan bina kod yang dioptimumkan.

Skrip build.py yang dibincangkan di atas juga menyokong --dayakan-contoh and membolehkan-ujian
hujah, tetapi secara umum, tidak secara langsung menyokong pilihan waf lain; sebagai contoh, ini
tidak akan berfungsi:

$ ./build.py --disable-python

akan menghasilkan

build.py: ralat: tiada pilihan sedemikian: --disable-python

Bagaimanapun, pengendali khas -- boleh digunakan untuk menghantar pilihan tambahan melalui waf, jadi
bukannya di atas, yang berikut akan berfungsi:

$ ./build.py -- --disable-python

kerana ia menjana arahan asas ./waff mengkonfigurasi --disable-python.

Berikut adalah beberapa lagi petua pengenalan tentang Waf.

Konfigurasi vs Membina
Sesetengah arahan Waf hanya bermakna semasa fasa konfigurasi dan beberapa arahan adalah
sah dalam fasa binaan. Contohnya, jika anda ingin menggunakan ciri emulasi
ns-3, anda mungkin mahu mendayakan tetapan bit suid menggunakan sudo seperti yang diterangkan di atas. ini
ternyata menjadi arahan masa konfigurasi, jadi anda boleh mengkonfigurasi semula menggunakan
arahan berikut yang juga termasuk contoh dan ujian.

$ ./waf configure --enable-sudo --enable-examples --enable-tests

Jika anda melakukan ini, Waf akan menjalankan sudo untuk menukar program pencipta soket
kod emulasi untuk dijalankan sebagai root.

Terdapat banyak pilihan konfigurasi dan masa binaan lain yang tersedia dalam Waf. Untuk meneroka ini
pilihan, taip:

$ ./waf --help

Kami akan menggunakan beberapa arahan yang berkaitan dengan ujian dalam bahagian seterusnya.

Membina Profil
Kami telah melihat cara anda boleh mengkonfigurasi Waf untuk debug or dioptimumkan membina:

$ ./waf --build-profile=debug

Terdapat juga profil binaan perantaraan, melepaskan. -d adalah sinonim untuk
--bina-profil.

Secara lalai Waf meletakkan artifak binaan dalam membina direktori. Anda boleh menentukan a
direktori output yang berbeza dengan --keluar pilihan, misalnya

$ ./waf configure --out=foo

Menggabungkan ini dengan profil binaan membolehkan anda bertukar antara pilihan kompilasi yang berbeza
dengan cara yang bersih:

$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf binaan
...
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf binaan
...

Ini membolehkan anda bekerja dengan berbilang binaan dan bukannya sentiasa menulis ganti yang terakhir
membina. Apabila anda menukar, Waf hanya akan menyusun apa yang perlu, bukannya menyusun semula
segala-galanya.

Apabila anda menukar profil binaan seperti ini, anda perlu berhati-hati untuk memberikan perkara yang sama
parameter konfigurasi setiap kali. Ia mungkin mudah untuk menentukan beberapa persekitaran
pembolehubah untuk membantu anda mengelakkan kesilapan:

$ export NS3CONFIG="--enable-examples --enable-tests"
$ eksport NS3DEBUG="--build-profile=debug --out=build/debug"
$ eksport NS3OPT=="--build-profile=optimized --out=build/optimized"

$ ./waf konfigurasikan $NS3CONFIG $NS3DEBUG
$ ./waf binaan
...
$ ./waf konfigurasikan $NS3CONFIG $NS3OPT
$ ./waf binaan

Penyusun
Dalam contoh di atas, Waf menggunakan pengkompil GCC C++, g ++, untuk bangunan ns-3. Walau bagaimanapun,
adalah mungkin untuk menukar pengkompil C++ yang digunakan oleh Waf dengan mentakrifkan CXX persekitaran
pembolehubah. Contohnya, untuk menggunakan pengkompil Clang C++, denting++,

$ CXX="clang++" ./waf configure
$ ./waf binaan

Seseorang juga boleh menyediakan Waf untuk melakukan penyusunan teragih distcc dengan cara yang sama:

$ CXX="distcc g++" ./waf konfigurasi
$ ./waf binaan

Maklumat lanjut mengenai distcc dan kompilasi yang diedarkan boleh didapati di atasnya projek halaman di bawah
Bahagian dokumentasi.

memasang
Waf boleh digunakan untuk memasang perpustakaan di pelbagai tempat pada sistem. lalai
lokasi di mana perpustakaan dan boleh laku dibina adalah dalam membina direktori, dan kerana
Waf tahu lokasi perpustakaan dan boleh laku ini, ia tidak perlu dipasang
perpustakaan di tempat lain.

Jika pengguna memilih untuk memasang perkara di luar direktori binaan, pengguna boleh mengeluarkan
./waff memasang perintah. Secara lalai, awalan untuk pemasangan ialah / usr / setempat, Jadi ./waff
memasang akan memasang program ke dalam / usr / local / bin, perpustakaan ke / Local / lib / usr, dan
tajuk ke dalam / usr / tempatan / termasuk. Keistimewaan pengguna super biasanya diperlukan untuk dipasang
awalan lalai, jadi arahan biasa ialah sudo ./waff memasang. Apabila berlari
program dengan Waf, Waf akan lebih suka menggunakan perpustakaan kongsi dalam direktori binaan,
kemudian akan mencari perpustakaan dalam laluan perpustakaan yang dikonfigurasikan dalam persekitaran setempat. Jadi
apabila memasang perpustakaan pada sistem, adalah amalan yang baik untuk memeriksa sama ada yang dimaksudkan
perpustakaan sedang digunakan.

Pengguna boleh memilih untuk memasang pada awalan yang berbeza dengan meneruskan --awalan pilihan di
mengkonfigurasi masa, seperti:

./waf configure --prefix=/opt/local

Jika kemudian selepas binaan pengguna mengeluarkan ./waff memasang perintah, awalan /opt/local
akan digunakan.

. ./waff membersihkan arahan harus digunakan sebelum mengkonfigurasi semula projek jika Waf akan
digunakan untuk memasang sesuatu pada awalan yang berbeza.

Ringkasnya, tidak perlu memanggil ./waff memasang untuk digunakan ns-3. Kebanyakan pengguna tidak akan
memerlukan arahan ini kerana Waf akan mengambil perpustakaan semasa daripada membina direktori,
tetapi sesetengah pengguna mungkin mendapati ia berguna jika kes penggunaan mereka melibatkan kerja dengan program di luar
daripada ns-3 direktori.

satu Waf
Hanya terdapat satu skrip Waf, di peringkat atas ns-3 pokok sumber. Semasa anda bekerja, anda
mungkin mendapati diri anda menghabiskan banyak masa calar/, atau jauh ke dalam src/..., dan perlu
ajak Waf. Anda hanya boleh ingat di mana anda berada, dan panggil Waf seperti ini:

$ ../../../waf ...

tetapi itu membosankan, dan terdedah kepada ralat, dan terdapat penyelesaian yang lebih baik.

Jika anda mempunyai kenyang ns-3 repositori permata kecil ini adalah permulaan:

$ cd $(hg root) && ./waf ...

Lebih baik lagi adalah untuk menentukan ini sebagai fungsi shell:

$ function waff { cd $(hg root) && ./waf $* ; }

$ binaan waff

Jika anda hanya mempunyai tarball, pembolehubah persekitaran boleh membantu:

$ eksport NS3DIR="$PWD"
$ function waff { cd $NS3DIR && ./waf $* ; }

$ cd calar
$ binaan waff

Ia mungkin menggoda dalam direktori modul untuk menambah perkara yang remeh WAF skrip sepanjang baris
exec ../../waf. Tolong jangan. Ia mengelirukan kepada pendatang baru, dan apabila ia dilakukan dengan buruk
membawa kepada ralat binaan yang halus. Penyelesaian di atas adalah cara untuk pergi.

Ujian ns-3
Anda boleh menjalankan ujian unit bagi ns-3 pengedaran dengan menjalankan ./test.py -c teras
skrip:

$ ./test.py -c teras

Ujian ini dijalankan secara selari oleh Waf. Anda akhirnya akan melihat laporan yang mengatakan itu

92 daripada 92 ujian lulus (92 lulus, 0 gagal, 0 ranap, 0 ralat valgrind)

Ini adalah mesej penting.

Anda juga akan melihat output ringkasan daripada Waf dan pelari ujian yang melaksanakan setiap ujian,
yang sebenarnya akan kelihatan seperti:

Waf: Memasuki direktori `/path/to/workspace/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/path/to/workspace/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (1.799s)

Modul dibina:
jambatan aplikasi aodv
klik teras config-store
csma csma-layout dsdv
pemantau aliran tenaga emu
internet lte mesh
mobiliti mpi netanim
rangkaian nix-vector-routing ns3tcp
aliran terbuka ns3wifi olsr
perambatan susun atur titik ke titik
spektrum stats-jambatan
alat ujian templat
topologi-baca uan peranti-jaring-maya
visualizer wifi wimax

LULUS: TestSuite ns3-wifi-gangguan
LULUS: Histogram TestSuite

...

LULUS: objek TestSuite
LULUS: TestSuite penjana nombor rawak
92 daripada 92 ujian lulus (92 lulus, 0 gagal, 0 ranap, 0 ralat valgrind)

Perintah ini biasanya dijalankan oleh pengguna untuk mengesahkan dengan cepat bahawa a ns-3 pengedaran mempunyai
dibina dengan betul. (Perhatikan susunan LULUS: ... garis boleh berbeza-beza, tidak mengapa. Apa yang
penting ialah garis ringkasan pada akhir melaporkan bahawa semua ujian lulus; tiada yang gagal atau
terhempas.)

Berlari a skrip
Kami biasanya menjalankan skrip di bawah kawalan Waf. Ini membolehkan sistem binaan memastikan
bahawa laluan perpustakaan kongsi ditetapkan dengan betul dan perpustakaan tersedia di
masa larian. Untuk menjalankan program, hanya gunakan --lari pilihan dalam Waf. Mari kita jalankan ns-3
setara dengan program hello world yang ada di mana-mana dengan menaip yang berikut:

$ ./waf --run hello-simulator

Waf menyemak terlebih dahulu untuk memastikan program dibina dengan betul dan melaksanakan binaan jika
diperlukan. Waf kemudian melaksanakan program, yang menghasilkan output berikut.

Hello Simulator

tahniah! Anda kini pengguna ns-3!

Servis do I do if I tidak lihat yang pengeluaran?

Jika anda melihat mesej Waf yang menunjukkan bahawa binaan telah berjaya disiapkan, tetapi tidak
lihat output "Hello Simulator", kemungkinan besar anda telah menukar mod binaan anda kepada
dioptimumkan dalam Bangunan bersama Waf bahagian, tetapi telah terlepas perubahan kembali ke debug mod.
Semua output konsol yang digunakan dalam tutorial ini menggunakan khas ns-3 komponen pembalakan yang
berguna untuk mencetak mesej pengguna ke konsol. Output daripada komponen ini ialah
dilumpuhkan secara automatik apabila anda menyusun kod yang dioptimumkan -- ia "dioptimumkan". Jika awak
tidak melihat output "Hello Simulator", taip yang berikut:

$ ./waf configure --build-profile=debug --enable-examples --enable-tests

untuk memberitahu Waf membina versi nyahpepijat ns-3 program yang merangkumi contoh
dan ujian. Anda masih mesti membina versi nyahpepijat sebenar kod dengan menaip

$ ./waf

Sekarang, jika anda menjalankan hello-simulator program, anda harus melihat output yang diharapkan.

Program Argumen
Untuk menyuapkan hujah baris arahan kepada an ns-3 program menggunakan corak ini:

$ ./waf --run --command-template="%s "

Gantikan nama program anda untuk , dan hujah untuk . Yang
--templat arahan hujah kepada Waf pada asasnya adalah resipi untuk membina yang sebenar
baris arahan Waf harus gunakan untuk melaksanakan program. Waf menyemak bahawa binaan itu adalah
selesai, tetapkan laluan perpustakaan kongsi, kemudian panggil boleh laku menggunakan yang disediakan
templat baris arahan, memasukkan nama program untuk %s pemegang tempat. (Saya akui ini
agak janggal, tetapi begitulah keadaannya. Patch dialu-alukan!)

Satu lagi contoh yang sangat berguna ialah menjalankan suite ujian dengan sendirinya. Mari kita andaikan bahawa a
mytest suite ujian wujud (tidak ada). Di atas, kami menggunakan ./test.py skrip untuk menjalankan keseluruhan
banyak ujian secara selari, dengan berulang kali menggunakan program ujian sebenar, pelari ujian.
Untuk menyeru pelari ujian secara langsung untuk satu ujian:

$ ./waf --run test-runner --command-template="%s --suite=mytest --verbose"

Ini menyampaikan hujah kepada pelari ujian program. Sejak mytest tidak wujud, an
mesej ralat akan dihasilkan. Untuk mencetak yang tersedia pelari ujian pilihan yang berikut:

$ ./waf --run test-runner --command-template="%s --help"

Debugging
Untuk berlari ns-3 atur cara di bawah kawalan utiliti lain, seperti penyahpepijat (contohnya gdb)
atau penyemak ingatan (contohnya valgrind), anda menggunakan yang serupa --command-template="..." bentuk.

Sebagai contoh, untuk menjalankan anda ns-3 program hello-simulator dengan hujah-hujah di bawah
gdb penyahpepijat:

$ ./waf --run=hello-simulator --command-template="gdb %s --args "

Perhatikan bahawa ns-3 nama program pergi dengan --lari hujah, dan utiliti kawalan
(di sini gdb) ialah token pertama dalam --templat arahan hujah. The --args memberitahu gdb
bahawa baki baris arahan tergolong dalam program "inferior". (Beberapa gdb's
tidak faham --args ciri. Dalam kes ini, tinggalkan hujah program daripada
--templat arahan, dan gunakan gdb arahan menetapkan args.)

Kita boleh menggabungkan resipi ini dan yang sebelumnya untuk menjalankan ujian di bawah penyahpepijat:

$ ./waf --run test-runner --command-template="gdb %s --args --suite=mytest --verbose"

Kerja Direktori
Waf perlu lari dari lokasinya di bahagian atas ns-3 pokok. Ini menjadi kerja
direktori tempat fail output akan ditulis. Tetapi bagaimana jika anda mahu menyimpannya
yang ns-3 pokok sumber? Menggunakan --cwd hujah:

$ ./waf --cwd=...

Ia mungkin lebih mudah untuk memulakan dengan direktori kerja anda di mana anda mahu output
fail, dalam hal ini sedikit arahan boleh membantu:

$fungsi waff {
CWD="$PWD"
cd $NS3DIR >/dev/null
./waf --cwd="$CWD" $*
cd - >/dev/null
}

Hiasan versi sebelumnya ini menyimpan direktori kerja semasa, cdke
direktori Waf, kemudian mengarahkan Waf menukar direktori kerja kembali kepada yang disimpan
direktori kerja semasa sebelum menjalankan program.

KONSEP MAKLUMAT UMUM


Perkara pertama yang perlu kita lakukan sebelum benar-benar mula melihat atau menulis ns-3 kod adalah untuk
menerangkan beberapa konsep teras dan abstraksi dalam sistem. Kebanyakan perkara ini mungkin muncul
telus jelas kepada sesetengah orang, tetapi kami mengesyorkan meluangkan masa untuk membaca ini
bahagian hanya untuk memastikan anda bermula di atas asas yang kukuh.

Utama Abstraksi
Dalam bahagian ini, kami akan menyemak beberapa istilah yang biasa digunakan dalam rangkaian, tetapi mempunyai a
makna khusus dalam ns-3.

nod
Dalam jargon Internet, peranti pengkomputeran yang menyambung ke rangkaian dipanggil a tuan rumah or
kadang-kadang an akhir sistem. kerana ns-3 ialah rangkaian simulator, bukan secara khusus
Internet simulator, kami sengaja tidak menggunakan istilah hos kerana ia adalah rapat
berkaitan dengan Internet dan protokolnya. Sebaliknya, kami juga menggunakan istilah yang lebih generik
digunakan oleh simulator lain yang berasal dari Teori Graf --- yang nod.

In ns-3 abstraksi peranti pengkomputeran asas dipanggil nod. Abstraksi ini adalah
diwakili dalam C++ oleh kelas nod. Yang nod kelas menyediakan kaedah untuk mengurus
perwakilan peranti pengkomputeran dalam simulasi.

Anda harus memikirkan a nod sebagai komputer yang mana anda akan menambah kefungsian. Seorang menambah
perkara seperti aplikasi, susunan protokol dan kad persisian dengan yang berkaitan
pemacu untuk membolehkan komputer melakukan kerja yang berguna. Kami menggunakan model asas yang sama dalam ns-3.

Permohonan
Biasanya, perisian komputer dibahagikan kepada dua kelas yang luas. sistem perisian menganjurkan
pelbagai sumber komputer seperti ingatan, kitaran pemproses, cakera, rangkaian, dsb.,
mengikut beberapa model pengkomputeran. Perisian sistem biasanya tidak menggunakan sumber tersebut
untuk menyelesaikan tugasan yang memberi manfaat secara langsung kepada pengguna. Seorang pengguna biasanya akan menjalankan a permohonan
yang memperoleh dan menggunakan sumber yang dikawal oleh perisian sistem untuk mencapai beberapa
Matlamat.

Selalunya, garis pemisahan antara sistem dan perisian aplikasi dibuat di
perubahan tahap keistimewaan yang berlaku dalam perangkap sistem pengendalian. Dalam ns-3 tidak ada yang sebenar
konsep sistem pengendalian dan terutamanya tiada konsep tahap keistimewaan atau panggilan sistem.
Kami, bagaimanapun, mempunyai idea permohonan. Sama seperti aplikasi perisian berjalan
komputer untuk melaksanakan tugas dalam "dunia nyata", ns-3 aplikasi dijalankan ns-3 Nod kepada
simulasi memandu dalam dunia simulasi.

In ns-3 abstraksi asas untuk atur cara pengguna yang menjana beberapa aktiviti untuk menjadi
simulasi adalah aplikasi. Abstraksi ini diwakili dalam C++ oleh kelas
Permohonan. Yang Permohonan kelas menyediakan kaedah untuk menguruskan perwakilan
versi aplikasi peringkat pengguna kami dalam simulasi. Pemaju dijangka
mengkhususkan Permohonan kelas dalam pengertian pengaturcaraan berorientasikan objek untuk mencipta baharu
aplikasi. Dalam tutorial ini, kami akan menggunakan pengkhususan kelas Permohonan dipanggil
UdpEchoClientApplication and UdpEchoServerApplication. Seperti yang anda jangkakan, ini
aplikasi mengarang set aplikasi klien/pelayan yang digunakan untuk menjana dan menggemakan simulasi
paket rangkaian

Saluran
Di dunia nyata, seseorang boleh menyambungkan komputer ke rangkaian. Selalunya media mengenainya
aliran data dalam rangkaian ini dipanggil saluran. Apabila anda menyambungkan kabel Ethernet anda ke
palam di dinding, anda sedang menyambungkan komputer anda ke komunikasi Ethernet
saluran. Dalam dunia simulasi ns-3, satu menghubungkan a nod kepada objek yang mewakili a
saluran komunikasi. Di sini abstraksi subrangkaian komunikasi asas dipanggil
saluran dan diwakili dalam C++ oleh kelas Saluran.

. Saluran kelas menyediakan kaedah untuk mengurus objek subrangkaian komunikasi dan
menyambungkan nod kepada mereka. Saluran mungkin juga dikhususkan oleh pembangun dalam objek
rasa pengaturcaraan berorientasikan. A Saluran pengkhususan boleh memodelkan sesuatu yang semudah a
wayar. Yang khusus Saluran juga boleh memodelkan perkara yang rumit seperti Ethernet yang besar
suis, atau ruang tiga dimensi yang penuh dengan halangan dalam kes rangkaian wayarles.

Kami akan menggunakan versi khusus bagi Saluran dipanggil CsmaChannel, PointToPointChannel
and WifiChannel dalam tutorial ini. The CsmaChannel, sebagai contoh, memodelkan versi a
subrangkaian komunikasi yang melaksanakan a pembawa rasa pelbagai mengakses komunikasi
sederhana. Ini memberi kita fungsi seperti Ethernet.

Bersih Peranti
Dulu, jika anda ingin menyambungkan komputer ke rangkaian, anda perlu melakukannya
beli jenis kabel rangkaian dan peranti perkakasan tertentu yang dipanggil (dalam terminologi PC) a
periferal kad yang perlu dipasang dalam komputer anda. Jika kad persisian
melaksanakan beberapa fungsi rangkaian, ia dipanggil Kad Antara Muka Rangkaian, atau NIC.
Hari ini kebanyakan komputer datang dengan perkakasan antara muka rangkaian terbina dalam dan pengguna tidak melihat
blok bangunan ini.

NIC tidak akan berfungsi tanpa pemacu perisian untuk mengawal perkakasan. Dalam Unix (atau
Linux), sekeping perkakasan persisian dikelaskan sebagai a peranti. Peranti dikawal
menggunakan peranti pemandu, dan peranti rangkaian (NIC) dikawal menggunakan rangkaian peranti
pemandu secara kolektif dikenali sebagai bersih peranti. Dalam Unix dan Linux anda merujuk kepada jaring ini
peranti dengan nama seperti eth0.

In ns-3 yang bersih peranti abstraksi meliputi kedua-dua pemacu perisian dan simulasi
perkakasan. Peranti bersih "dipasang" dalam a nod untuk membolehkan nod kepada
berkomunikasi dengan orang lain Nod dalam simulasi melalui Saluran. Sama seperti dalam komputer sebenar,
a nod mungkin disambungkan kepada lebih daripada satu Saluran melalui berbilang NetDevices.

Abstraksi peranti bersih diwakili dalam C++ oleh kelas NetDevice. Yang NetDevice
kelas menyediakan kaedah untuk menguruskan sambungan ke nod and Saluran objek; dan mungkin
dikhususkan oleh pembangun dalam pengertian pengaturcaraan berorientasikan objek. Kami akan menggunakan
beberapa versi khusus bagi NetDevice dipanggil CsmaNetDevice, PointToPointNetDevice,
and WifiNetDevice dalam tutorial ini. Sama seperti NIC Ethernet direka untuk berfungsi dengan
Rangkaian Ethernet, yang CsmaNetDevice direka untuk bekerja dengan a CsmaChannel; yang
PointToPointNetDevice direka untuk bekerja dengan a PointToPointChannel dan WifiNetNevice
direka untuk bekerja dengan a WifiChannel.

Topologi Pembantu
Dalam rangkaian sebenar, anda akan menemui komputer hos dengan NIC tambahan (atau terbina dalam). Dalam ns-3 we
akan mengatakan bahawa anda akan mendapati Nod dengan dilampirkan NetDevices. Dalam rangkaian simulasi yang besar
anda perlu mengatur banyak sambungan antara Nod, NetDevices and Saluran.

Sejak bersambung NetDevices kepada Nod, NetDevices kepada Saluran, memberikan alamat IP,
dan lain-lain, adalah tugas biasa dalam ns-3, kami menyediakan apa yang kami panggil topologi pembantu untuk membuat ini
semudah mungkin. Sebagai contoh, ia mungkin memerlukan banyak yang berbeza ns-3 operasi teras kepada
buat NetDevice, tambah alamat MAC, pasang peranti bersih itu pada a nod, konfigurasikan
timbunan protokol nod, dan kemudian sambungkan NetDevice kepada Saluran. Malah lebih banyak operasi
akan diperlukan untuk menyambungkan berbilang peranti ke saluran berbilang titik dan kemudian untuk menyambung
rangkaian individu bersama-sama menjadi internetworks. Kami menyediakan objek pembantu topologi itu
menggabungkan banyak operasi yang berbeza itu menjadi model yang mudah digunakan untuk kemudahan anda.

A pertama ns-3 skrip
Jika anda memuat turun sistem seperti yang dicadangkan di atas, anda akan mempunyai keluaran ns-3 dalam
direktori dipanggil repo di bawah direktori rumah anda. Tukar ke direktori keluaran itu, dan
anda harus mencari struktur direktori seperti berikut:

AUTHORS contoh scratch utils waf.bat*
bindings LESEN src utils.py waf-tools
bina ns3 test.py* utils.pyc wscript
CHANGES.html README testpy-output VERSION wutils.py
doc RELEASE_NOTES testpy.supp waf* wutils.pyc

Tukar kepada contoh/tutorial direktori. Anda sepatutnya melihat fail bernama pertama.cc terletak
di sana. Ini ialah skrip yang akan mencipta pautan titik-ke-titik yang mudah antara dua nod
dan bergema satu paket di antara nod. Mari kita lihat barisan skrip oleh itu
talian, jadi teruskan dan buka pertama.cc dalam editor kegemaran anda.

Plat dandang
Baris pertama dalam fail ialah baris mod emacs. Ini memberitahu emacs tentang pemformatan
konvensyen (gaya pengekodan) yang kami gunakan dalam kod sumber kami.

/* -*- Mod:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

Ini selalu menjadi subjek yang agak kontroversial, jadi sebaiknya kita menyingkirkannya
segera. The ns-3 projek, seperti kebanyakan projek besar, telah menggunakan gaya pengekodan untuk
yang mesti dipatuhi oleh semua kod yang disumbangkan. Jika anda ingin menyumbang kod anda kepada
projek, anda akhirnya perlu mematuhi ns-3 standard pengekodan seperti yang diterangkan dalam
fail doc/codingstd.txt atau ditunjukkan pada halaman web projek di sini.

Kami mengesyorkan agar anda membiasakan diri dengan rupa dan rasa ns-3 kod dan pakai
standard ini setiap kali anda bekerja dengan kod kami. Semua pasukan pembangunan dan
penyumbang telah berbuat demikian dengan pelbagai rungutan. Baris mod emacs di atas
menjadikannya lebih mudah untuk mendapatkan pemformatan yang betul jika anda menggunakan editor emacs.

. ns-3 simulator dilesenkan menggunakan Lesen Awam Am GNU. Anda akan melihat
perundangan GNU yang sesuai di kepala setiap fail dalam ns-3 pengedaran. Selalunya awak
akan melihat notis hak cipta untuk salah satu institusi yang terlibat dalam ns-3 projek di atas
teks GPL dan pengarang yang disenaraikan di bawah.

/*
* Program ini adalah perisian percuma; anda boleh mengedarkannya semula dan/atau mengubah suai
* ia di bawah terma GNU General Public License versi 2 sebagai
* diterbitkan oleh Yayasan Perisian Percuma;
*
*Program ini diedarkan dengan harapan ianya bermanfaat,
* tetapi TANPA SEBARANG WARANTI; tanpa waranti tersirat pun
* KEBOLEHPERDAGANGAN atau KESESUAIAN UNTUK TUJUAN TERTENTU. Lihat
* Lesen Awam Am GNU untuk butiran lanjut.
*
* Anda sepatutnya menerima salinan Lesen Awam Am GNU
* bersama dengan program ini; jika tidak, tulis kepada Perisian Percuma
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

Modul Termasuk
Kod yang betul bermula dengan beberapa pernyataan termasuk.

#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"

Untuk membantu pengguna skrip peringkat tinggi kami menangani sejumlah besar fail sertakan yang ada
sistem, kami kumpulan termasuk mengikut modul yang agak besar. Kami menyediakan satu
sertakan fail yang akan memuatkan semua fail sertakan yang digunakan dalam setiap modul secara rekursif.
Daripada perlu mencari dengan tepat tajuk yang anda perlukan, dan mungkin perlu mendapatkan a
bilangan tanggungan yang betul, kami memberi anda keupayaan untuk memuatkan sekumpulan fail secara besar-besaran
kebutiran. Ini bukan pendekatan yang paling berkesan tetapi ia pastinya membuat penulisan
skrip lebih mudah.

Setiap satu daripada ns-3 masukkan fail diletakkan dalam direktori yang dipanggil ns3 (di bawah binaan
direktori) semasa proses binaan untuk membantu mengelakkan perlanggaran nama fail. The
ns3/modul-teras.h fail sepadan dengan modul ns-3 yang anda akan dapati dalam direktori
src/teras dalam pengedaran keluaran anda yang dimuat turun. Jika anda menyenaraikan direktori ini, anda akan
cari sebilangan besar fail pengepala. Apabila anda membuat binaan, Waf akan meletakkan pengepala awam
fail dalam ns3 direktori di bawah yang sesuai bina/nyahpepijat or bina/dioptimumkan direktori
bergantung pada konfigurasi anda. Waf juga akan menjana modul termasuk secara automatik
fail untuk memuatkan semua fail pengepala awam.

Memandangkan anda, sudah tentu, mengikuti tutorial ini secara agama, anda sudah pun melakukannya
a

$ ./waf -d debug --enable-examples --enable-tests configure

untuk mengkonfigurasi projek untuk melaksanakan binaan nyahpepijat yang merangkumi contoh dan ujian.
Anda juga akan melakukan a

$ ./waf

untuk membina projek. Jadi sekarang jika anda melihat dalam direktori ../../build/debug/ns3 anda akan
cari empat modul termasuk fail yang ditunjukkan di atas. Anda boleh lihat pada kandungan
fail ini dan mendapati bahawa mereka termasuk semua orang awam termasuk fail dalam mereka
modul masing-masing.

Ns3 Ruang nama
Baris seterusnya dalam pertama.cc skrip ialah pengisytiharan ruang nama.

menggunakan ruang nama ns3;

. ns-3 projek dilaksanakan dalam ruang nama C++ yang dipanggil ns3. Kumpulan ini semua
ns-3-pengisytiharan berkaitan dalam skop di luar ruang nama global, yang kami harap akan membantu
dengan integrasi dengan kod lain. C++ menggunakan kenyataan memperkenalkan ns-3 ruang nama
ke kawasan perisytiharan semasa (global). Ini adalah cara yang mewah untuk mengatakan bahawa selepas
pengisytiharan ini, anda tidak perlu menaip ns3:: pengendali resolusi skop sebelum semua
yang ns-3 kod untuk menggunakannya. Jika anda tidak biasa dengan ruang nama, sila rujuk
hampir mana-mana tutorial C++ dan bandingkan ns3 ruang nama dan penggunaan di sini dengan contoh
std ruang nama dan menggunakan ruang nama std; kenyataan yang sering anda temui dalam perbincangan
of cout dan aliran.

Pembalakan
Baris skrip seterusnya adalah seperti berikut,

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Kami akan menggunakan kenyataan ini sebagai tempat yang sesuai untuk bercakap tentang dokumentasi Doxygen kami
sistem. Jika anda melihat laman web projek, ns-3 projek, anda akan menemui pautan ke
"Dokumentasi" dalam bar navigasi. Jika anda memilih pautan ini, anda akan dibawa ke kami
halaman dokumentasi. Terdapat pautan ke "Keluaran Terkini" yang akan membawa anda ke
dokumentasi untuk keluaran stabil terkini ns-3. Jika anda memilih "API
Dokumentasi", anda akan dibawa ke ns-3 halaman dokumentasi API.

Di sepanjang bahagian kiri, anda akan menemui perwakilan grafik struktur
dokumentasi. Tempat yang baik untuk bermula ialah NS-3 Modul "buku" dalam ns-3 navigasi
pokok. Jika anda mengembangkan Modul anda akan melihat senarai ns-3 dokumentasi modul. The
konsep modul di sini mengikat terus ke dalam modul termasuk fail yang dibincangkan di atas. The
ns-3 subsistem pembalakan dibincangkan dalam C + + Konstruk Digunakan by Semua Modul bahagian, jadi
teruskan dan kembangkan nod dokumentasi itu. Sekarang, kembangkan Debugging buku dan kemudian
pilih Pembalakan .

Anda kini sepatutnya melihat dokumentasi Doxygen untuk modul Pengelogan. Di dalam
senarai #tentukan's di bahagian atas halaman anda akan melihat entri untuk
NS_LOG_COMPONENT_DEFINE. Sebelum melompat masuk, mungkin lebih baik untuk mencari
"Penerangan Terperinci" modul pengelogan untuk merasakan operasi keseluruhan. awak
boleh sama ada tatal ke bawah atau pilih pautan "Lagi..." di bawah rajah kerjasama untuk dilakukan
ini.

Sebaik sahaja anda mempunyai idea umum tentang perkara yang sedang berlaku, teruskan dan lihat yang khusus
NS_LOG_COMPONENT_DEFINE dokumentasi. Saya tidak akan menduplikasi dokumentasi di sini, tetapi untuk
ringkaskan, baris ini mengisytiharkan komponen pembalakan dipanggil FirstScriptContoh yang membenarkan
anda untuk mendayakan dan melumpuhkan pengelogan mesej konsol dengan merujuk kepada nama.

Utama fungsi
Baris skrip seterusnya yang anda akan dapati ialah,

int
utama (int argc, char *argv[])
{

Ini hanyalah pengisytiharan fungsi utama program anda (skrip). Sama seperti dalam
mana-mana program C++, anda perlu menentukan fungsi utama yang akan menjadi fungsi pertama yang dijalankan.
Tiada apa yang istimewa di sini. awak ns-3 skrip hanyalah program C++.

Baris seterusnya menetapkan resolusi masa kepada satu nanosaat, yang kebetulan menjadi lalai
nilai:

Masa::SetResolution (Masa::NS);

Resolusi ialah nilai masa terkecil yang boleh diwakili (serta nilai masa terkecil
perbezaan yang boleh diwakili antara dua nilai masa). Anda boleh menukar resolusi dengan tepat
sekali. Mekanisme yang membolehkan fleksibiliti ini agak kehausan memori, jadi sekali
resolusi telah ditetapkan secara eksplisit kami melepaskan memori, menghalang kemas kini selanjutnya.
(Jika anda tidak menetapkan resolusi secara eksplisit, ia akan lalai kepada satu nanosaat, dan
ingatan akan dikeluarkan apabila simulasi bermula.)

Dua baris skrip seterusnya digunakan untuk membolehkan dua komponen pengelogan yang dibina
ke dalam aplikasi Echo Client dan Echo Server:

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);

Jika anda telah membaca dokumentasi komponen Pembalakan, anda akan melihatnya di sana
ialah beberapa tahap verbositi/perincian pengelogan yang boleh anda dayakan pada setiap komponen.
Kedua-dua baris kod ini membolehkan pengelogan nyahpepijat pada peringkat INFO untuk pelanggan gema dan
pelayan. Ini akan menyebabkan aplikasi mencetak mesej semasa paket dihantar
dan diterima semasa simulasi.

Sekarang kita akan terus kepada perniagaan mencipta topologi dan menjalankan simulasi.
Kami menggunakan objek pembantu topologi untuk membuat kerja ini semudah mungkin.

Topologi Pembantu
NodeContainer
Dua baris kod seterusnya dalam skrip kami sebenarnya akan mencipta ns-3 nod objek yang
akan mewakili komputer dalam simulasi.

NodeContainer nod;
nod.Buat (2);

Mari cari dokumentasi untuk NodeContainer kelas sebelum kita meneruskan. Cara lain
untuk masuk ke dalam dokumentasi untuk kelas tertentu adalah melalui kelas tab dalam Doxygen
muka surat. Jika anda masih mempunyai Doxygen, hanya tatal ke atas halaman dan
pilih kelas tab. Anda sepatutnya melihat set tab baharu muncul, salah satunya ialah Kelas
senarai. Di bawah tab itu anda akan melihat senarai semua ns-3 kelas. Tatal ke bawah,
mencari ns3::NodeContainer. Apabila anda menemui kelas, teruskan dan pilih kelas itu untuk pergi
dokumentasi untuk kelas.

Anda mungkin masih ingat bahawa salah satu abstraksi utama kami ialah nod. Ini mewakili komputer
yang mana kami akan menambah perkara seperti susunan protokol, aplikasi dan persisian
kad. The NodeContainer pembantu topologi menyediakan cara yang mudah untuk mencipta, mengurus dan
akses mana-mana nod objek yang kami cipta untuk menjalankan simulasi. Baris pertama di atas
hanya mengisytiharkan NodeContainer yang kami panggil nod. Baris kedua memanggil Buat
kaedah pada nod objek dan meminta bekas untuk mencipta dua nod. Seperti yang diterangkan dalam
Doxygen, bekas itu memanggil ke dalam ns-3 sistem yang sesuai untuk mencipta dua nod
objek dan menyimpan penunjuk kepada objek tersebut secara dalaman.

Nod seperti yang terdapat dalam skrip tidak melakukan apa-apa. Langkah seterusnya dalam membina a
topologi adalah untuk menyambungkan nod kita bersama-sama ke dalam rangkaian. Bentuk rangkaian yang paling mudah kita
sokongan ialah satu pautan titik-ke-titik antara dua nod. Kami akan membina salah satu daripadanya
pautan di sini.

PointToPointHelper
Kami sedang membina pautan titik ke titik, dan, dalam corak yang akan menjadi agak
biasa kepada anda, kami menggunakan objek pembantu topologi untuk melakukan kerja peringkat rendah yang diperlukan untuk meletakkan
pautan bersama. Ingat bahawa dua abstraksi utama kami ialah NetDevice dan juga
Saluran. Di dunia nyata, istilah ini sepadan secara kasar dengan kad persisian dan
kabel rangkaian. Biasanya kedua-dua perkara ini diikat rapat dan satu tidak boleh
mengharapkan untuk bertukar, contohnya, peranti Ethernet dan saluran wayarles. Topologi Kami
Pembantu mengikuti gandingan intim ini dan oleh itu anda akan menggunakan single
PointToPointHelper untuk mengkonfigurasi dan menyambung ns-3 PointToPointNetDevice and
PointToPointChannel objek dalam skrip ini.

Tiga baris seterusnya dalam skrip ialah,

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

Baris pertama,

PointToPointHelper pointToPoint;

instantiat a PointToPointHelper objek pada timbunan. Dari perspektif peringkat tinggi
baris seterusnya,

pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));

memberitahu PointToPointHelper objek untuk menggunakan nilai "5Mbps" (lima megabit sesaat) sebagai
"DataRate" apabila ia mencipta a PointToPointNetDevice objek.

Daripada perspektif yang lebih terperinci, rentetan "DataRate" sepadan dengan apa yang kami panggil an
atribut daripada PointToPointNetDevice. Jika anda melihat Doxygen untuk kelas
ns3::PointToPointNetDevice dan cari dokumentasi untuk GetTypeId kaedah, anda akan
cari senarai Atribut ditakrifkan untuk peranti. Antaranya ialah "DataRate"
atribut. Paling boleh dilihat oleh pengguna ns-3 objek mempunyai senarai serupa Atribut. Kami menggunakan ini
mekanisme untuk mengkonfigurasi simulasi dengan mudah tanpa menyusun semula seperti yang anda akan lihat dalam a
bahagian berikut.

Sama seperti "DataRate" pada PointToPointNetDevice anda akan menemui "Keterlambatan" atribut
dikaitkan dengan PointToPointChannel. Barisan akhir,

pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

memberitahu PointToPointHelper untuk menggunakan nilai "2ms" (dua milisaat) sebagai nilai
kelewatan penghantaran setiap saluran titik ke titik yang dibuatnya kemudiannya.

NetDeviceContainer
Pada ketika ini dalam skrip, kami mempunyai a NodeContainer yang mengandungi dua nod. Kami mempunyai a
PointToPointHelper yang siap dan sedia untuk dibuat PointToPointNetDevices dan wayar
PointToPointChannel objek di antara mereka. Sama seperti kami menggunakan NodeContainer topologi
objek pembantu untuk mencipta Nod untuk simulasi kami, kami akan bertanya PointToPointHelper
untuk melakukan kerja yang terlibat dalam mencipta, mengkonfigurasi dan memasang peranti kami untuk kami. Kami
perlu mempunyai senarai semua objek NetDevice yang dicipta, jadi kami menggunakan a
NetDeviceContainer untuk memegangnya sama seperti kami menggunakan NodeContainer untuk memegang nod yang kami
dicipta. Dua baris kod berikut,

Peranti NetDeviceContainer;
peranti = pointToPoint.Install (nod);

akan selesai mengkonfigurasi peranti dan saluran. Baris pertama mengisytiharkan peranti
bekas yang disebutkan di atas dan yang kedua melakukan pengangkatan berat. The memasang kaedah
yang PointToPointHelper mengambil a NodeContainer sebagai parameter. Secara dalaman, a
NetDeviceContainer dicipta. Untuk setiap nod dalam NodeContainer (mesti ada betul-betul
dua untuk pautan titik ke titik) a PointToPointNetDevice dicipta dan disimpan dalam peranti
bekas. A PointToPointChannel dicipta dan keduanya PointToPointNetDevices adalah
dilampirkan. Apabila objek dicipta oleh PointToPointHelper, yang Atribut sebelum ini
set dalam pembantu digunakan untuk memulakan yang sepadan Atribut dalam yang dicipta
objek.

Selepas melaksanakan pointToPoint.Install (nod) panggilan kita akan mempunyai dua nod, setiap satu dengan
peranti bersih titik-ke-titik yang dipasang dan satu saluran titik-ke-titik di antaranya.
Kedua-dua peranti akan dikonfigurasikan untuk menghantar data pada lima megabit sesaat sepanjang
saluran yang mempunyai kelewatan penghantaran dua milisaat.

InternetStackHelper
Kami kini mempunyai nod dan peranti yang dikonfigurasikan, tetapi kami tidak mempunyai sebarang susunan protokol yang dipasang
pada nod kami. Dua baris kod seterusnya akan mengurusnya.

Timbunan InternetStackHelper;
stack.Install (nod);

. InternetStackHelper ialah pembantu topologi iaitu kepada tindanan internet apa yang
PointToPointHelper adalah untuk peranti bersih point-to-point. The memasang kaedah mengambil a
NodeContainer sebagai parameter. Apabila ia dilaksanakan, ia akan memasang Tindanan Internet
(TCP, UDP, IP, dll.) pada setiap nod dalam bekas nod.

Ipv4AddressHelper
Seterusnya kita perlu mengaitkan peranti pada nod kita dengan alamat IP. Kami menyediakan a
pembantu topologi untuk menguruskan peruntukan alamat IP. Satu-satunya API yang boleh dilihat oleh pengguna ialah
tetapkan alamat IP asas dan topeng rangkaian untuk digunakan semasa melaksanakan alamat sebenar
peruntukan (yang dilakukan pada tahap yang lebih rendah di dalam pembantu).

Dua baris kod seterusnya dalam skrip contoh kami, pertama.cc,

Alamat Ipv4AddressHelper;
address.SetBase ("10.1.1.0", "255.255.255.0");

mengisytiharkan objek pembantu alamat dan memberitahunya bahawa ia harus mula memperuntukkan alamat IP
daripada rangkaian 10.1.1.0 menggunakan mask 255.255.255.0 untuk mentakrifkan bit yang boleh diperuntukkan. Oleh
lalai alamat yang diperuntukkan akan bermula pada satu dan meningkat secara monoton, jadi yang pertama
alamat yang diperuntukkan daripada pangkalan ini ialah 10.1.1.1, diikuti dengan 10.1.1.2, dsb.
tahap ns-3 sistem sebenarnya mengingati semua alamat IP yang diperuntukkan dan akan menjana a
ralat maut jika anda secara tidak sengaja menyebabkan alamat yang sama dijana dua kali (iaitu a
sangat sukar untuk menyahpepijat ralat, dengan cara itu).

Baris kod seterusnya,

Antara muka Ipv4InterfaceContainer = alamat.Assign (peranti);

melaksanakan tugasan alamat sebenar. Dalam ns-3 kami membuat perkaitan antara IP
alamat dan peranti menggunakan Ipv4Interface objek. Sama seperti kita kadang-kadang memerlukan senarai
peranti bersih yang dicipta oleh pembantu untuk rujukan masa hadapan yang kadangkala memerlukan senarai
Ipv4Interface objek. The Ipv4InterfaceContainer menyediakan fungsi ini.

Kini kami mempunyai rangkaian titik ke titik yang dibina, dengan tindanan dipasang dan alamat IP
ditugaskan. Apa yang kita perlukan pada ketika ini ialah aplikasi untuk menjana trafik.

Aplikasi
Satu lagi abstraksi teras sistem ns-3 ialah Permohonan. Dalam kes ini,
skrip kami menggunakan dua pengkhususan teras ns-3 kelas Permohonan dipanggil
UdpEchoServerApplication and UdpEchoClientApplication. Sama seperti yang kita ada pada sebelumnya
penjelasan, kami menggunakan objek pembantu untuk membantu mengkonfigurasi dan mengurus objek asas.
Di sini, kami gunakan UdpEchoServerHelper and UdpEchoClientHelper objek untuk memudahkan hidup kita.

UdpEchoServerHelper
Baris kod berikut dalam skrip contoh kami, pertama.cc, digunakan untuk menyediakan gema UDP
aplikasi pelayan pada salah satu nod yang telah kami buat sebelum ini.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Saat (1.0));
serverApps.Stop (Saat (10.0));

Baris pertama kod dalam coretan di atas mengisytiharkan UdpEchoServerHelper. Seperti biasa,
ini bukan aplikasi itu sendiri, ia adalah objek yang digunakan untuk membantu kami mencipta yang sebenar
aplikasi. Salah satu konvensyen kami adalah untuk menempatkan dikehendaki Atribut dalam penolong
pembina. Dalam kes ini, pembantu tidak boleh melakukan apa-apa yang berguna melainkan ia disediakan
nombor port yang pelanggan juga tahu. Daripada hanya memilih satu dan berharap
semuanya berjaya, kami memerlukan nombor port sebagai parameter kepada pembina. The
pembina, sebaliknya, hanya melakukan a SetAttribute dengan nilai lulus. Jika anda mahu, anda
boleh menetapkan "Port" atribut kepada nilai lain kemudian menggunakan SetAttribute.

Sama seperti banyak objek penolong lain, the UdpEchoServerHelper objek mempunyai memasang
kaedah. Perlaksanaan kaedah ini yang sebenarnya menyebabkan gema asas
aplikasi pelayan untuk dijadikan instantiated dan dilampirkan pada nod. Menariknya, memasang
kaedah mengambil a NodeContainer sebagai parameter sama seperti yang lain memasang kaedah yang kita ada
dilihat. Inilah sebenarnya yang diluluskan kepada kaedah walaupun ia tidak kelihatan begitu masuk
kes ini. Terdapat C++ tersirat Penukaran di tempat kerja di sini yang mengambil hasil daripada
nod.Dapatkan (1) (yang mengembalikan penunjuk pintar kepada objek nod --- Ptr) dan menggunakannya
dalam pembina untuk yang tidak dinamakan NodeContainer yang kemudiannya diserahkan kepada memasang. Jika anda adalah
pernah mengalami kerugian untuk mencari tandatangan kaedah tertentu dalam kod C++ yang menyusun dan berjalan
baiklah, cari jenis penukaran tersirat ini.

Kita sekarang nampak itu echoServer.Install akan memasang a UdpEchoServerApplication pada
nod ditemui pada indeks nombor satu daripada NodeContainer kami pernah menguruskan nod kami. memasang
akan mengembalikan bekas yang menyimpan penunjuk kepada semua aplikasi (satu dalam kes ini
sejak kita lulus a NodeContainer mengandungi satu nod) yang dicipta oleh pembantu.

Aplikasi memerlukan masa untuk "memulakan" menjana trafik dan mungkin mengambil masa pilihan untuk
"berhenti". Kami menyediakan kedua-duanya. Masa ini ditetapkan menggunakan ApplicationContainer kaedah
Start and Berhenti. Kaedah ini mengambil Masa parameter. Dalam kes ini, kami menggunakan a jelas C + +
urutan penukaran untuk mengambil C++ double 1.0 dan menukarnya kepada a ns-3 Masa objek menggunakan
a Seconds pelakon. Harap maklum bahawa peraturan penukaran mungkin dikawal oleh pengarang model,
dan C++ mempunyai peraturannya sendiri, jadi anda tidak boleh selalu menganggap bahawa parameter akan menjadi gembira
ditukar untuk anda. Dua baris,

serverApps.Start (Saat (1.0));
serverApps.Stop (Saat (10.0));

akan menyebabkan aplikasi pelayan gema Start (dayakan dirinya) pada satu saat ke dalam
simulasi dan kepada Berhenti (lumpuhkan sendiri) pada sepuluh saat ke dalam simulasi. Menurut kuasa
hakikat bahawa kami telah mengisytiharkan acara simulasi (acara berhenti aplikasi) sebagai
dilaksanakan pada sepuluh saat, simulasi akan berlangsung at kurangnya sepuluh saat.

UdpEchoClientHelper
Aplikasi klien gema disediakan dalam kaedah yang hampir sama dengan kaedah untuk
pelayan. Terdapat asas UdpEchoClientApplication yang diuruskan oleh seorang
UdpEchoClientHelper.

UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Selang", TimeValue (Saat (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Secons (2.0));
clientApps.Stop (Saat (10.0));

Untuk pelanggan gema, bagaimanapun, kita perlu menetapkan lima yang berbeza Atribut. Dua yang pertama
Atribut ditetapkan semasa pembinaan UdpEchoClientHelper. Kami lulus parameter
yang digunakan (secara dalaman kepada pembantu) untuk menetapkan "RemoteAddress" dan "RemotePort"
Atribut selaras dengan konvensyen kami untuk membuat diperlukan Atribut parameter dalam
pembantu pembina.

Ingat bahawa kami menggunakan satu Ipv4InterfaceContainer untuk menjejaki alamat IP yang kami
ditetapkan pada peranti kami. Antara muka sifar dalam antara muka bekas akan
sepadan dengan alamat IP nod sifar dalam nod bekas. Yang pertama
antara muka dalam antara muka bekas sepadan dengan alamat IP nod pertama masuk
yang nod bekas. Jadi, dalam baris pertama kod (dari atas), kami mencipta kod
pembantu dan memberitahunya supaya tetapkan alamat jauh klien menjadi alamat IP
diberikan kepada nod di mana pelayan berada. Kami juga memberitahunya untuk mengatur penghantaran
paket ke port sembilan.

"MaxPackets" atribut memberitahu pelanggan bilangan maksimum paket yang kami benarkan
hantar semasa simulasi. "Selang" atribut memberitahu pelanggan berapa lama untuk menunggu
antara paket dan "PacketSize" atribut memberitahu pelanggan betapa besar paketnya
muatan sepatutnya. Dengan gabungan khusus ini Atribut, kami memberitahu
pelanggan untuk menghantar satu paket 1024-bait.

Sama seperti dalam kes pelayan gema, kami memberitahu klien gema untuk Start and Berhenti, Tetapi
di sini kita mulakan klien satu saat selepas pelayan didayakan (pada dua saat ke dalam
simulasi).

Simulator
Apa yang perlu kita lakukan pada ketika ini ialah menjalankan simulasi sebenarnya. Ini dilakukan menggunakan
fungsi global Simulator::Lari.

Simulator::Jalankan ();

Apabila kita sebelum ini memanggil kaedah,

serverApps.Start (Saat (1.0));
serverApps.Stop (Saat (10.0));
...
clientApps.Start (Secons (2.0));
clientApps.Stop (Saat (10.0));

kami sebenarnya menjadualkan acara dalam simulator pada 1.0 saat, 2.0 saat dan dua acara
pada 10.0 saat. Bila Simulator::Lari dipanggil, sistem akan mula melihat melalui
senarai acara yang dijadualkan dan melaksanakannya. Mula-mula ia akan menjalankan acara pada 1.0 saat,
yang akan membolehkan aplikasi pelayan gema (acara ini, seterusnya, menjadualkan banyak
acara lain). Kemudian ia akan menjalankan acara yang dijadualkan untuk t=2.0 saat yang akan bermula
aplikasi pelanggan gema. Sekali lagi, acara ini mungkin menjadualkan lebih banyak acara. Permulaan
pelaksanaan acara dalam aplikasi klien gema akan memulakan fasa pemindahan data bagi
simulasi dengan menghantar paket ke pelayan.

Tindakan menghantar paket ke pelayan akan mencetuskan rangkaian peristiwa yang akan berlaku
secara automatik dijadualkan di belakang tabir dan yang akan melaksanakan mekanik
gema paket mengikut pelbagai parameter masa yang telah kami tetapkan dalam skrip.

Akhirnya, kerana kami hanya menghantar satu paket (ingat MaxPackets atribut telah ditetapkan
satu), rangkaian peristiwa yang dicetuskan oleh permintaan gema pelanggan tunggal itu akan berkurangan dan
simulasi akan terbiar. Sebaik sahaja ini berlaku, acara yang selebihnya akan menjadi Berhenti
acara untuk pelayan dan pelanggan. Apabila peristiwa ini dilaksanakan, tidak ada
acara selanjutnya untuk diproses dan Simulator::Lari pulangan. Simulasi kemudiannya selesai.

Yang tinggal hanyalah membersihkan. Ini dilakukan dengan memanggil fungsi global
Simulator:: Musnahkan. Apabila pembantu berfungsi (atau tahap rendah ns-3 kod) dilaksanakan, mereka
menyusunnya supaya cangkuk dimasukkan ke dalam simulator untuk memusnahkan semua objek
yang dicipta. Anda tidak perlu menjejaki mana-mana objek ini sendiri ---
anda hanya perlu menelefon Simulator:: Musnahkan dan keluar. The ns-3 sistem dijaga
bahagian yang sukar untuk anda. Baki baris pertama kami ns-3 skrip, pertama.cc, lakukan sahaja
bahawa:

Simulator::Memusnahkan ();
0 kembali;
}

Bila yang simulator akan berhenti?
ns-3 ialah simulator Acara Diskret (DE). Dalam simulator sedemikian, setiap acara dikaitkan
dengan masa pelaksanaannya, dan simulasi diteruskan dengan melaksanakan peristiwa dalam temporal
susunan masa simulasi. Acara boleh menyebabkan acara akan datang dijadualkan (contohnya, a
pemasa boleh menjadualkan semula dirinya untuk tamat tempoh pada selang berikutnya).

Peristiwa awal biasanya dicetuskan oleh setiap objek, contohnya, IPv6 akan menjadualkan Penghala
Iklan, Rayuan Jiran, dsb., Jadual Permohonan paket pertama
menghantar acara, dsb.

Apabila sesuatu peristiwa diproses, ia mungkin menjana sifar, satu atau lebih peristiwa. Sebagai simulasi
melaksanakan, peristiwa digunakan, tetapi lebih banyak peristiwa mungkin (atau mungkin tidak) dijana. The
simulasi akan berhenti secara automatik apabila tiada acara selanjutnya berada dalam baris gilir acara, atau apabila
acara Stop khas ditemui. Acara Stop dicipta melalui Simulator::Berhenti
(stopTime); fungsi.

Terdapat kes tipikal di mana Simulator::Berhenti adalah benar-benar perlu untuk menghentikan
simulasi: apabila terdapat peristiwa yang dapat mengekalkan diri. Peristiwa yang berterusan (atau berulang).
adalah acara yang sentiasa menjadualkan sendiri. Akibatnya, mereka sentiasa menjaga acara itu
beratur tidak kosong.

Terdapat banyak protokol dan modul yang mengandungi peristiwa berulang, cth:

· FlowMonitor - pemeriksaan berkala untuk paket yang hilang

· RIPng - siaran berkala kemas kini jadual penghalaan

· dan lain-lain.

Dalam kes ini, Simulator::Berhenti adalah perlu untuk menghentikan simulasi dengan anggun. Dalam
tambahan, apabila ns-3 berada dalam mod emulasi, the RealtimeSimulator digunakan untuk menyimpan
jam simulasi sejajar dengan jam mesin, dan Simulator::Berhenti adalah perlu untuk berhenti
proses itu.

Banyak program simulasi dalam tutorial tidak memanggil secara eksplisit Simulator::Berhenti,
kerana baris gilir acara akan kehabisan acara secara automatik. Walau bagaimanapun, program ini akan
juga menerima panggilan ke Simulator::Berhenti. Sebagai contoh, pernyataan tambahan berikut dalam
program contoh pertama akan menjadualkan perhentian eksplisit pada 11 saat:

+ Simulator::Berhenti (Saat (11.0));
Simulator::Jalankan ();
Simulator::Memusnahkan ();
0 kembali;
}

Perkara di atas sebenarnya tidak akan mengubah tingkah laku program ini, kerana ini
simulasi secara semula jadi tamat selepas 10 saat. Tetapi jika anda menukar masa berhenti
penyataan di atas dari 11 saat hingga 1 saat, anda akan perasan bahawa simulasi
berhenti sebelum sebarang output dicetak ke skrin (kerana output berlaku sekitar masa 2
saat masa simulasi).

Adalah penting untuk menelefon Simulator::Berhenti sebelum memanggil Simulator::Lari; jika tidak,
Simulator::Lari mungkin tidak akan mengembalikan kawalan ke program utama untuk melaksanakan hentian!

Bangunan skrip
Kami telah menjadikannya remeh untuk membina skrip mudah anda. Apa yang anda perlu lakukan ialah menjatuhkan anda
skrip ke dalam direktori scratch dan ia akan dibina secara automatik jika anda menjalankan Waf.
Jom cuba. Salinan contoh/tutorial/first.cc ke menggaru direktori selepas menukar
kembali ke direktori peringkat atas.

$ cd../ ..
$ cp contoh/tutorial/first.cc scratch/myfirst.cc

Sekarang bina skrip contoh pertama anda menggunakan waf:

$ ./waf

Anda sepatutnya melihat mesej yang melaporkan bahawa anda kali pertama saya contoh berjaya dibina.

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[614/708] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[706/708] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (2.357s)

Anda kini boleh menjalankan contoh (perhatikan bahawa jika anda membina program anda dalam direktori scratch
anda mesti menjalankannya keluar dari direktori awal):

$ ./waf --run scratch/myfirst

Anda sepatutnya melihat beberapa output:

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.418s)
Dihantar 1024 bait ke 10.1.1.2
Menerima 1024 bait daripada 10.1.1.1
Menerima 1024 bait daripada 10.1.1.2

Di sini anda melihat bahawa sistem binaan menyemak untuk memastikan bahawa fail telah dibina dan
kemudian menjalankannya. Anda melihat komponen pengelogan pada klien gema menunjukkan bahawa ia telah dihantar
satu paket 1024 bait ke Pelayan Echo pada 10.1.1.2. Anda juga melihat komponen pengelogan
pada pelayan gema mengatakan bahawa ia telah menerima 1024 bait daripada 10.1.1.1. Pelayan gema
menggemakan paket secara senyap dan anda melihat log klien gema yang telah diterima paketnya
kembali dari pelayan.

Ns-3 Source Kod
Sekarang anda telah menggunakan beberapa ns-3 pembantu yang mungkin anda ingin lihat pada beberapa
kod sumber yang melaksanakan fungsi tersebut. Kod terbaharu boleh dilayari
pelayan web kami di pautan berikut: http://code.nsnam.org/ns-3-dev. Di sana, anda akan melihat
halaman ringkasan Mercurial untuk kami ns-3 pokok pembangunan.

Di bahagian atas halaman, anda akan melihat beberapa pautan,

ringkasan | shortlog | log perubahan | graf | tag | fail

Teruskan dan pilih fail pautan. Inilah tahap tertinggi kebanyakan kami
repositori akan lihat:

drwxr-xr-x [atas]
drwxr-xr-x mengikat fail python
fail doc drwxr-xr-x
drwxr-xr-x contoh fail
fail drwxr-xr-x ns3
fail scratch drwxr-xr-x
fail drwxr-xr-x src
drwxr-xr-x menggunakan fail
-rw-r--r-- 2009-07-01 12:47 +0200 560 .hgignore fail | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 1886 fail .hgtags | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 1276 fail PENULIS | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html fail | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 17987 fail LESEN | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 3742 fail README | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 16171 LEPAS_NOTA fail | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSI fail | semakan | anotasi
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 fail waf | semakan | anotasi
-rwxr-xr-x 2009-07-01 12:47 +0200 28 fail waf.bat | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 35395 fail wskrip | semakan | anotasi
-rw-r--r-- 2009-07-01 12:47 +0200 7673 fail wutils.py | semakan | anotasi

Skrip contoh kami adalah dalam contoh direktori. Jika anda klik pada contoh awak akan lihat
senarai subdirektori. Salah satu fail dalam tutorial subdirektori ialah pertama.cc. Jika anda
klik pada pertama.cc anda akan menemui kod yang baru anda lalui.

Kod sumber terutamanya dalam src direktori. Anda boleh melihat kod sumber sama ada dengan
mengklik pada nama direktori atau dengan mengklik pada fail pautan di sebelah kanan
nama direktori. Jika anda klik pada src direktori, anda akan dibawa ke senarai
yang src subdirektori. Jika anda kemudian klik pada teras subdirektori, anda akan menemui senarai
fail. Fail pertama yang anda akan temui (setakat penulisan ini) ialah menggugurkan kandungan.h. Jika anda klik pada
menggugurkan kandungan.h pautan, anda akan dihantar ke fail sumber untuk menggugurkan kandungan.h yang mengandungi makro yang berguna
untuk keluar dari skrip jika keadaan abnormal dikesan.

Kod sumber untuk pembantu yang telah kami gunakan dalam bab ini boleh didapati dalam
src/applications/helper direktori. Jangan segan-segan untuk mencari di dalam pokok direktori untuk mendapatkan
rasa untuk apa yang ada dan gaya ns-3 program.

MENCUCUT


Menggunakan yang Pembalakan Modul
Kami telah melihat secara ringkas ns-3 modul pembalakan semasa pergi ke
pertama.cc skrip. Kami kini akan melihat dengan lebih dekat dan melihat jenis kes penggunaan
subsistem pembalakan direka bentuk untuk menampung.

Pembalakan Pengenalan
Banyak sistem besar menyokong beberapa jenis kemudahan pengelogan mesej, dan ns-3 bukan satu
pengecualian. Dalam sesetengah kes, hanya mesej ralat dilog ke "konsol pengendali" (yang
biasanya stderr dalam sistem berasaskan Unix). Dalam sistem lain, mesej amaran mungkin
output serta mesej maklumat yang lebih terperinci. Dalam beberapa kes, kemudahan pembalakan
digunakan untuk mengeluarkan mesej nyahpepijat yang boleh mengubah output menjadi kabur dengan cepat.

ns-3 mengambil pandangan bahawa semua tahap verbositi ini berguna dan kami menyediakan a
pendekatan berbilang peringkat yang boleh dipilih untuk pengelogan mesej. Pembalakan boleh dilumpuhkan sepenuhnya,
didayakan berdasarkan komponen demi komponen, atau didayakan secara global; dan ia menyediakan boleh dipilih
tahap verbositi. The ns-3 modul log menyediakan ringkas, agak mudah untuk digunakan
cara untuk mendapatkan maklumat berguna daripada simulasi anda.

Anda harus faham bahawa kami menyediakan mekanisme tujuan umum --- mengesan --- kepada
dapatkan data daripada model anda yang sepatutnya diutamakan untuk output simulasi (lihat
bahagian tutorial Menggunakan Sistem Pengesanan untuk butiran lanjut tentang sistem pengesanan kami).
Pengelogan harus diutamakan untuk menyahpepijat maklumat, amaran, mesej ralat atau sebarang
masa anda ingin mendapatkan mesej pantas daripada skrip atau model anda dengan mudah.

Pada masa ini terdapat tujuh peringkat mesej log peningkatan verbositi yang ditakrifkan dalam
sistem.

· LOG_ERROR --- Log mesej ralat (makro yang berkaitan: NS_LOG_ERROR);

· LOG_WARN --- Log mesej amaran (makro yang berkaitan: NS_LOG_WARN);

· LOG_DEBUG --- Log agak jarang, mesej penyahpepijatan ad-hoc (makro yang berkaitan:
NS_LOG_DEBUG);

· LOG_INFO --- Log mesej maklumat tentang kemajuan program (makro yang berkaitan:
NS_LOG_INFO);

· LOG_FUNCTION --- Log mesej yang menerangkan setiap fungsi yang dipanggil (dua makro yang berkaitan:
NS_LOG_FUNCTION, digunakan untuk fungsi ahli dan NS_LOG_FUNCTION_NOARGS, digunakan untuk statik
fungsi);

· LOG_LOGIC -- Mesej log yang menerangkan aliran logik dalam fungsi (makro yang berkaitan:
NS_LOG_LOGIC);

· LOG_ALL --- Log semua yang dinyatakan di atas (tiada makro yang berkaitan).

Untuk setiap LOG_TYPE terdapat juga LOG_LEVEL_TYPE yang, jika digunakan, membolehkan pengelogan semua
peringkat di atasnya sebagai tambahan kepada tahapnya. (Akibat daripada ini, LOG_ERROR dan
LOG_LEVEL_ERROR dan juga LOG_ALL dan LOG_LEVEL_ALL adalah setara dari segi fungsi.) Untuk
contoh, mendayakan LOG_INFO hanya akan mendayakan mesej yang disediakan oleh makro NS_LOG_INFO, manakala
mendayakan LOG_LEVEL_INFO juga akan mendayakan mesej yang disediakan oleh NS_LOG_DEBUG, NS_LOG_WARN
dan makro NS_LOG_ERROR.

Kami juga menyediakan makro pengelogan tanpa syarat yang sentiasa dipaparkan, tanpa mengira
tahap pembalakan atau pemilihan komponen.

· NS_LOG_UNCOND -- Log mesej yang berkaitan tanpa syarat (tiada tahap log yang berkaitan).

Setiap peringkat boleh diminta secara tunggal atau kumulatif; dan pembalakan boleh disediakan menggunakan a
pembolehubah persekitaran shell (NS_LOG) atau melalui panggilan fungsi sistem log. Seperti yang dilihat
awal dalam tutorial, sistem pembalakan mempunyai dokumentasi Doxygen dan kini akan menjadi a
masa yang baik untuk meneliti dokumentasi Modul Pembalakan jika anda belum melakukannya.

Sekarang setelah anda membaca dokumentasi dengan terperinci, mari gunakan sebahagian daripada pengetahuan itu
untuk mendapatkan beberapa maklumat menarik daripada scratch/myfirst.cc contoh skrip yang anda ada
sudah dibina.

Mendayakan Pembalakan
Mari gunakan pembolehubah persekitaran NS_LOG untuk menghidupkan beberapa lagi pengelogan, tetapi pertama, hanya untuk
dapatkan sokongan kami, teruskan dan jalankan skrip terakhir seperti yang anda lakukan sebelum ini,

$ ./waf --run scratch/myfirst

Anda sepatutnya melihat keluaran yang kini biasa bagi yang pertama ns-3 contoh program

$ Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.413s)
Dihantar 1024 bait ke 10.1.1.2
Menerima 1024 bait daripada 10.1.1.1
Menerima 1024 bait daripada 10.1.1.2

Ternyata mesej "Dihantar" dan "Diterima" yang anda lihat di atas sebenarnya sedang dilog
mesej daripada UdpEchoClientApplication and UdpEchoServerApplication. Kita boleh bertanya kepada
aplikasi klien, sebagai contoh, untuk mencetak lebih banyak maklumat dengan menetapkan tahap pengelogannya
melalui pembolehubah persekitaran NS_LOG.

Saya akan mengandaikan dari sini bahawa anda menggunakan shell seperti sh yang menggunakan
sintaks "VARIABLE=value". Jika anda menggunakan shell seperti csh, maka anda perlu melakukannya
tukar contoh saya kepada sintaks "nilai VARIABLE setenv" yang diperlukan oleh cengkerang tersebut.

Pada masa ini, aplikasi klien gema UDP sedang bertindak balas kepada baris kod berikut dalam
scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Baris kod ini membolehkan LOG_LEVEL_INFO tahap pembalakan. Apabila kita melepasi pembalakan
bendera tahap, kami sebenarnya mendayakan tahap yang diberikan dan semua tahap yang lebih rendah. Dalam kes ini,
kami telah membolehkan NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN and NS_LOG_ERROR. Kita boleh meningkat
tahap pengelogan dan dapatkan lebih banyak maklumat tanpa mengubah skrip dan menyusun semula oleh
menetapkan pembolehubah persekitaran NS_LOG seperti ini:

$ eksport NS_LOG=UdpEchoClientApplication=level_all

Ini menetapkan pembolehubah persekitaran shell NS_LOG kepada rentetan,

UdpEchoClientApplication=level_all

Bahagian kiri tugasan ialah nama komponen pengelogan yang ingin kami tetapkan,
dan sebelah kanan ialah bendera yang kita nak guna. Dalam kes ini, kita akan menghidupkan
semua peringkat penyahpepijatan untuk aplikasi. Jika anda menjalankan skrip dengan set NS_LOG
dengan cara ini, yang ns-3 sistem pembalakan akan mengambil perubahan dan anda akan melihat perkara berikut
pengeluaran:

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Dihantar 1024 bait ke 10.1.1.2
Menerima 1024 bait daripada 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Menerima 1024 bait daripada 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Maklumat nyahpepijat tambahan yang disediakan oleh aplikasi adalah daripada NS_LOG_FUNCTION
tahap. Ini menunjukkan setiap kali fungsi dalam aplikasi dipanggil semasa skrip
perlaksanaan. Secara amnya, penggunaan (sekurang-kurangnya) NS_LOG_FUNCTION(ini) dalam fungsi ahli ialah
diutamakan. Gunakan NS_LOG_FUNCTION_NOARGS() hanya dalam fungsi statik. Perhatikan, bagaimanapun, bahawa
tiada keperluan dalam ns-3 sistem yang model mesti menyokong mana-mana tertentu
fungsi pembalakan. Keputusan mengenai berapa banyak maklumat yang direkod diserahkan kepada
pembangun model individu. Dalam kes aplikasi gema, banyak log
output tersedia.

Anda kini boleh melihat log panggilan fungsi yang dibuat kepada aplikasi. Jika awak
lihat dengan teliti anda akan melihat satu kolon di antara rentetan UdpEchoClientApplication
dan nama kaedah di mana anda mungkin menjangkakan pengendali skop C++ (::). Ini adalah
sengaja.

Nama itu sebenarnya bukan nama kelas, ia adalah nama komponen pengelogan. Apabila terdapat a
surat-menyurat satu-dengan-satu antara fail sumber dan kelas, ini biasanya akan menjadi
nama kelas tetapi anda harus faham bahawa ia sebenarnya bukan nama kelas, dan terdapat a
kolon tunggal di sana dan bukannya kolon berganda untuk mengingatkan anda dengan cara yang agak halus untuk
secara konseptual memisahkan nama komponen pengelogan daripada nama kelas.

Ternyata dalam beberapa kes, sukar untuk menentukan kaedah mana sebenarnya
menghasilkan mesej log. Jika anda melihat dalam teks di atas, anda mungkin tertanya-tanya di mana rentetan
"Diterima 1024 bait dari 10.1.1.2" datang daripada. Anda boleh menyelesaikan masalah ini dengan ATAU
prefix_func tahap ke dalam NS_LOG pembolehubah persekitaran. Cuba lakukan perkara berikut,

$ eksport 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Ambil perhatian bahawa petikan diperlukan kerana bar menegak yang kami gunakan untuk menunjukkan ATAU
operasi juga merupakan penyambung paip Unix.

Sekarang, jika anda menjalankan skrip anda akan melihat bahawa sistem pembalakan memastikan bahawa setiap
mesej daripada komponen log yang diberikan diawali dengan nama komponen.

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Dihantar 1024 bait ke 10.1.1.2
Menerima 1024 bait daripada 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Menerima 1024 bait daripada 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Anda kini boleh melihat semua mesej yang datang daripada aplikasi klien gema UDP
dikenal pasti sebegitu. Mesej "Menerima 1024 bait daripada 10.1.1.2" kini jelas
dikenal pasti datang daripada aplikasi klien gema. Mesej yang tinggal mestilah
datang daripada aplikasi pelayan gema UDP. Kita boleh mendayakan komponen itu dengan memasukkan a
senarai komponen dipisahkan kolon dalam pembolehubah persekitaran NS_LOG.

$ eksport 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
UdpEchoServerApplication=level_all|prefix_func'

Amaran: Anda perlu mengalih keluar baris baharu selepas : dalam contoh teks di atas yang
hanya ada untuk tujuan pemformatan dokumen.

Sekarang, jika anda menjalankan skrip, anda akan melihat semua mesej log daripada kedua-dua klien gema
dan aplikasi pelayan. Anda mungkin melihat bahawa ini boleh menjadi sangat berguna dalam masalah nyahpepijat.

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Dihantar 1024 bait ke 10.1.1.2
UdpEchoServerApplication:HandleRead(): Menerima 1024 bait daripada 10.1.1.1
UdpEchoServerApplication:HandleRead(): Paket bergema
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Menerima 1024 bait daripada 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Ia juga kadangkala berguna untuk dapat melihat masa simulasi di mana mesej log
dijana. Anda boleh melakukan ini dengan ORing dalam bit prefix_time.

$ eksport 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time:
UdpEchoServerApplication=level_all|prefix_func|prefix_time'

Sekali lagi, anda perlu mengalih keluar baris baharu di atas. Jika anda menjalankan skrip sekarang, anda sepatutnya
lihat output berikut:

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Dihantar 1024 bait ke 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Menerima 1024 bait daripada 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Paket bergema
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Menerima 1024 bait daripada 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Anda boleh melihat bahawa pembina untuk UdpEchoServer telah dipanggil pada masa simulasi
0 saat. Ini sebenarnya berlaku sebelum simulasi bermula, tetapi masanya adalah
dipaparkan sebagai sifar saat. Perkara yang sama berlaku untuk mesej pembina UdpEchoClient.

Ingatlah bahawa scratch/first.cc skrip memulakan aplikasi pelayan gema pada satu saat
ke dalam simulasi. Anda kini boleh melihat bahawa StartApplication kaedah pelayan ialah,
sebenarnya, dipanggil pada satu saat. Anda juga boleh melihat bahawa aplikasi klien gema adalah
bermula pada masa simulasi selama dua saat seperti yang kami minta dalam skrip.

Anda kini boleh mengikuti perkembangan simulasi dari JadualTransmit panggil di
pelanggan yang menelefon HANTAR kepada HandleRead panggil balik dalam aplikasi pelayan gema. Catatan
bahawa masa berlalu untuk paket dihantar merentasi pautan titik ke titik ialah 3.69
milisaat. Anda melihat pelayan gema mengelog mesej yang memberitahu anda bahawa ia telah bergema
paket dan kemudian, selepas kelewatan saluran lain, anda melihat klien gema menerima
paket bergema di dalamnya HandleRead kaedah.

Terdapat banyak perkara yang berlaku di bawah perlindungan dalam simulasi ini yang anda tidak
melihat juga. Anda boleh mengikuti keseluruhan proses dengan mudah dengan menghidupkan semua
komponen log masuk dalam sistem. Cuba tetapkan NS_LOG pembolehubah kepada yang berikut,

$ eksport 'NS_LOG=*=level_all|prefix_func|prefix_time'

Asterisk di atas ialah kad bebas komponen pengelogan. Ini akan menghidupkan semua
log masuk semua komponen yang digunakan dalam simulasi. Saya tidak akan mengeluarkan semula output
di sini (setakat penulisan ini ia menghasilkan 1265 baris output untuk gema paket tunggal) tetapi
anda boleh mengubah hala maklumat ini ke dalam fail dan menyemaknya dengan kegemaran anda
editor jika anda suka,

$ ./waf --run scratch/myfirst > log.out 2>&1

Saya secara peribadi menggunakan versi pembalakan yang sangat verbose ini apabila saya dibentangkan dengan a
masalah dan saya tidak tahu di mana perkara yang tidak kena. Saya boleh mengikuti perkembangan
kod dengan agak mudah tanpa perlu menetapkan titik putus dan melangkah melalui kod dalam penyahpepijat.
Saya hanya boleh mengedit output dalam editor kegemaran saya dan mencari perkara yang saya harapkan,
dan melihat perkara yang berlaku yang saya tidak jangkakan. Apabila saya mempunyai idea umum tentang apa itu
menjadi salah, saya beralih ke penyahpepijat untuk pemeriksaan terperinci masalah itu.
Output jenis ini boleh menjadi sangat berguna apabila skrip anda melakukan sesuatu sepenuhnya
tidak dijangka. Jika anda melangkah menggunakan penyahpepijat, anda mungkin terlepas lawatan yang tidak dijangka
sepenuhnya. Mengelog persiaran menjadikannya cepat kelihatan.

Menambah Pembalakan kepada Matlamat Kod
Anda boleh menambah pengelogan baharu pada simulasi anda dengan membuat panggilan ke komponen log melalui
beberapa makro. Mari kita berbuat demikian dalam myfirst.cc skrip yang kita ada dalam menggaru direktori.

Ingat bahawa kami telah menentukan komponen pengelogan dalam skrip itu:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Anda kini tahu bahawa anda boleh mendayakan semua pengelogan untuk komponen ini dengan menetapkan
NS_LOG pembolehubah persekitaran kepada pelbagai peringkat. Mari teruskan dan tambahkan beberapa pengelogan ke
skrip. Makro yang digunakan untuk menambah mesej log peringkat maklumat ialah NS_LOG_INFO. Pergi
ke hadapan dan tambah satu (sejurus sebelum kita mula mencipta nod) yang memberitahu anda bahawa skrip
ialah "Mencipta Topologi." Ini dilakukan seperti dalam coretan kod ini,

Buka scratch/myfirst.cc dalam editor kegemaran anda dan tambah baris,

NS_LOG_INFO ("Mencipta Topologi");

betul-betul sebelum garisan,

NodeContainer nod;
nod.Buat (2);

Sekarang bina skrip menggunakan waf dan kosongkan NS_LOG pembolehubah untuk mematikan torrent
pembalakan yang kami aktifkan sebelum ini:

$ ./waf
$ eksport NS_LOG=

Sekarang, jika anda menjalankan skrip,

$ ./waf --run scratch/myfirst

anda akan tidak lihat mesej baharu anda sejak komponen pengelogannya yang berkaitan
(FirstScriptContoh) belum didayakan. Untuk melihat mesej anda, anda perlu
dayakan FirstScriptContoh komponen pembalakan dengan tahap yang lebih besar daripada atau sama dengan
NS_LOG_INFO. Jika anda hanya mahu melihat tahap pengelogan tertentu ini, anda boleh mendayakannya
oleh,

$ eksport NS_LOG=FirstScriptExample=info

Jika anda kini menjalankan skrip, anda akan melihat mesej log "Mencipta Topologi" baharu anda,

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.404s)
Mencipta Topologi
Dihantar 1024 bait ke 10.1.1.2
Menerima 1024 bait daripada 10.1.1.1
Menerima 1024 bait daripada 10.1.1.2

Menggunakan Perintah Talian Argumen
Menimpa Lalai Atribut
Satu lagi cara anda boleh mengubah cara ns-3 skrip berkelakuan tanpa menyunting dan membina adalah melalui
arahan selaras hujah-hujah. Kami menyediakan mekanisme untuk menghuraikan hujah baris arahan dan
secara automatik menetapkan pembolehubah tempatan dan global berdasarkan hujah tersebut.

Langkah pertama dalam menggunakan sistem hujah baris arahan ialah mengisytiharkan baris arahan
penghurai. Ini dilakukan dengan mudah (dalam program utama anda) seperti dalam kod berikut,

int
utama (int argc, char *argv[])
{
...

cmd Baris Perintah;
cmd.Parse (argc, argv);

...
}

Coretan dua baris ringkas ini sebenarnya sangat berguna dengan sendirinya. Ia membuka pintu kepada
ns-3 pembolehubah global dan atribut sistem. Teruskan dan tambahkan dua baris kod itu ke
yang scratch/myfirst.cc skrip pada permulaan utama. Teruskan dan bina skrip dan jalankan
itu, tetapi minta bantuan skrip dengan cara berikut,

$ ./waf --run "scratch/myfirst --PrintHelp"

Ini akan meminta Waf untuk menjalankan calar/pertama saya skrip dan lulus hujah baris arahan
--CetakBantuan kepada skrip. Sebut harga diperlukan untuk menyelesaikan program mana yang mendapat mana
hujah. Penghurai baris arahan kini akan melihat --CetakBantuan hujah dan balas dengan,

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: Cetak mesej bantuan ini.
--PrintGroups: Cetak senarai kumpulan.
--PrintTypeIds: Cetak semua TypeIds.
--PrintGroup=[kumpulan]: Cetak semua TypeId kumpulan.
--PrintAttributes=[typeid]: Cetak semua atribut typeid.
--PrintGlobals: Cetak senarai global.

Mari fokus pada --CetakAtribut pilihan. Kami telah membayangkan pada ns-3 atribut
sistem semasa berjalan melalui pertama.cc skrip. Kami melihat baris berikut
kod,

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

dan menyebut bahawa Kadar Data sebenarnya adalah atribut daripada PointToPointNetDevice. mari
gunakan parser argumen baris arahan untuk melihat Atribut daripada
PointToPointNetDevice. Penyenaraian bantuan mengatakan bahawa kami harus menyediakan a JenisId. ini
sepadan dengan nama kelas kelas yang Atribut milik. Dalam kes ini
ia akan menjadi ns3::PointToPointNetDevice. Mari teruskan dan taip,

$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"

Sistem akan mencetak semua Atribut peranti bersih jenis ini. Antaranya
Atribut anda akan lihat tersenarai ialah,

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
Kadar data lalai untuk pautan titik ke titik

Ini ialah nilai lalai yang akan digunakan apabila a PointToPointNetDevice dicipta di
sistem. Kami mengatasi lalai ini dengan atribut tetapan di PointToPointHelper
di atas. Mari kita gunakan nilai lalai untuk peranti dan saluran titik ke titik oleh
memadamkan SetDeviceAttribute panggilan dan SetChannelAttribute panggilan daripada myfirst.cc
kita ada dalam direktori scratch.

Skrip anda kini sepatutnya hanya mengisytiharkan PointToPointHelper dan tidak melakukan apa-apa menetapkan operasi
seperti contoh berikut,

...

NodeContainer nod;
nod.Buat (2);

PointToPointHelper pointToPoint;

Peranti NetDeviceContainer;
peranti = pointToPoint.Install (nod);

...

Teruskan dan bina skrip baharu dengan Waf (./waff) dan mari kita kembali dan dayakan beberapa
log dari aplikasi pelayan gema UDP dan hidupkan awalan masa.

$ eksport 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Jika anda menjalankan skrip, anda kini akan melihat output berikut,

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Dihantar 1024 bait ke 10.1.1.2
2.25732s Menerima 1024 bait daripada 10.1.1.1
2.25732s Paket bergema
Menerima 1024 bait daripada 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Ingat bahawa kali terakhir kita melihat masa simulasi di mana paket itu berada
diterima oleh pelayan gema, ia berada pada 2.00369 saat.

2.00369s UdpEchoServerApplication:HandleRead(): Menerima 1024 bait daripada 10.1.1.1

Kini ia menerima paket pada 2.25732 saat. Ini kerana kami baru sahaja menjatuhkan
kadar data daripada PointToPointNetDevice turun kepada lalainya sebanyak 32768 bit sesaat daripada
lima megabit sesaat.

Jika kami menyediakan yang baru Kadar Data menggunakan baris arahan, kami boleh mempercepatkan simulasi kami
naik semula. Kami melakukan ini dengan cara berikut, mengikut formula yang tersirat oleh bantuan
item:

$ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"

Ini akan menetapkan nilai lalai bagi Kadar Data atribut kembali kepada lima megabit setiap
kedua. Adakah anda terkejut dengan hasilnya? Ternyata untuk mendapatkan yang asli
tingkah laku skrip kembali, kita perlu menetapkan kelewatan kelajuan cahaya saluran
juga. Kita boleh meminta sistem baris arahan untuk mencetak Atribut daripada saluran tersebut
sama seperti yang kami lakukan untuk peranti bersih:

$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel"

Kami menemui Kelewatan atribut saluran ditetapkan dengan cara berikut:

--ns3::PointToPointChannel::Delay=[0ns]:
Kelewatan penghantaran melalui saluran

Kami kemudiannya boleh menetapkan kedua-dua nilai lalai ini melalui sistem baris arahan,

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms"

dalam hal ini kami memulihkan masa yang kami ada apabila kami menetapkan secara eksplisit Kadar Data and Kelewatan
dalam skrip:

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Dihantar 1024 bait ke 10.1.1.2
2.00369s Menerima 1024 bait daripada 10.1.1.1
2.00369s Paket bergema
Menerima 1024 bait daripada 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Ambil perhatian bahawa paket itu diterima semula oleh pelayan pada 2.00369 saat. Kita boleh
sebenarnya menetapkan mana-mana Atribut digunakan dalam skrip dengan cara ini. Khususnya kita boleh
menetapkan UdpEchoClient atribut MaxPackets kepada beberapa nilai lain daripada satu.

Bagaimana anda akan melakukannya? Mencubanya. Ingat anda perlu mengulas tempat itu
kami mengatasi lalai atribut dan ditetapkan secara eksplisit MaxPackets dalam skrip. Kemudian kamu
perlu membina semula skrip. Anda juga perlu mencari sintaks untuk tetapan sebenarnya
nilai atribut lalai baharu menggunakan kemudahan bantuan baris arahan. Sebaik sahaja anda mempunyai ini
mendapati anda sepatutnya dapat mengawal bilangan paket yang digemakan daripada arahan itu
barisan. Memandangkan kami orang yang baik, kami akan memberitahu anda bahawa baris arahan anda sepatutnya kelihatan
sesuatu seperti,

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"

Memikat Sendiri Nilai-nilai
Anda juga boleh menambah cangkuk anda sendiri pada sistem baris arahan. Ini dilakukan dengan mudah oleh
menggunakan Tambah Nilai kaedah kepada parser baris arahan.

Mari gunakan kemudahan ini untuk menentukan bilangan paket untuk bergema dalam yang berbeza sama sekali
cara. Mari tambah pembolehubah tempatan yang dipanggil nPaket kepada utama fungsi. Kami akan mulakan
ia kepada satu untuk memadankan tingkah laku lalai kami sebelum ini. Untuk membenarkan penghurai baris arahan untuk
menukar nilai ini, kita perlu memasukkan nilai ke dalam parser. Kami melakukan ini dengan menambah panggilan
kepada Tambah Nilai. Teruskan dan tukar scratch/myfirst.cc skrip untuk bermula dengan
kod berikut,

int
utama (int argc, char *argv[])
{
uint32_t nPaket = 1;

cmd Baris Perintah;
cmd.AddValue("nPackets", "Nomer of packets to echo", nPackets);
cmd.Parse (argc, argv);

...

Tatal ke bawah ke titik dalam skrip yang kami tetapkan MaxPackets atribut dan mengubahnya
supaya ia ditetapkan kepada pembolehubah nPaket bukannya pemalar 1 seperti yang ditunjukkan di bawah.

echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));

Sekarang jika anda menjalankan skrip dan menyediakan --CetakBantuan hujah, anda harus melihat baru anda
pengguna Hujah disenaraikan dalam paparan bantuan.

Cuba,

$ ./waf --run "scratch/myfirst --PrintHelp"

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.403s)
--PrintHelp: Cetak mesej bantuan ini.
--PrintGroups: Cetak senarai kumpulan.
--PrintTypeIds: Cetak semua TypeIds.
--PrintGroup=[kumpulan]: Cetak semua TypeId kumpulan.
--PrintAttributes=[typeid]: Cetak semua atribut typeid.
--PrintGlobals: Cetak senarai global.
Hujah Pengguna:
--nPackets: Bilangan paket untuk digemakan

Jika anda ingin menentukan bilangan paket untuk digemakan, anda kini boleh melakukannya dengan menetapkan
--nPaket hujah dalam baris arahan,

$ ./waf --run "scratch/myfirst --nPackets=2"

Anda kini harus melihat

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Dihantar 1024 bait ke 10.1.1.2
2.25732s Menerima 1024 bait daripada 10.1.1.1
2.25732s Paket bergema
Menerima 1024 bait daripada 10.1.1.2
Dihantar 1024 bait ke 10.1.1.2
3.25732s Menerima 1024 bait daripada 10.1.1.1
3.25732s Paket bergema
Menerima 1024 bait daripada 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Anda kini telah menggemakan dua paket. Agak mudah, bukan?

Anda boleh melihatnya jika anda seorang ns-3 pengguna, anda boleh menggunakan sistem hujah baris arahan untuk
mengawal nilai global dan Atribut. Jika anda seorang pengarang model, anda boleh menambah baharu
Atribut kepada anda Objek dan ia akan tersedia secara automatik untuk ditetapkan oleh anda
pengguna melalui sistem baris arahan. Jika anda seorang pengarang skrip, anda boleh menambah baharu
pembolehubah ke skrip anda dan sangkutkannya ke dalam sistem baris arahan dengan agak tidak menyakitkan.

Menggunakan yang Penjejakan sistem
Keseluruhan titik simulasi adalah untuk menjana output untuk kajian lanjut, dan ns-3
sistem pengesanan adalah mekanisme utama untuk ini. Sejak ns-3 ialah program C++, standard
kemudahan untuk menjana output daripada program C++ boleh digunakan:

#termasuk
...
int utama ()
{
...
std::cout << "Nilai x ialah " << x << std::endl;
...
}

Anda juga boleh menggunakan modul pengelogan untuk menambah sedikit struktur pada penyelesaian anda. di sana
adalah banyak masalah terkenal yang dihasilkan oleh pendekatan sedemikian dan oleh itu kami telah menyediakan a
subsistem pengesanan peristiwa generik untuk menangani isu yang kami fikir penting.

Matlamat asas bagi ns-3 sistem pengesanan ialah:

· Untuk tugas asas, sistem pengesanan harus membenarkan pengguna menjana pengesanan standard
untuk sumber pengesanan popular, dan untuk menyesuaikan objek yang menjana pengesanan;

· Pengguna pertengahan mesti boleh melanjutkan sistem pengesanan untuk mengubah suai format output
dijana, atau untuk memasukkan sumber pengesanan baharu, tanpa mengubah suai teras
simulator;

· Pengguna lanjutan boleh mengubah suai teras simulator untuk menambah sumber pengesanan dan sinki baharu.

. ns-3 sistem pengesanan dibina berdasarkan konsep sumber pengesanan bebas dan
menjejak singki, dan mekanisme seragam untuk menyambungkan sumber ke singki. Sumber surih adalah
entiti yang boleh memberi isyarat peristiwa yang berlaku dalam simulasi dan menyediakan akses kepada
data asas yang menarik. Sebagai contoh, sumber surih boleh menunjukkan apabila paket itu
diterima oleh peranti bersih dan menyediakan akses kepada kandungan paket untuk jejak yang berminat
tenggelam.

Sumber surih tidak berguna dengan sendirinya, ia mesti "disambungkan" ke bahagian lain
kod yang sebenarnya melakukan sesuatu yang berguna dengan maklumat yang diberikan oleh sinki. Jejak
sinki ialah pengguna peristiwa dan data yang disediakan oleh sumber surih. Sebagai contoh,
seseorang boleh mencipta sinki surih yang akan (apabila disambungkan ke sumber surih
contoh sebelumnya) mencetak bahagian menarik dari paket yang diterima.

Rasional pembahagian eksplisit ini adalah untuk membolehkan pengguna melampirkan jenis sinki baharu
sumber pengesanan sedia ada, tanpa memerlukan penyuntingan dan penyusunan semula teras
simulator. Oleh itu, dalam contoh di atas, pengguna boleh menentukan sinki pengesanan baharu dalam dirinya
skrip dan lampirkannya pada sumber pengesanan sedia ada yang ditakrifkan dalam teras simulasi oleh
mengedit hanya skrip pengguna.

Dalam tutorial ini, kami akan melihat beberapa sumber dan sinki yang telah ditetapkan dan menunjukkan caranya
mereka mungkin disesuaikan dengan sedikit usaha pengguna. Lihat bahagian manual ns-3 atau cara-cara
untuk maklumat tentang konfigurasi pengesanan lanjutan termasuk memanjangkan pengesanan
ruang nama dan mencipta sumber pengesanan baharu.

ASCII Penjejakan
ns-3 menyediakan fungsi pembantu yang membungkus sistem pengesanan peringkat rendah untuk membantu anda
dengan butiran yang terlibat dalam mengkonfigurasi beberapa jejak paket yang mudah difahami. Jika awak
dayakan fungsi ini, anda akan melihat output dalam fail ASCII --- oleh itu namanya. Untuk
mereka yang biasa dengan ns-2 output, jenis surih ini adalah serupa dengan keluar.tr dijana
oleh banyak skrip.

Mari masuk terus dan tambahkan beberapa output pengesanan ASCII pada kami scratch/myfirst.cc
skrip. Sejurus sebelum panggilan ke Simulator::Lari (), tambah baris kod berikut:

AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

Seperti dalam banyak yang lain ns-3 simpulan bahasa, kod ini menggunakan objek pembantu untuk membantu mencipta ASCII
jejak. Baris kedua mengandungi dua panggilan kaedah bersarang. Kaedah "dalam",
CreateFileStream() menggunakan simpulan bahasa objek tanpa nama untuk mencipta objek aliran fail pada
tindanan (tanpa nama objek) dan turunkannya ke kaedah yang dipanggil. Kami akan pergi ke dalam ini
lebih banyak lagi pada masa hadapan, tetapi apa yang anda perlu tahu pada ketika ini ialah anda sedang mencipta
objek yang mewakili fail bernama "myfirst.tr" dan menghantarnya ke dalam ns-3. Anda memberitahu
ns-3 untuk menangani isu seumur hidup objek yang dicipta dan juga untuk menangani masalah
disebabkan oleh pengehadan objek aliran C++ yang kurang diketahui (sengaja) berkaitan dengan salinan
pembina.

Panggilan luar, kepada EnableAsciiAll(), memberitahu pembantu bahawa anda ingin mendayakan ASCII
mengesan pada semua peranti titik ke titik dalam simulasi anda; dan anda mahu (dengan syarat)
surih sink untuk menulis maklumat tentang pergerakan paket dalam format ASCII.

Bagi mereka yang biasa dengan ns-2, peristiwa yang dikesan adalah bersamaan dengan titik jejak yang popular
log peristiwa "+", "-", "d", dan "r".

Anda kini boleh membina skrip dan menjalankannya dari baris arahan:

$ ./waf --run scratch/myfirst

Seperti yang telah anda lihat berkali-kali sebelum ini, anda akan melihat beberapa mesej daripada Waf dan kemudian
"'build' selesai dengan jayanya" dengan beberapa bilangan mesej daripada program yang sedang berjalan.

Apabila ia dijalankan, program akan mencipta fail bernama myfirst.tr. Kerana cara
bahawa Waf berfungsi, fail itu tidak dibuat dalam direktori tempatan, ia dibuat di
direktori peringkat atas repositori secara lalai. Jika anda ingin mengawal di mana jejak
disimpan anda boleh menggunakan --cwd pilihan Waf untuk menentukan ini. Kami tidak berbuat demikian, oleh itu
kita perlu menukar ke dalam direktori peringkat teratas repo kami dan lihat ASCII
fail jejak myfirst.tr dalam editor kegemaran anda.

Parsing ASCII Jejak
Terdapat banyak maklumat di sana dalam bentuk yang agak padat, tetapi perkara pertama yang perlu diperhatikan
ialah terdapat beberapa baris yang berbeza dalam fail ini. Ia mungkin sukar untuk dilihat
ini dengan jelas melainkan anda meluaskan tingkap anda dengan ketara.

Setiap baris dalam fail sepadan dengan a mengesan kategori acara. Dalam kes ini kami menjejaki peristiwa di
yang menghantar beratur hadir dalam setiap peranti bersih titik ke titik dalam simulasi. The
menghantar giliran ialah baris gilir yang melaluinya setiap paket ditakdirkan untuk saluran titik ke titik
mesti lulus. Ambil perhatian bahawa setiap baris dalam fail surih bermula dengan aksara tunggal (mempunyai a
ruang selepasnya). Watak ini akan mempunyai makna berikut:

· +: Operasi enqueue berlaku pada baris gilir peranti;

· -: Operasi dequeue berlaku pada baris gilir peranti;

· d: Satu paket telah digugurkan, biasanya kerana baris gilir penuh;

· r: Satu paket telah diterima oleh peranti bersih.

Mari kita lihat lebih terperinci tentang baris pertama dalam fail surih. Saya akan memecahkannya
ke dalam bahagian (inden untuk kejelasan) dengan nombor rujukan di sebelah kiri:

+
2
/NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
ns3::PppHeader (
Protokol Point-to-Point: IP (0x0021))
ns3::Ipv4Header (
tos 0x0 ttl 64 id 0 protokol 17 mengimbangi 0 bendera [tiada]
panjang: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
panjang: 1032 49153 > 9)
Muatan (saiz=1024)

Bahagian pertama acara surih dikembangkan ini (nombor rujukan 0) ialah operasi. Kami
ada + watak, jadi ini sepadan dengan a enqueue operasi pada baris gilir penghantaran.
Bahagian kedua (rujukan 1) ialah masa simulasi yang dinyatakan dalam saat. Anda boleh
ingat bahawa kami bertanya kepada UdpEchoClientApplication untuk mula menghantar paket pada dua saat.
Di sini kita melihat pengesahan bahawa ini memang berlaku.

Bahagian seterusnya pada surih contoh (rujukan 2) memberitahu kami sumber surih mana yang berasal
acara ini (dinyatakan dalam ruang nama pengesanan). Anda boleh memikirkan ruang nama pengesanan
agak seperti anda akan ruang nama sistem fail. Punca ruang nama ialah
NodeList. Ini sepadan dengan bekas yang diuruskan dalam ns-3 kod teras yang mengandungi semua
daripada nod yang dicipta dalam skrip. Sama seperti sistem fail mungkin mempunyai direktori
di bawah akar, kita mungkin mempunyai nombor nod dalam NodeList. Rentetan itu /NodeList/0
oleh itu merujuk kepada nod sifar dalam NodeList yang biasanya kita anggap sebagai "nod
0". Dalam setiap nod terdapat senarai peranti yang telah dipasang. Senarai ini muncul
seterusnya dalam ruang nama. Anda dapat melihat bahawa peristiwa surih ini berasal dari Senarai Peranti/0 iaitu
peranti sifar yang dipasang dalam nod.

Rentetan seterusnya, $ns3::PointToPointNetDevice memberitahu anda jenis peranti yang terdapat dalam
kedudukan sifar senarai peranti untuk nod sifar. Ingat bahawa operasi + dijumpai di
rujukan 00 bermakna operasi enqueue berlaku pada baris gilir penghantaran peranti.
Ini ditunjukkan dalam segmen akhir "laluan jejak" iaitu TxQueue/Enqueue.

Bahagian selebihnya dalam jejak harus agak intuitif. Rujukan 3-4 menunjukkan
bahawa paket itu terkandung dalam protokol titik-ke-titik. Rujukan 5-7 menunjukkan bahawa
paket itu mempunyai tajuk empat versi IP dan berasal dari alamat IP 10.1.1.1 dan
ditakdirkan untuk 10.1.1.2. Rujukan 8-9 menunjukkan bahawa paket ini mempunyai pengepala UDP dan,
akhirnya, rujukan 10 menunjukkan bahawa muatan ialah 1024 bait yang dijangkakan.

Baris seterusnya dalam fail surih menunjukkan paket yang sama disingkirkan daripada penghantaran
beratur pada nod yang sama.

Baris Ketiga dalam fail surih menunjukkan paket diterima oleh peranti bersih pada
nod dengan pelayan gema. Saya telah menghasilkan semula peristiwa itu di bawah.

r
2.25732
/NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
ns3::Ipv4Header (
tos 0x0 ttl 64 id 0 protokol 17 mengimbangi 0 bendera [tiada]
panjang: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
panjang: 1032 49153 > 9)
Muatan (saiz=1024)

Perhatikan bahawa operasi jejak kini r dan masa simulasi telah meningkat kepada 2.25732
detik. Jika anda telah mengikuti langkah tutorial dengan teliti ini bermakna anda telah melakukannya
meninggalkan Kadar Data daripada peranti bersih dan saluran Kelewatan ditetapkan kepada nilai lalainya.
Kali ini sepatutnya biasa kerana anda telah melihatnya sebelum ini dalam bahagian sebelumnya.

Entri ruang nama sumber surih (rujukan 02) telah berubah untuk menggambarkan bahawa peristiwa ini adalah
datang dari nod 1 (/NodeList/1) dan sumber surih penerimaan paket (/MacRx). Ia
sepatutnya agak mudah untuk anda mengikuti perkembangan paket melalui topologi dengan
melihat baki kesan dalam fail.

PCAP Penjejakan
. ns-3 pembantu peranti juga boleh digunakan untuk mencipta fail surih dalam .pcap format. The
akronim pcap (biasanya ditulis dalam huruf kecil) bermaksud tangkapan paket, dan sebenarnya adalah
API yang merangkumi definisi a .pcap format fail. Program paling popular yang
boleh membaca dan memaparkan format ini ialah Wireshark (dahulunya dipanggil Ethereal). Namun, di sana
adalah banyak penganalisis jejak trafik yang menggunakan format paket ini. Kami menggalakkan pengguna untuk
mengeksploitasi banyak alat yang tersedia untuk menganalisis jejak pcap. Dalam tutorial ini, kami
tumpukan pada melihat jejak pcap dengan tcpdump.

Kod yang digunakan untuk membolehkan pengesanan pcap ialah satu pelapik.

pointToPoint.EnablePcapAll ("myfirst");

Teruskan dan masukkan baris kod ini selepas kod pengesanan ASCII yang baru kami tambahkan
scratch/myfirst.cc. Perhatikan bahawa kami hanya melepasi rentetan "myfirst," dan tidak
"myfirst.pcap" atau sesuatu yang serupa. Ini kerana parameter adalah awalan, bukan a
nama fail lengkap. Pembantu sebenarnya akan membuat fail surih untuk setiap titik ke titik
peranti dalam simulasi. Nama fail akan dibina menggunakan awalan, nombor nod,
nombor peranti dan akhiran ".pcap".

Dalam skrip contoh kami, kami akhirnya akan melihat fail bernama "myfirst-0-0.pcap" dan
"myfirst-1-0.pcap" yang merupakan jejak pcap untuk nod 0-peranti 0 dan nod 1-peranti 0,
masing-masing.

Sebaik sahaja anda telah menambah baris kod untuk mendayakan pengesanan pcap, anda boleh menjalankan skrip dalam
cara biasa:

$ ./waf --run scratch/myfirst

Jika anda melihat pada direktori peringkat atas pengedaran anda, anda kini sepatutnya melihat tiga log
fail: myfirst.tr ialah fail surih ASCII yang telah kami periksa sebelum ini. myfirst-0-0.pcap
and myfirst-1-0.pcap adalah fail pcap baharu yang baru kami hasilkan.

Reading output bersama tcpdump
Perkara paling mudah untuk dilakukan pada ketika ini ialah menggunakan tcpdump untuk melihat pcap fail.

$ tcpdump -nn -tt -r myfirst-0-0.pcap
membaca daripada fail myfirst-0-0.pcap, PPP jenis pautan (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, panjang 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, panjang 1024

tcpdump -nn -tt -r myfirst-1-0.pcap
membaca daripada fail myfirst-1-0.pcap, PPP jenis pautan (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, panjang 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, panjang 1024

Anda boleh lihat di tempat pembuangan myfirst-0-0.pcap (peranti klien) bahawa paket gema itu
dihantar pada 2 saat ke dalam simulasi. Jika anda melihat tempat pembuangan kedua (myfirst-1-0.pcap)
anda boleh melihat paket itu diterima pada 2.257324 saat. Anda melihat paket itu
bergema kembali pada 2.257324 saat dalam pembuangan kedua, dan akhirnya, anda melihat paket itu sedang
diterima semula pada pelanggan dalam pembuangan pertama pada 2.514648 saat.

Reading output bersama Wireshark
Jika anda tidak biasa dengan Wireshark, terdapat tapak web yang boleh anda gunakan
muat turun program dan dokumentasi: http://www.wireshark.org/.

Wireshark ialah antara muka pengguna grafik yang boleh digunakan untuk memaparkan jejak ini
fail. Jika anda mempunyai Wireshark, anda boleh membuka setiap fail surih dan paparan
kandungannya seolah-olah anda telah menangkap paket menggunakan a paket penghidu.

BANGUNAN TOPOLOGI


Bangunan a Bas rangkaian Topologi
Dalam bahagian ini kita akan mengembangkan penguasaan kita ns-3 peranti rangkaian dan saluran untuk
meliputi contoh rangkaian bas. ns-3 menyediakan peranti bersih dan saluran yang kami panggil CSMA
(Carrier Sense Multiple Access).

. ns-3 Peranti CSMA memodelkan rangkaian mudah dalam semangat Ethernet. Ethernet sebenar
menggunakan skema CSMA/CD (Carrier Sense Multiple Access with Collision Detection) dengan
peningkatan secara eksponen mundur untuk bersaing untuk medium penghantaran yang dikongsi. The ns-3
Model peranti dan saluran CSMA hanya subset daripada ini.

Sama seperti kita telah melihat objek pembantu topologi titik ke titik semasa membina
topologi point-to-point, kita akan melihat pembantu topologi CSMA yang setara dalam bahagian ini.
Penampilan dan operasi pembantu ini sepatutnya kelihatan biasa kepada anda.

Kami menyediakan skrip contoh dalam direktori examples/tutorial} kami. Skrip ini dibina di atas
yang pertama.cc skrip dan menambah rangkaian CSMA pada simulasi titik ke titik yang telah kami lakukan
dipertimbangkan. Teruskan dan buka contoh/tutorial/kedua.cc dalam editor kegemaran anda. awak
sudah cukup melihat ns-3 kod untuk memahami kebanyakan perkara yang berlaku dalam perkara ini
contoh, tetapi kami akan menyemak keseluruhan skrip dan memeriksa beberapa output.

Sama seperti dalam pertama.cc contoh (dan dalam semua contoh ns-3) fail bermula dengan emacs
talian mod dan beberapa plat dandang GPL.

Kod sebenar bermula dengan memuatkan modul termasuk fail seperti yang dilakukan dalam pertama.cc
contohnya.

#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"

Satu perkara yang sangat berguna ialah sedikit seni ASCII yang menunjukkan kartun
daripada topologi rangkaian yang dibina dalam contoh. Anda akan menemui "lukisan" yang serupa
kebanyakan contoh kita.

Dalam kes ini, anda boleh melihat bahawa kami akan melanjutkan contoh point-to-point kami (pautan
antara nod n0 dan n1 di bawah) dengan menggantung rangkaian bas di sebelah kanan. Notis
bahawa ini ialah topologi rangkaian lalai kerana anda sebenarnya boleh mengubah bilangan nod
dicipta pada LAN. Jika anda menetapkan nCsma kepada satu, akan terdapat sejumlah dua nod pada
LAN (saluran CSMA) --- satu nod yang diperlukan dan satu nod "tambahan". Secara lalai terdapat tiga
nod "tambahan" seperti yang dilihat di bawah:

// Topologi Rangkaian Lalai
//
/ / 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// titik ke titik | | | |
// ==================
// LAN 10.1.2.0

Kemudian ruang nama ns-3 ialah digunakan dan komponen pembalakan ditakrifkan. Ini semua hanya sebagai
ia berada dalam pertama.cc, jadi belum ada yang baru.

menggunakan ruang nama ns3;

NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");

Program utama bermula dengan kelainan yang sedikit berbeza. Kami menggunakan bendera verbose untuk
menentukan sama ada atau tidak UdpEchoClientApplication and UdpEchoServerApplication pembalakan
komponen didayakan. Bendera ini lalai kepada benar (komponen pengelogan didayakan)
tetapi membolehkan kami mematikan pengelogan semasa ujian regresi contoh ini.

Anda akan melihat beberapa kod biasa yang akan membolehkan anda menukar bilangan peranti pada
Rangkaian CSMA melalui hujah baris arahan. Kami melakukan sesuatu yang serupa apabila kami membenarkan
bilangan paket yang dihantar untuk diubah dalam bahagian pada argumen baris arahan. Yang terakhir
baris memastikan anda mempunyai sekurang-kurangnya satu nod "tambahan".

Kod ini terdiri daripada variasi API yang dilindungi sebelum ini, jadi anda sepatutnya melakukannya sepenuhnya
selesa dengan kod berikut pada ketika ini dalam tutorial.

bool verbose = benar;
uint32_t nCsma = 3;

cmd Baris Perintah;
cmd.AddValue ("nCsma", "Bilangan \"tambahan\" nod/peranti CSMA", nCsma);
cmd.AddValue ("verbose", "Beritahu aplikasi gema untuk log jika benar", verbose);

cmd.Parse (argc, argv);

jika (verbose)
{
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}

nCsma = nCsma == 0 ? 1 : nCsma;

Langkah seterusnya ialah membuat dua nod yang akan kami sambungkan melalui pautan point-to-point.
. NodeContainer digunakan untuk melakukan ini seperti yang telah dilakukan dalam pertama.cc.

NodeContainer p2pNodes;
p2pNodes.Create (2);

Seterusnya, kami mengisytiharkan satu lagi NodeContainer untuk memegang nod yang akan menjadi sebahagian daripada bas
(CSMA) rangkaian. Pertama, kita hanya membuat instantiat objek bekas itu sendiri.

NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);

Baris kod seterusnya Dapat nod pertama (seperti mempunyai indeks satu) daripada
bekas nod titik ke titik dan menambahnya pada bekas nod yang akan mendapat CSMA
peranti. Nod yang dipersoalkan akan berakhir dengan peranti titik ke titik and sebuah CSMA
peranti. Kami kemudian mencipta beberapa nod "tambahan" yang membentuk baki CSMA
rangkaian. Memandangkan kita sudah mempunyai satu nod dalam rangkaian CSMA -- satu nod yang akan mempunyai
kedua-dua peranti bersih titik-ke-titik dan CSMA, bilangan nod "tambahan" bermaksud nombor
nod yang anda inginkan dalam bahagian CSMA tolak satu.

Sedikit kod seterusnya sepatutnya sudah biasa sekarang. Kami instantiate a PointToPointHelper
dan tetapkan lalai yang berkaitan Atribut supaya kita mencipta lima megabit sesaat
pemancar pada peranti yang dibuat menggunakan pembantu dan kelewatan dua milisaat pada saluran
dicipta oleh penolong.

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);

Kami kemudian membuat instantiat a NetDeviceContainer untuk menjejaki peranti bersih titik ke titik
dan kita memasang peranti pada nod titik ke titik.

Kami menyebut di atas bahawa anda akan melihat pembantu untuk peranti dan saluran CSMA, dan
baris seterusnya memperkenalkan mereka. The CsmaHelper berfungsi seperti a PointToPointHelper, Tetapi
ia mencipta dan menghubungkan peranti dan saluran CSMA. Dalam kes peranti CSMA dan
pasangan saluran, perhatikan bahawa kadar data ditentukan oleh a saluran atribut bukan a
peranti atribut. Ini kerana rangkaian CSMA sebenar tidak membenarkan seseorang itu bercampur, kerana
contoh, peranti 10Base-T dan 100Base-T pada saluran tertentu. Kami mula-mula menetapkan kadar data kepada
100 megabit sesaat, dan kemudian tetapkan kelewatan kelajuan cahaya saluran kepada 6560
nano-saat (dipilih sewenang-wenangnya sebagai 1 nanosaat setiap kaki pada segmen 100 meter).
Perhatikan bahawa anda boleh menetapkan a atribut menggunakan jenis data asalnya.

CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);

Sama seperti kami mencipta a NetDeviceContainer untuk memegang peranti yang dicipta oleh
PointToPointHelper kami mencipta a NetDeviceContainer untuk memegang peranti yang dicipta oleh kami
CsmaHelper. Kami memanggil memasang kaedah CsmaHelper untuk memasang peranti ke dalam
simpul dari csmaNodes NodeContainer.

Kami kini telah membuat nod, peranti dan saluran kami, tetapi kami tidak mempunyai susunan protokol
hadir. Sama seperti dalam pertama.cc skrip, kami akan menggunakan InternetStackHelper untuk memasang
timbunan ini.

Timbunan InternetStackHelper;
stack.Install (p2pNodes.Get (0));
stack.Install (csmaNodes);

Ingat bahawa kami mengambil salah satu nod daripada p2pNod bekas dan menambahnya pada
csmaNodes bekas. Oleh itu kita hanya perlu memasang tindanan pada bakinya p2pNod
nod, dan semua nod dalam csmaNodes bekas untuk menutup semua nod dalam
simulasi.

Sama seperti dalam pertama.cc contoh skrip, kita akan menggunakan Ipv4AddressHelper kepada
tetapkan alamat IP kepada antara muka peranti kami. Mula-mula kita menggunakan rangkaian 10.1.1.0 untuk mencipta
dua alamat yang diperlukan untuk dua peranti point-to-point kami.

Alamat Ipv4AddressHelper;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = alamat.Assign (p2pDevices);

Ingat bahawa kami menyimpan antara muka yang dibuat dalam bekas untuk memudahkan pengeluaran
menangani maklumat kemudian untuk digunakan dalam menyediakan aplikasi.

Kami kini perlu memberikan alamat IP kepada antara muka peranti CSMA kami. Operasi berfungsi
sama seperti yang dilakukan untuk kes point-to-point, kecuali kami kini sedang menjalankan operasi pada
bekas yang mempunyai bilangan peranti CSMA yang berubah-ubah --- ingat kami membuat bilangan
Peranti CSMA boleh ditukar dengan hujah baris arahan. Peranti CSMA akan dikaitkan
dengan alamat IP dari nombor rangkaian 10.1.2.0 dalam kes ini, seperti yang dilihat di bawah.

address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = alamat.Assign (csmaDevices);

Sekarang kami mempunyai topologi yang dibina, tetapi kami memerlukan aplikasi. Bahagian ini akan menjadi
asasnya serupa dengan bahagian aplikasi pertama.cc tetapi kita akan pergi
instantiate pelayan pada salah satu nod yang mempunyai peranti CSMA dan klien pada
nod hanya mempunyai peranti titik ke titik.

Mula-mula, kami menyediakan pelayan gema. Kami mencipta a UdpEchoServerHelper dan menyediakan yang diperlukan
atribut nilai kepada pembina iaitu nombor port pelayan. Ingat bahawa pelabuhan ini
boleh ditukar kemudian menggunakan SetAttribute kaedah jika dikehendaki, tetapi kami memerlukannya
diberikan kepada pembina.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Saat (1.0));
serverApps.Stop (Saat (10.0));

Ingatlah bahawa csmaNodes NodeContainer mengandungi salah satu nod yang dicipta untuk
rangkaian point-to-point dan nCsma nod "tambahan". Apa yang kita mahu dapatkan adalah yang terakhir
nod "tambahan". Kemasukan ke sifar csmaNodes bekas akan menjadi titik ke titik
nod. Oleh itu, cara mudah untuk memikirkan perkara ini ialah jika kita mencipta satu nod CSMA "tambahan", maka ia
akan berada di indeks satu daripada csmaNodes bekas. Secara induksi, jika kita mencipta nCsma "tambahan"
nod yang terakhir akan berada di indeks nCsma. Anda lihat ini dipamerkan dalam Dapatkan yang pertama
baris kod.

Aplikasi klien disediakan sama seperti yang kami lakukan dalam pertama.cc contoh skrip. sekali lagi,
kami sediakan diperlukan Atribut kepada UdpEchoClientHelper dalam pembina (dalam kes ini
alamat jauh dan pelabuhan). Kami memberitahu pelanggan untuk menghantar paket ke pelayan yang kami hanya
dipasang pada nod CSMA "tambahan" terakhir. Kami memasang klien di sebelah kiri
nod titik ke titik dilihat dalam ilustrasi topologi.

UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Selang", TimeValue (Saat (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
clientApps.Start (Secons (2.0));
clientApps.Stop (Saat (10.0));

Oleh kerana kami sebenarnya telah membina kerja internet di sini, kami memerlukan beberapa bentuk kerja internet
penghalaan. ns-3 menyediakan apa yang kami panggil penghalaan global untuk membantu anda. Penghalaan global mengambil masa
kelebihan fakta bahawa keseluruhan kerja internet boleh diakses dalam simulasi dan
berjalan melalui semua nod yang dicipta untuk simulasi --- ia melakukan kerja keras
menyediakan penghalaan untuk anda tanpa perlu mengkonfigurasi penghala.

Pada asasnya, apa yang berlaku ialah setiap nod berkelakuan seolah-olah ia adalah penghala OSPF yang
berkomunikasi serta-merta dan secara ajaib dengan semua penghala lain di belakang tabir. Setiap nod
menjana iklan pautan dan menyampaikannya terus kepada pengurus laluan global
yang menggunakan maklumat global ini untuk membina jadual penghalaan bagi setiap nod. Tetapan
atas bentuk penghalaan ini ialah satu baris:

Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

Seterusnya kami membolehkan pengesanan pcap. Baris pertama kod untuk membolehkan pengesanan pcap dalam
penolong point-to-point sepatutnya sudah biasa kepada anda sekarang. Baris kedua membolehkan pcap
mengesan dalam pembantu CSMA dan terdapat parameter tambahan yang anda belum temui lagi.

pointToPoint.EnablePcapAll ("second");
csma.EnablePcap ("second", csmaDevices.Get (1), true);

Rangkaian CSMA ialah rangkaian multi-point-to-point. Ini bermakna terdapat boleh (dan ada dalam
kes ini) berbilang titik akhir pada medium yang dikongsi. Setiap titik akhir ini mempunyai jaringan
peranti yang berkaitan dengannya. Terdapat dua alternatif asas untuk mengumpul jejak
maklumat daripada rangkaian tersebut. Satu cara ialah mencipta fail surih untuk setiap peranti bersih
dan simpan hanya paket yang dipancarkan atau digunakan oleh peranti bersih itu. Cara lain
adalah untuk memilih salah satu peranti dan meletakkannya dalam mod rambang. Peranti tunggal itu kemudian
"menghidu" rangkaian untuk semua paket dan menyimpannya dalam satu fail pcap. Beginilah caranya
tcpdump, sebagai contoh, berfungsi. Parameter akhir itu memberitahu pembantu CSMA sama ada mahu atau tidak
mengatur untuk menangkap paket dalam mod rambang.

Dalam contoh ini, kami akan memilih salah satu peranti pada rangkaian CSMA dan bertanyakannya
untuk melakukan sedutan rambang rangkaian, dengan itu meniru apa tcpdump akan lakukan.
Jika anda menggunakan mesin Linux, anda mungkin melakukan sesuatu seperti itu tcpdump -i eth0 untuk mendapatkan
jejak. Dalam kes ini, kami menentukan peranti yang digunakan csmaDevices.Get(1), yang memilih
peranti pertama dalam bekas. Menetapkan parameter akhir kepada benar membolehkan promiscuous
tangkapan.

Bahagian terakhir kod hanya menjalankan dan membersihkan simulasi seperti pertama.cc
contohnya.

Simulator::Jalankan ();
Simulator::Memusnahkan ();
0 kembali;
}

Untuk menjalankan contoh ini, salin second.cc contoh skrip ke dalam direktori scratch
dan gunakan waf untuk membina seperti yang anda lakukan dengan pertama.cc contoh. Jika anda berada dalam
direktori peringkat atas repositori yang baru anda taip,

$ cp contoh/tutorial/second.cc scratch/mysecond.cc
$ ./waf

Amaran: Kami menggunakan fail second.cc sebagai salah satu ujian regresi kami untuk mengesahkan bahawa ia berfungsi
tepat seperti yang kami fikirkan untuk menjadikan pengalaman tutorial anda sebagai pengalaman yang positif.
Ini bermakna bahawa boleh laku dinamakan kedua sudah wujud dalam projek. Untuk mengelakkan sebarang
kekeliruan tentang perkara yang anda laksanakan, sila lakukan penamaan semula mysecond.cc mencadangkan
atas.

Jika anda mengikuti tutorial secara agama (anda, bukan) anda masih akan mempunyai
set pembolehubah NS_LOG, jadi teruskan dan kosongkan pembolehubah itu dan jalankan program.

$ eksport NS_LOG=
$ ./waf --run scratch/mysecond

Memandangkan kami telah menyediakan aplikasi gema UDP untuk log sama seperti yang kami lakukan pertama.cc, anda akan
lihat output yang serupa apabila anda menjalankan skrip.

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.415s)
Dihantar 1024 bait ke 10.1.2.4
Menerima 1024 bait daripada 10.1.1.1
Menerima 1024 bait daripada 10.1.2.4

Ingat bahawa mesej pertama, "Dihantar 1024 bait kepada 10.1.2.4," ialah klien gema UDP
menghantar paket ke pelayan. Dalam kes ini, pelayan berada pada rangkaian yang berbeza
(10.1.2.0). Mesej kedua, "Diterima 1024 bait dari 10.1.1.1," adalah daripada gema UDP
pelayan, dijana apabila ia menerima paket gema. Mesej terakhir, "Diterima 1024
bait dari 10.1.2.4," adalah daripada klien gema, menunjukkan bahawa ia telah menerima gemanya
kembali dari pelayan.

Jika anda kini pergi dan melihat dalam direktori peringkat atas, anda akan menemui tiga fail surih:

second-0-0.pcap second-1-0.pcap second-2-0.pcap

Mari kita luangkan sedikit masa untuk melihat penamaan fail ini. Kesemuanya mempunyai bentuk yang sama,
- - .pcap. Sebagai contoh, fail pertama dalam penyenaraian ialah
kedua-0-0.pcap yang merupakan surih pcap dari nod sifar, sifar peranti. Ini adalah
peranti bersih titik ke titik pada nod sifar. Fail kedua-1-0.pcap adalah jejak pcap untuk
peranti sifar pada nod satu, juga peranti bersih titik ke titik; dan fail kedua-2-0.pcap is
jejak pcap untuk peranti sifar pada nod dua.

Jika anda merujuk kembali kepada ilustrasi topologi pada permulaan bahagian, anda akan melihat
bahawa nod sifar ialah nod paling kiri bagi pautan titik ke titik dan nod satu ialah nod
yang mempunyai kedua-dua peranti titik ke titik dan peranti CSMA. Anda akan melihat bahawa nod dua ialah
nod "tambahan" pertama pada rangkaian CSMA dan sifar perantinya telah dipilih sebagai peranti
untuk menangkap jejak mod promiscuous.

Sekarang, mari kita ikuti paket gema melalui kerja internet. Pertama, lakukan tcpdump
jejak fail untuk nod titik ke titik paling kiri --- nod sifar.

$ tcpdump -nn -tt -r second-0-0.pcap

Anda sepatutnya melihat kandungan fail pcap yang dipaparkan:

membaca daripada fail second-0-0.pcap, PPP jenis pautan (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, panjang 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, panjang 1024

Baris pertama tempat pembuangan menunjukkan bahawa jenis pautan adalah PPP (point-to-point) yang kami
jangkakan. Anda kemudiannya melihat paket gema meninggalkan nod sifar melalui peranti yang dikaitkan dengan IP
alamat 10.1.1.1 menuju ke alamat IP 10.1.2.4 (nod CSMA paling kanan). paket ini
akan bergerak ke atas pautan titik ke titik dan diterima oleh peranti bersih titik ke titik dihidupkan
nod satu. Mari kita lihat:

$ tcpdump -nn -tt -r second-1-0.pcap

Anda kini sepatutnya melihat output jejak pcap dari sisi lain pautan titik ke titik:

membaca daripada fail second-1-0.pcap, PPP jenis pautan (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, panjang 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, panjang 1024

Di sini kita melihat bahawa jenis pautan juga adalah PPP seperti yang kita jangkakan. Anda melihat paket dari IP
alamat 10.1.1.1 (yang dihantar pada 2.000000 saat) menuju ke alamat IP 10.1.2.4
muncul pada antara muka ini. Sekarang, secara dalaman ke nod ini, paket akan dimajukan ke
antara muka CSMA dan kita sepatutnya melihatnya muncul pada peranti yang menuju ke muktamadnya
destinasi.

Ingat bahawa kami memilih nod 2 sebagai nod penghidu rambang untuk rangkaian CSMA
mari kita lihat pada second-2-0.pcap dan lihat jika ada.

$ tcpdump -nn -tt -r second-2-0.pcap

Anda kini sepatutnya melihat pembuangan rambang nod dua, peranti sifar:

membaca daripada fail second-2-0.pcap, jenis pautan EN10MB (Ethernet)
2.007698 ARP, Minta siapa yang mempunyai 10.1.2.4 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.1, panjang 50
2.007710 ARP, Balas 10.1.2.4 ialah-pada 00:00:00:00:00:06, panjang 50
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, panjang 1024
2.013815 ARP, Minta siapa yang mempunyai 10.1.2.1 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.4, panjang 50
2.013828 ARP, Balas 10.1.2.1 ialah-pada 00:00:00:00:00:03, panjang 50
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, panjang 1024

Seperti yang anda lihat, jenis pautan kini ialah "Ethernet". Sesuatu yang baru telah muncul, walaupun. The
keperluan rangkaian bas ARP, Protokol Resolusi Alamat. Node seseorang tahu ia perlu dihantar
paket ke alamat IP 10.1.2.4, tetapi ia tidak mengetahui alamat MAC
nod yang sepadan. Ia disiarkan pada rangkaian CSMA (ff:ff:ff:ff:ff:ff) meminta
peranti yang mempunyai alamat IP 10.1.2.4. Dalam kes ini, nod paling kanan membalas mengatakannya
berada di alamat MAC 00:00:00:00:00:06. Ambil perhatian bahawa nod dua tidak terlibat secara langsung dalam perkara ini
pertukaran, tetapi menghidu rangkaian dan melaporkan semua trafik yang dilihatnya.

Pertukaran ini dilihat dalam baris berikut,

2.007698 ARP, Minta siapa yang mempunyai 10.1.2.4 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.1, panjang 50
2.007710 ARP, Balas 10.1.2.4 ialah-pada 00:00:00:00:00:06, panjang 50

Kemudian nod satu, peranti satu meneruskan dan menghantar paket gema ke pelayan gema UDP di
Alamat IP 10.1.2.4.

2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, panjang 1024

Pelayan menerima permintaan gema dan mengubah paket itu cuba menghantarnya kembali
sumber. Pelayan mengetahui bahawa alamat ini berada pada rangkaian lain yang dicapai melalui
Alamat IP 10.1.2.1. Ini kerana kami memulakan penghalaan global dan ia telah memikirkan semuanya
daripada ini untuk kita. Tetapi, nod pelayan gema tidak mengetahui alamat MAC yang pertama
Nod CSMA, jadi ia perlu ARP untuknya seperti yang perlu dilakukan oleh nod CSMA pertama.

2.013815 ARP, Minta siapa yang mempunyai 10.1.2.1 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.4, panjang 50
2.013828 ARP, Balas 10.1.2.1 ialah-pada 00:00:00:00:00:03, panjang 50

Pelayan kemudian menghantar gema kembali ke nod pemajuan.

2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, panjang 1024

Melihat kembali pada nod paling kanan pautan titik ke titik,

$ tcpdump -nn -tt -r second-1-0.pcap

Anda kini boleh melihat paket bergema kembali ke pautan point-to-point sebagai yang terakhir
garisan tempat pembuangan kesan.

membaca daripada fail second-1-0.pcap, PPP jenis pautan (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, panjang 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, panjang 1024

Akhir sekali, anda boleh melihat kembali pada nod yang menghasilkan gema

$ tcpdump -nn -tt -r second-0-0.pcap

dan lihat bahawa paket bergema tiba kembali pada sumber pada 2.007602 saat,

membaca daripada fail second-0-0.pcap, PPP jenis pautan (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, panjang 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, panjang 1024

Akhir sekali, ingat bahawa kami menambah keupayaan untuk mengawal bilangan peranti CSMA dalam
simulasi oleh hujah baris arahan. Anda boleh menukar hujah ini dengan cara yang sama seperti bila
kami melihat menukar bilangan paket yang bergema dalam pertama.cc contoh. Cuba lari
program dengan bilangan peranti "tambahan" ditetapkan kepada empat:

$ ./waf --run "scratch/mysecond --nCsma=4"

Anda sekarang harus melihat,

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.405s)
Pada masa pelanggan 2s menghantar 1024 bait ke 10.1.2.5 port 9
Pada masa pelayan 2.0118s menerima 1024 bait daripada 10.1.1.1 port 49153
Pada masa pelayan 2.0118s menghantar 1024 bait ke 10.1.1.1 port 49153
Pada masa 2.02461s pelanggan menerima 1024 bait daripada 10.1.2.5 port 9

Perhatikan bahawa pelayan gema kini telah dipindahkan ke nod CSMA yang terakhir, iaitu
10.1.2.5 dan bukannya kes lalai, 10.1.2.4.

Ada kemungkinan bahawa anda mungkin tidak berpuas hati dengan fail surih yang dijana oleh pemerhati masuk
rangkaian CSMA. Anda mungkin benar-benar ingin mendapatkan jejak daripada satu peranti dan anda mungkin tidak
berminat dengan mana-mana trafik lain pada rangkaian. Anda boleh melakukan ini dengan agak mudah.

Mari kita lihat scratch/mysecond.cc dan tambahkan kod itu yang membolehkan kita menjadi lebih
tertentu. ns-3 pembantu menyediakan kaedah yang mengambil nombor nod dan nombor peranti sebagai
parameter. Teruskan dan gantikan EnablePcap panggilan dengan panggilan di bawah.

pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
csma.EnablePcap ("second", csmaNodes.Get (nCsma)->GetId (), 0, false);
csma.EnablePcap ("second", csmaNodes.Get (nCsma-1)->GetId (), 0, false);

Kami tahu bahawa kami ingin mencipta fail pcap dengan nama asas "kedua" dan kami juga tahu
bahawa peranti yang diminati dalam kedua-dua kes akan menjadi sifar, jadi parameter tersebut tidak
sangat menarik.

Untuk mendapatkan nombor nod, anda mempunyai dua pilihan: pertama, nod dinomborkan dalam a
fesyen meningkat secara membosankan bermula dari sifar dalam susunan yang anda buat
mereka. Satu cara untuk mendapatkan nombor nod adalah dengan memikirkan nombor ini "secara manual" dengan
merenung susunan penciptaan nod. Jika anda lihat pada topologi rangkaian
ilustrasi pada permulaan fail, kami melakukan ini untuk anda dan anda boleh melihat bahawa
nod CSMA terakhir akan menjadi nombor nod nCsma + 1. Pendekatan ini boleh menjadi menjengkelkan
sukar dalam simulasi yang lebih besar.

Cara alternatif, yang kami gunakan di sini, adalah untuk menyedari bahawa NodeContainers mengandungi
petunjuk kepada ns-3 nod Objek. The nod Objek mempunyai kaedah yang dipanggil GetId yang akan
kembalikan ID nod itu, iaitu nombor nod yang kami cari. Mari kita lihat di
Doksigen untuk nod dan cari kaedah itu, yang terletak lebih jauh di bawah ns-3 kod teras
daripada yang kita lihat setakat ini; tapi kadang-kadang kena rajin cari benda yang berfaedah.

Pergi ke dokumentasi Doxygen untuk keluaran anda (ingat bahawa anda boleh menemuinya di
laman web projek). Anda boleh pergi ke nod dokumentasi dengan melihat melalui
Tab "Kelas" dan tatal ke bawah "Senarai Kelas" sehingga anda menemuinya ns3::Nod. Pilih
ns3::Nod dan anda akan dibawa ke dokumentasi untuk nod kelas. Jika anda sekarang
tatal ke bawah ke GetId kaedah dan pilihnya, anda akan dibawa ke terperinci
dokumentasi untuk kaedah tersebut. Menggunakan GetId kaedah boleh membuat penentuan nombor nod
lebih mudah dalam topologi yang kompleks.

Mari kosongkan fail surih lama daripada direktori peringkat atas untuk mengelakkan kekeliruan tentang
apa yang sedang berlaku,

$ rm *.pcap
$ rm *.tr

Jika anda membina skrip baharu dan menjalankan tetapan simulasi nCsma kepada 100,

$ ./waf --run "scratch/mysecond --nCsma=100"

anda akan melihat output berikut:

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.407s)
Pada masa pelanggan 2s menghantar 1024 bait ke 10.1.2.101 port 9
Pada masa pelayan 2.0068s menerima 1024 bait daripada 10.1.1.1 port 49153
Pada masa pelayan 2.0068s menghantar 1024 bait ke 10.1.1.1 port 49153
Pada masa 2.01761s pelanggan menerima 1024 bait daripada 10.1.2.101 port 9

Ambil perhatian bahawa pelayan gema kini terletak di 10.1.2.101 yang sepadan dengan mempunyai 100
nod CSMA "tambahan" dengan pelayan gema pada yang terakhir. Jika anda menyenaraikan fail pcap dalam
direktori peringkat atas yang anda akan lihat,

second-0-0.pcap second-100-0.pcap second-101-0.pcap

Fail jejak kedua-0-0.pcap ialah peranti titik ke titik "paling kiri" iaitu gema
sumber paket. Fail kedua-101-0.pcap sepadan dengan peranti CSMA paling kanan yang
ialah tempat pelayan gema berada. Anda mungkin perasan bahawa parameter akhir pada
panggilan untuk membolehkan pengesanan pcap pada nod pelayan gema adalah palsu. Ini bermakna bahawa jejak
yang terkumpul pada nod itu berada dalam mod tidak rambang.

Untuk menggambarkan perbezaan antara jejak rambang dan tidak rambang, kami juga
meminta jejak tidak rambang untuk nod seterusnya hingga terakhir. Teruskan dan lihat
yang tcpdump khususnya kedua-100-0.pcap.

$ tcpdump -nn -tt -r second-100-0.pcap

Anda kini boleh melihat bahawa nod 100 benar-benar penonton dalam pertukaran gema. Satu-satunya
paket yang diterima adalah permintaan ARP yang disiarkan ke seluruh CSMA
rangkaian.

membaca daripada fail second-100-0.pcap, jenis pautan EN10MB (Ethernet)
2.006698 ARP, Minta siapa yang mempunyai 10.1.2.101 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.1, panjang 50
2.013815 ARP, Minta siapa yang mempunyai 10.1.2.1 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.101, panjang 50

Sekarang lihat pada tcpdump khususnya kedua-101-0.pcap.

$ tcpdump -nn -tt -r second-101-0.pcap

Anda kini boleh melihat bahawa nod 101 adalah benar-benar peserta dalam pertukaran gema.

membaca daripada fail second-101-0.pcap, jenis pautan EN10MB (Ethernet)
2.006698 ARP, Minta siapa yang mempunyai 10.1.2.101 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.1, panjang 50
2.006698 ARP, Balas 10.1.2.101 ialah-pada 00:00:00:00:00:67, panjang 50
2.006803 IP 10.1.1.1.49153 > 10.1.2.101.9: UDP, panjang 1024
2.013803 ARP, Minta siapa yang mempunyai 10.1.2.1 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.101, panjang 50
2.013828 ARP, Balas 10.1.2.1 ialah-pada 00:00:00:00:00:03, panjang 50
2.013828 IP 10.1.2.101.9 > 10.1.1.1.49153: UDP, panjang 1024

Model, Atribut and Realiti
Ini adalah tempat yang mudah untuk membuat lawatan kecil dan membuat perkara penting. Ia mungkin
atau mungkin tidak jelas kepada anda, tetapi apabila seseorang menggunakan simulasi, adalah penting untuk
memahami betul-betul apa yang dimodelkan dan apa yang tidak. Ia menggoda, sebagai contoh, untuk
anggap peranti dan saluran CSMA yang digunakan dalam bahagian sebelumnya seolah-olah ia adalah sebenar
Peranti Ethernet; dan mengharapkan hasil simulasi untuk menggambarkan secara langsung apa yang akan berlaku
dalam Ethernet sebenar. Ini tidak berlaku.

Model adalah, mengikut definisi, abstraksi realiti. Ia akhirnya menjadi tanggungjawab
pengarang skrip simulasi untuk menentukan apa yang dipanggil "julat ketepatan" dan "domain
kebolehgunaan" simulasi secara keseluruhan, dan oleh itu bahagian konstituennya.

Dalam beberapa kes, seperti Csma, agak mudah untuk menentukan perkara itu tidak dimodelkan. Oleh
membaca penerangan model (csma.h) anda boleh mendapati bahawa tiada pengesanan perlanggaran
dalam model CSMA dan tentukan kesesuaian penggunaannya dalam simulasi anda atau apa
kaveat yang mungkin anda ingin sertakan dengan keputusan anda. Dalam kes lain, ia boleh menjadi agak mudah
untuk mengkonfigurasi tingkah laku yang mungkin tidak bersetuju dengan mana-mana realiti yang anda boleh keluar dan beli. Ia
akan terbukti berbaloi untuk meluangkan sedikit masa menyiasat beberapa kejadian sedemikian, dan bagaimana
dengan mudah anda boleh melencong di luar batasan realiti dalam simulasi anda.

Seperti yang anda lihat, ns-3 menyediakan Atribut yang boleh ditetapkan oleh pengguna untuk menukar model dengan mudah
tingkah laku. Pertimbangkan dua daripada Atribut daripada CsmaNetDevice: Mtu and
Mod Enkapsulasi. Yang Mtu atribut menunjukkan Unit Penghantaran Maksimum ke
peranti. Ini ialah saiz Unit Data Protokol (PDU) terbesar yang peranti boleh
hantar.

MTU lalai kepada 1500 bait dalam CsmaNetDevice. Lalai ini sepadan dengan nombor
ditemui dalam RFC 894, "Standard untuk Penghantaran Datagram IP melalui Ethernet
Rangkaian." Nombor itu sebenarnya diperoleh daripada saiz paket maksimum untuk 10Base5
rangkaian (Ethernet spesifikasi penuh) -- 1518 bait. Jika anda menolak enkapsulasi DIX
overhed untuk paket Ethernet (18 bait) anda akan mendapat saiz data maksimum yang mungkin
(MTU) sebanyak 1500 bait. Seseorang juga boleh mendapati bahawa MTU untuk rangkaian IEEE 802.3 ialah 1492
bait. Ini kerana pengkapsulan LLC/SNAP menambahkan lapan bait tambahan overhed kepada
paket itu. Dalam kedua-dua kes, perkakasan asas hanya boleh menghantar 1518 bait, tetapi data
saiz adalah berbeza.

Untuk menetapkan mod enkapsulasi, CsmaNetDevice menyediakan atribut dipanggil
Mod Enkapsulasi yang boleh mengambil nilai Dix or LLC. Ini sepadan dengan Ethernet
dan pembingkaian LLC/SNAP masing-masing.

Jika seseorang meninggalkan Mtu pada 1500 bait dan menukar mod enkapsulasi kepada LLC, keputusan
akan menjadi rangkaian yang merangkumi 1500 bait PDU dengan pembingkaian LLC/SNAP yang menghasilkan
paket 1526 bait, yang akan menyalahi undang-undang dalam banyak rangkaian, kerana ia boleh menghantar a
maksimum 1518 bait setiap paket. Ini berkemungkinan besar akan menghasilkan simulasi yang
secara halus tidak menggambarkan realiti yang anda jangkakan.

Hanya untuk merumitkan gambar, terdapat bingkai jumbo (1500 < MTU <= 9000 bait) dan
bingkai super-jumbo (MTU > 9000 bait) yang tidak dibenarkan secara rasmi oleh IEEE tetapi
tersedia dalam beberapa rangkaian berkelajuan tinggi (Gigabit) dan NIC. Seseorang boleh meninggalkan
mod enkapsulasi ditetapkan kepada Dix, dan tetapkan Mtu atribut pada CsmaNetDevice kepada 64000 bait
-- walaupun berkaitan CsmaChannel Kadar Data telah ditetapkan pada 10 megabit sesaat. ini
pada asasnya akan memodelkan suis Ethernet yang diperbuat daripada 1980Base10 gaya 5-an yang ditoreh vampire
rangkaian yang menyokong datagram super-jumbo. Ini sememangnya bukan sesuatu yang pernah berlaku
pernah dibuat, dan tidak mungkin akan dibuat, tetapi agak mudah untuk anda konfigurasikan.

Dalam contoh sebelumnya, anda menggunakan baris arahan untuk mencipta simulasi yang mempunyai 100
Csma nod. Anda boleh membuat simulasi dengan 500 nod dengan mudah. Jika awak
sebenarnya memodelkan rangkaian 10Base5 vampire-tap, panjang maksimum spesifikasi penuh
Kabel Ethernet ialah 500 meter, dengan jarak paip minimum 2.5 meter. Maksudnya di sana
hanya boleh 200 ketikan pada rangkaian sebenar. Anda boleh membina yang tidak sah dengan mudah
rangkaian dengan cara itu juga. Ini mungkin atau mungkin tidak menghasilkan simulasi yang bermakna
bergantung pada apa yang anda cuba modelkan.

Situasi yang sama boleh berlaku di banyak tempat di ns-3 dan dalam mana-mana simulator. Sebagai contoh,
anda mungkin boleh meletakkan nod sedemikian rupa sehingga ia menduduki ruang yang sama di
masa yang sama, atau anda mungkin boleh mengkonfigurasi penguat atau tahap hingar yang melanggar
undang-undang asas fizik.

ns-3 secara amnya mengutamakan fleksibiliti, dan banyak model akan membenarkan penetapan secara bebas Atribut
tanpa cuba menguatkuasakan sebarang konsistensi sewenang-wenang atau spesifikasi asas tertentu.

Perkara yang perlu dibawa pulang dari ini ialah ns-3 akan menyediakan pangkalan yang sangat fleksibel
untuk anda bereksperimen. Terpulang kepada anda untuk memahami apa yang anda tanyakan kepada sistem
untuk melakukan dan untuk memastikan bahawa simulasi yang anda cipta mempunyai beberapa makna dan beberapa
hubungan dengan realiti yang ditentukan oleh anda.

Bangunan a wayarles rangkaian Topologi
Dalam bahagian ini kami akan mengembangkan lagi pengetahuan kami tentang ns-3 peranti rangkaian dan
saluran untuk merangkumi contoh rangkaian wayarles. ns-3 menyediakan satu set model 802.11
percubaan itu untuk menyediakan pelaksanaan peringkat MAC yang tepat bagi spesifikasi 802.11
dan model peringkat PHY "tidak begitu perlahan" bagi spesifikasi 802.11a.

Sama seperti kita telah melihat objek pembantu topologi point-to-point dan CSMA apabila
membina topologi titik-ke-titik, kita akan melihat setara Wifi pembantu topologi dalam
bahagian ini. Penampilan dan operasi pembantu ini sepatutnya kelihatan agak biasa
anda.

Kami menyediakan skrip contoh dalam kami contoh/tutorial direktori. Skrip ini dibina di atas
yang second.cc skrip dan menambah rangkaian Wifi. Teruskan dan buka
contoh/tutorial/third.cc dalam editor kegemaran anda. Anda sudah cukup melihat
ns-3 kod untuk memahami kebanyakan perkara yang berlaku dalam contoh ini, tetapi terdapat beberapa yang baharu
perkara, jadi kami akan menyemak keseluruhan skrip dan memeriksa beberapa output.

Sama seperti dalam second.cc contoh (dan dalam semua ns-3 contoh) fail bermula dengan emacs
talian mod dan beberapa plat dandang GPL.

Lihat seni ASCII (dihasilkan semula di bawah) yang menunjukkan topologi rangkaian lalai
dibina dalam contoh. Anda boleh lihat bahawa kami akan memanjangkan lagi contoh kami
dengan menggantung rangkaian wayarles di sebelah kiri. Perhatikan bahawa ini adalah rangkaian lalai
topologi kerana anda sebenarnya boleh mengubah bilangan nod yang dicipta pada wayar dan wayarles
rangkaian. Sama seperti dalam second.cc kes skrip, jika anda menukar nCsma, ia akan memberi anda a
bilangan nod CSMA "tambahan". Begitu juga, anda boleh menetapkan nWifi untuk mengawal berapa banyak STA
(stesen) nod dicipta dalam simulasi. Akan sentiasa ada satu AP (Pusat akses)
nod pada rangkaian wayarles. Secara lalai terdapat tiga nod CSMA "tambahan" dan tiga
wayarles STA nod.

Kod bermula dengan memuatkan modul termasuk fail seperti yang dilakukan dalam second.cc contohnya.
Terdapat beberapa termasuk baharu yang sepadan dengan modul Wifi dan mobiliti
modul yang akan kita bincangkan di bawah.

#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"

Ilustrasi topologi rangkaian berikut:

// Topologi Rangkaian Lalai
//
// Wifi 10.1.3.0
// AP
// * * * *
// | | | | 10.1.1.0
// n5 n6 n7 n0 -------------- n1 n2 n3 n4
// titik ke titik | | | |
// ==================
// LAN 10.1.2.0

Anda boleh melihat bahawa kami sedang menambah peranti rangkaian baharu pada nod di sebelah kiri
pautan point-to-point yang menjadi titik capaian untuk rangkaian wayarles. Sebilangan
nod STA tanpa wayar dicipta untuk mengisi rangkaian 10.1.3.0 baharu seperti yang ditunjukkan di sebelah kiri
sebelah ilustrasi.

Selepas ilustrasi, ns-3 ruang nama ialah digunakan dan komponen pembalakan ditakrifkan.
Ini semua sepatutnya sudah biasa sekarang.

menggunakan ruang nama ns3;

NS_LOG_COMPONENT_DEFINE ("ThirdScriptContoh");

Program utama bermula seperti second.cc dengan menambah beberapa parameter baris arahan untuk
mendayakan atau melumpuhkan komponen pengelogan dan untuk menukar bilangan peranti yang dicipta.

bool verbose = benar;
uint32_t nCsma = 3;
uint32_t nWifi = 3;

cmd Baris Perintah;
cmd.AddValue ("nCsma", "Bilangan \"tambahan\" nod/peranti CSMA", nCsma);
cmd.AddValue ("nWifi", "Bilangan peranti STA wifi", nWifi);
cmd.AddValue ("verbose", "Beritahu aplikasi gema untuk log jika benar", verbose);

cmd.Parse (argc,argv);

jika (verbose)
{
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}

Sama seperti dalam semua contoh sebelumnya, langkah seterusnya adalah untuk mencipta dua nod yang akan kami lakukan
sambung melalui pautan point-to-point.

NodeContainer p2pNodes;
p2pNodes.Create (2);

Seterusnya, kita melihat seorang kawan lama. Kami instantiate a PointToPointHelper dan tetapkan yang berkaitan
lalai Atribut supaya kami mencipta pemancar lima megabit sesaat pada peranti
dibuat menggunakan pembantu dan kelewatan dua milisaat pada saluran yang dibuat oleh pembantu.
Kami kemudian Intall peranti pada nod dan saluran di antara mereka.

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);

Seterusnya, kami mengisytiharkan satu lagi NodeContainer untuk memegang nod yang akan menjadi sebahagian daripada bas
(CSMA) rangkaian.

NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);

Baris kod seterusnya Dapat nod pertama (seperti mempunyai indeks satu) daripada
bekas nod titik ke titik dan menambahnya pada bekas nod yang akan mendapat CSMA
peranti. Nod yang dipersoalkan akan berakhir dengan peranti titik ke titik dan CSMA
peranti. Kami kemudian mencipta beberapa nod "tambahan" yang membentuk baki CSMA
rangkaian.

Kami kemudian membuat instantiat a CsmaHelper dan menetapkannya Atribut seperti yang kita lakukan dalam contoh sebelumnya.
Kami mencipta a NetDeviceContainer untuk menjejaki peranti bersih CSMA yang dicipta dan kemudian kami
memasang Peranti CSMA pada nod yang dipilih.

CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));

NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);

Seterusnya, kami akan mencipta nod yang akan menjadi sebahagian daripada rangkaian Wifi. Kami adalah
akan mencipta beberapa nod "stesen" seperti yang ditentukan oleh hujah baris arahan, dan
kita akan menggunakan nod "paling kiri" pautan titik ke titik sebagai nod untuk
Pusat akses.

NodeContainer wifiStaNodes;
wifiStaNodes.Create (nWifi);
NodeContainer wifiApNode = p2pNodes.Get (0);

Bit kod seterusnya membina peranti wifi dan saluran antara sambungan antara
nod wifi ini. Mula-mula, kami mengkonfigurasi PHY dan pembantu saluran:

Saluran YansWifiChannelHelper = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();

Untuk kesederhanaan, kod ini menggunakan konfigurasi lapisan PHY lalai dan model saluran
yang didokumenkan dalam dokumentasi doksigen API untuk
YansWifiChannelHelper:: Lalai and YansWifiPhyHelper:: Lalai kaedah. Apabila objek ini
dicipta, kami mencipta objek saluran dan mengaitkannya dengan pengurus objek lapisan PHY kami
untuk memastikan bahawa semua objek lapisan PHY yang dicipta oleh YansWifiPhyHelper kongsi
saluran asas yang sama, iaitu, mereka berkongsi medium wayarles yang sama dan boleh
komunikasi dan campur tangan:

phy.SetChannel (channel.Create ());

Setelah pembantu PHY dikonfigurasikan, kita boleh fokus pada lapisan MAC. Di sini kita memilih untuk bekerja
dengan MAC bukan Qos jadi kami menggunakan objek NqosWifiMacHelper untuk menetapkan parameter MAC.

WifiHelper wifi = WifiHelper::Default ();
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");

NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();

. SetRemoteStationManager kaedah memberitahu pembantu jenis algoritma kawalan kadar untuk
guna. Di sini, ia meminta pembantu untuk menggunakan algoritma AARF --- butirannya, sudah tentu,
terdapat dalam Doxygen.

Seterusnya, kami mengkonfigurasi jenis MAC, SSID rangkaian infrastruktur yang kami mahu
sediakan dan pastikan stesen kami tidak melakukan pemeriksaan aktif:

Ssid ssid = Ssid ("ns-3-ssid");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));

Kod ini mula-mula mencipta objek pengecam set perkhidmatan (SSID) 802.11 yang akan digunakan
untuk menetapkan nilai "Ssid" atribut pelaksanaan lapisan MAC. Yang khusus
jenis lapisan MAC yang akan dibuat oleh pembantu ditentukan oleh atribut sebagai daripada
jenis "ns3::StaWifiMac". Penggunaan NqosWifiMacHelper akan memastikan bahawa
"QosSupported" atribut untuk objek MAC yang dicipta ditetapkan palsu. Gabungan ini
dua konfigurasi bermakna bahawa tika MAC yang dibuat seterusnya ialah bukan-QoS bukan AP
stesen (STA) dalam BSS infrastruktur (iaitu, BSS dengan AP). Akhirnya, yang
"ActiveProbing" atribut ditetapkan kepada palsu. Ini bermakna permintaan siasatan tidak akan berlaku
dihantar oleh MAC yang dicipta oleh pembantu ini.

Setelah semua parameter khusus stesen dikonfigurasikan sepenuhnya, kedua-duanya pada MAC dan PHY
lapisan, kita boleh memanggil yang kita kenal sekarang memasang kaedah untuk mencipta peranti wifi ini
stesen:

NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);

Kami telah mengkonfigurasi Wifi untuk semua nod STA kami, dan kini kami perlu mengkonfigurasi AP
(titik akses) nod. Kami memulakan proses ini dengan menukar lalai Atribut daripada
NqosWifiMacHelper untuk mencerminkan keperluan AP.

mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));

Dalam kes ini, yang NqosWifiMacHelper akan mencipta lapisan MAC "ns3::ApWifiMac",
yang terakhir menyatakan bahawa tika MAC yang dikonfigurasikan sebagai AP harus dibuat, dengan
jenis pembantu yang membayangkan bahawa "QosSupported" atribut hendaklah ditetapkan kepada palsu - melumpuhkan
Sokongan QoS gaya 802.11e/WMM pada AP yang dibuat.

Baris seterusnya mencipta AP tunggal yang berkongsi set tahap PHY yang sama Atribut (Dan
saluran) sebagai stesen:

NetDeviceContainer apDevices;
apDevices = wifi.Install (phy, mac, wifiApNode);

Sekarang, kami akan menambah model mobiliti. Kami mahu nod STA menjadi mudah alih, mengembara
di dalam kotak sempadan, dan kami mahu menjadikan nod AP tidak bergerak. Kami menggunakan
MobilityHelper untuk memudahkan kami. Pertama, kami membuat instantiat a MobilityHelper objek
dan tetapkan beberapa Atribut mengawal fungsi "pembahagian kedudukan".

MobilityHelper mobiliti;

mobiliti.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinY", DoubleValue (0.0),
"DeltaX", DoubleValue (5.0),
"DeltaY", DoubleValue (10.0),
"GridWidth", UintegerValue (3),
"LayoutType", StringValue ("RowFirst"));

Kod ini memberitahu pembantu mobiliti untuk menggunakan grid dua dimensi untuk meletakkan pada mulanya
nod STA. Jangan ragu untuk meneroka Doxygen untuk kelas ns3::GridPositionAllocator untuk melihat
betul-betul apa yang sedang dilakukan.

Kami telah menyusun nod kami pada grid awal, tetapi sekarang kami perlu memberitahu mereka cara untuk bergerak.
Kami memilih RandomWalk2dMobilityModel yang mempunyai nod bergerak dalam arah rawak di
kelajuan rawak mengelilingi dalam kotak sempadan.

mobiliti.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));

Kami kini memberitahu MobilityHelper untuk memasang model mobiliti pada nod STA.

mobiliti.Pasang (wifiStaNodes);

Kami mahu titik akses kekal dalam kedudukan tetap semasa simulasi. Kami
capai ini dengan menetapkan model mobiliti untuk nod ini menjadi
ns3::ConstantPositionMobilityModel:

mobiliti.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobiliti.Pasang (wifiApNode);

Kami kini mempunyai nod, peranti dan saluran kami yang dibuat, dan model mobiliti dipilih untuk
Nod Wifi, tetapi kami tidak mempunyai tindanan protokol. Sama seperti yang telah kita lakukan sebelum ini
kali, kami akan menggunakan InternetStackHelper untuk memasang tindanan ini.

Timbunan InternetStackHelper;
stack.Install (csmaNodes);
stack.Install (wifiApNode);
stack.Install (wifiStaNodes);

Sama seperti dalam second.cc contoh skrip, kita akan menggunakan Ipv4AddressHelper kepada
tetapkan alamat IP kepada antara muka peranti kami. Mula-mula kita menggunakan rangkaian 10.1.1.0 untuk mencipta
dua alamat yang diperlukan untuk dua peranti point-to-point kami. Kemudian kami menggunakan rangkaian 10.1.2.0
untuk memberikan alamat kepada rangkaian CSMA dan kemudian kami menetapkan alamat dari rangkaian 10.1.3.0
kepada kedua-dua peranti STA dan AP pada rangkaian wayarles.

Alamat Ipv4AddressHelper;

address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = alamat.Assign (p2pDevices);

address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = alamat.Assign (csmaDevices);

address.SetBase ("10.1.3.0", "255.255.255.0");
address.Assign (staDevices);
address.Assign (apDevices);

Kami meletakkan pelayan gema pada nod "paling kanan" dalam ilustrasi pada permulaan
fail. Kami telah melakukan ini sebelum ini.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Saat (1.0));
serverApps.Stop (Saat (10.0));

Dan kami meletakkan klien gema pada nod STA terakhir yang kami buat, menghalakannya ke pelayan dihidupkan
rangkaian CSMA. Kami juga telah melihat operasi serupa sebelum ini.

UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Selang", TimeValue (Saat (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps =
echoClient.Install (wifiStaNodes.Get (nWifi - 1));
clientApps.Start (Secons (2.0));
clientApps.Stop (Saat (10.0));

Memandangkan kami telah membina kerja internet di sini, kami perlu mendayakan penghalaan kerja internet sama seperti
kami lakukan dalam second.cc contoh skrip.

Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

Satu perkara yang boleh mengejutkan sesetengah pengguna ialah hakikat bahawa simulasi yang baru kami buat
tidak akan "semula jadi" berhenti. Ini kerana kami meminta pusat akses wayarles untuk
menjana suar. Ia akan menjana suar selama-lamanya, dan ini akan menghasilkan simulator
acara dijadualkan pada masa hadapan selama-lamanya, jadi kami mesti memberitahu simulator untuk berhenti
walaupun ia mungkin mempunyai acara penjanaan suar yang dijadualkan. Baris kod berikut
memberitahu simulator untuk berhenti supaya kita tidak mensimulasikan suar selama-lamanya dan memasukkan apa yang ada
pada asasnya gelung yang tidak berkesudahan.

Simulator::Berhenti (Saat (10.0));

Kami mencipta penjejakan yang cukup untuk merangkumi ketiga-tiga rangkaian:

pointToPoint.EnablePcapAll ("ketiga");
phy.EnablePcap ("ketiga", apDevices.Get (0));
csma.EnablePcap ("ketiga", csmaDevices.Get (0), benar);

Tiga baris kod ini akan memulakan pengesanan pcap pada kedua-dua nod titik ke titik itu
berfungsi sebagai tulang belakang kami, akan memulakan jejak mod rambang (monitor) pada rangkaian Wifi,
dan akan memulakan jejak rambang pada rangkaian CSMA. Ini akan membolehkan kita melihat semua
trafik dengan bilangan fail surih minimum.

Akhirnya, kami sebenarnya menjalankan simulasi, membersihkan dan kemudian keluar dari program.

Simulator::Jalankan ();
Simulator::Memusnahkan ();
0 kembali;
}

Untuk menjalankan contoh ini, anda perlu menyalin ketiga.cc contoh skrip ke dalam
direktori scratch dan gunakan Waf untuk membina seperti yang anda lakukan dengan second.cc contoh. Jika awak
berada dalam direktori peringkat atas repositori yang anda akan taip,

$ cp contoh/tutorial/third.cc scratch/mythird.cc
$ ./waf
$ ./waf --run scratch/mythird

Sekali lagi, kerana kami telah menyediakan aplikasi gema UDP seperti yang kami lakukan dalam second.cc
skrip, anda akan melihat output yang serupa.

Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'bina' berjaya diselesaikan (0.407s)
Pada masa pelanggan 2s menghantar 1024 bait ke 10.1.2.4 port 9
Pada masa pelayan 2.01796s menerima 1024 bait daripada 10.1.3.3 port 49153
Pada masa pelayan 2.01796s menghantar 1024 bait ke 10.1.3.3 port 49153
Pada masa 2.03364s pelanggan menerima 1024 bait daripada 10.1.2.4 port 9

Ingat bahawa mesej pertama, Dihantar 1024 bait kepada 10.1.2.4," ialah klien gema UDP
menghantar paket ke pelayan. Dalam kes ini, pelanggan berada pada rangkaian wayarles
(10.1.3.0). Mesej kedua, "Diterima 1024 bait dari 10.1.3.3," adalah daripada gema UDP
pelayan, dijana apabila ia menerima paket gema. Mesej terakhir, "Diterima 1024
bait dari 10.1.2.4," adalah daripada klien gema, menunjukkan bahawa ia telah menerima gemanya
kembali dari pelayan.

Jika anda sekarang pergi dan melihat dalam direktori peringkat atas, anda akan menemui empat fail surih daripada
simulasi ini, dua daripada nod sifar dan dua daripada nod satu:

third-0-0.pcap third-0-1.pcap third-1-0.pcap third-1-1.pcap

Fail "third-0-0.pcap" sepadan dengan peranti titik ke titik pada nod sifar --
sebelah kiri "tulang belakang". Fail "third-1-0.pcap" sepadan dengan titik-ke-titik
peranti pada nod satu -- sebelah kanan "tulang belakang". Fail "third-0-1.pcap" akan menjadi
surih rambang (mod monitor) daripada rangkaian Wifi dan fail "third-1-1.pcap"
akan menjadi jejak rambang dari rangkaian CSMA. Bolehkah anda mengesahkan ini dengan memeriksa
kod itu?

Memandangkan klien gema berada pada rangkaian Wifi, mari kita mulakan di sana. Mari kita lihat pada
jejak rambang (mod monitor) yang kami tangkap pada rangkaian itu.

$ tcpdump -nn -tt -r ketiga-0-1.pcap

Anda sepatutnya melihat beberapa kandungan yang kelihatan seperti wifi yang anda tidak pernah lihat di sini sebelum ini:

membaca daripada fail third-0-1.pcap, jenis pautan IEEE802_11 (802.11)
0.000025 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
0.000308 Permintaan Bersekutu (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
0.000324 Acknowledgment RA:00:00:00:00:00:08
0.000402 Maklum Balas Bersekutu PERTOLONGAN(0) :: Berjaya
0.000546 Acknowledgment RA:00:00:00:00:00:0a
0.000721 Permintaan Bersekutu (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
0.000737 Acknowledgment RA:00:00:00:00:00:07
0.000824 Maklum Balas Bersekutu PERTOLONGAN(0) :: Berjaya
0.000968 Acknowledgment RA:00:00:00:00:00:0a
0.001134 Permintaan Bersekutu (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
0.001150 Acknowledgment RA:00:00:00:00:00:09
0.001273 Maklum Balas Bersekutu PERTOLONGAN(0) :: Berjaya
0.001417 Acknowledgment RA:00:00:00:00:00:0a
0.102400 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
0.204800 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
0.307200 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS

Anda boleh melihat bahawa jenis pautan kini adalah 802.11 seperti yang anda jangkakan. Anda mungkin boleh
fahami apa yang sedang berlaku dan cari permintaan gema IP dan paket tindak balas dalam ini
jejak. Kami meninggalkannya sebagai latihan untuk menghuraikan sepenuhnya pembuangan surih.

Sekarang, lihat fail pcap di sebelah kanan pautan point-to-point,

$ tcpdump -nn -tt -r ketiga-0-0.pcap

Sekali lagi, anda harus melihat beberapa kandungan yang kelihatan biasa:

membaca daripada fail third-0-0.pcap, PPP jenis pautan (PPP)
2.008151 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, panjang 1024
2.026758 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, panjang 1024

Ini ialah paket gema dari kiri ke kanan (dari Wifi ke CSMA) dan kembali lagi ke seberang
pautan titik ke titik.

Sekarang, lihat fail pcap di sebelah kanan pautan point-to-point,

$ tcpdump -nn -tt -r ketiga-1-0.pcap

Sekali lagi, anda harus melihat beberapa kandungan yang kelihatan biasa:

membaca daripada fail third-1-0.pcap, PPP jenis pautan (PPP)
2.011837 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, panjang 1024
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, panjang 1024

Ini juga merupakan paket gema dari kiri ke kanan (dari Wifi ke CSMA) dan kembali lagi
merentasi pautan titik ke titik dengan pemasaan yang sedikit berbeza seperti yang anda jangkakan.

Pelayan gema berada di rangkaian CSMA, mari lihat jejak rambang di sana:

$ tcpdump -nn -tt -r ketiga-1-1.pcap

Anda sepatutnya melihat beberapa kandungan yang kelihatan biasa:

membaca daripada fail third-1-1.pcap, jenis pautan EN10MB (Ethernet)
2.017837 ARP, Minta siapa yang mempunyai 10.1.2.4 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.1, panjang 50
2.017861 ARP, Balas 10.1.2.4 ialah-pada 00:00:00:00:00:06, panjang 50
2.017861 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, panjang 1024
2.022966 ARP, Minta siapa yang mempunyai 10.1.2.1 (ff:ff:ff:ff:ff:ff) beritahu 10.1.2.4, panjang 50
2.022966 ARP, Balas 10.1.2.1 ialah-pada 00:00:00:00:00:03, panjang 50
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, panjang 1024

Ini harus mudah difahami. Jika anda terlupa, kembali dan lihat perbincangan
in second.cc. Ini adalah urutan yang sama.

Kini, kami menghabiskan banyak masa untuk menyediakan model mobiliti untuk rangkaian wayarles dan sebagainya
memalukan untuk menyelesaikannya tanpa menunjukkan bahawa nod STA sebenarnya bergerak
sekitar semasa simulasi. Mari lakukan ini dengan menyambung ke MobilityModel kursus
tukar sumber surih. Ini hanyalah sepintas lalu ke bahagian pengesanan terperinci iaitu
akan datang, tetapi ini nampaknya tempat yang sangat bagus untuk mendapatkan contoh.

Seperti yang dinyatakan dalam bahagian "Tweaking ns-3", the ns-3 sistem pengesanan dibahagikan kepada jejak
sumber dan sinki surih, dan kami menyediakan fungsi untuk menyambungkan kedua-duanya. Kami akan menggunakan
model mobiliti mentakrifkan sumber surih tukar kursus untuk menghasilkan peristiwa surih. Kami
perlu menulis sinki surih untuk menyambung ke sumber itu yang akan memaparkan sesuatu yang cantik
maklumat untuk kita. Walaupun reputasinya sukar, ia sebenarnya agak mudah.
Sejurus sebelum program utama scratch/mythird.cc skrip (iaitu, hanya selepas
NS_LOG_COMPONENT_DEFINE pernyataan), tambah fungsi berikut:

membatalkan
CourseChange (std::konteks rentetan, Ptr model)
{
Kedudukan vektor = model->GetPosition ();
NS_LOG_UNCOND (konteks <
" x = " << kedudukan.x << ", y = " << kedudukan.y);
}

Kod ini hanya menarik maklumat kedudukan daripada model mobiliti dan tanpa syarat
merekodkan kedudukan x dan y nod. Kami akan mengaturkan fungsi ini
dipanggil setiap kali nod wayarles dengan klien gema menukar kedudukannya. Kami melakukan ini
menggunakan Konfigurasi::Sambung fungsi. Tambahkan baris kod berikut pada skrip sahaja
sebelum Simulator::Lari panggil.

std::ostringstream oss;
oss <
"/NodeList/" << wifiStaNodes.Get (nWifi - 1)->GetId () <
"/$ns3::MobilityModel/CourseChange";

Config::Connect (oss.str (), MakeCallback (&CourseChange));

Apa yang kami lakukan di sini adalah untuk mencipta rentetan yang mengandungi laluan ruang nama penjejakan acara tersebut
yang kami ingin sambungkan. Pertama, kita perlu memikirkan nod mana yang kita mahu gunakan
yang GetId kaedah seperti yang diterangkan sebelum ini. Dalam kes nombor lalai CSMA dan
nod wayarles, ini ternyata menjadi nod tujuh dan laluan ruang nama pengesanan ke
model mobiliti akan kelihatan seperti,

/NodeList/7/$ns3::MobilityModel/CourseChange

Berdasarkan perbincangan dalam bahagian pengesanan, anda boleh membuat kesimpulan bahawa laluan jejak ini
merujuk nod ketujuh dalam NodeList global. Ia menentukan apa yang dipanggil an
jenis objek agregat ns3::MobilityModel. Awalan tanda dolar membayangkan bahawa
MobilityModel diagregatkan kepada nod tujuh. Komponen terakhir laluan bermakna kita
sedang menyambung ke acara "CourseChange" model itu.

Kami membuat sambungan antara sumber surih dalam nod tujuh dengan sinki surih kami dengan memanggil
Konfigurasi::Sambung dan melepasi laluan ruang nama ini. Setelah ini dilakukan, setiap kursus berubah
peristiwa pada nod tujuh akan disambungkan ke sinki surih kami, yang seterusnya akan mencetak
kedudukan baru.

Jika anda kini menjalankan simulasi, anda akan melihat perubahan kursus dipaparkan apabila ia berlaku.

'bina' berjaya diselesaikan (5.989s)
/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
Pada masa pelanggan 2s menghantar 1024 bait ke 10.1.2.4 port 9
Pada masa pelayan 2.01796s menerima 1024 bait daripada 10.1.3.3 port 49153
Pada masa pelayan 2.01796s menghantar 1024 bait ke 10.1.3.3 port 49153
Pada masa 2.03364s pelanggan menerima 1024 bait daripada 10.1.2.4 port 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

TRACING


Latar Belakang
Seperti yang dinyatakan dalam UsingTracingSystem, keseluruhan titik menjalankan an ns-3 simulasi adalah untuk
menjana output untuk kajian. Anda mempunyai dua strategi asas untuk mendapatkan output daripada ns-3:
menggunakan mekanisme keluaran pukal pra-takrif generik dan menghuraikan kandungannya untuk diekstrak
maklumat menarik; atau entah bagaimana membangunkan mekanisme output yang menyampaikan dengan tepat
(dan mungkin sahaja) maklumat yang dikehendaki.

Menggunakan mekanisme keluaran pukal yang telah ditetapkan mempunyai kelebihan kerana tidak memerlukan sebarang perubahan
ns-3, tetapi ia mungkin memerlukan penulisan skrip untuk menghuraikan dan menapis data yang diminati. Selalunya,
PCAP atau NS_LOG mesej output dikumpulkan semasa simulasi dijalankan dan dijalankan secara berasingan
melalui skrip yang menggunakan grep, sed or awk untuk menghuraikan mesej dan mengurangkan serta mengubah
data kepada bentuk yang boleh diurus. Program mesti ditulis untuk melakukan transformasi, jadi ini
tidak datang secara percuma. NS_LOG output tidak dianggap sebagai sebahagian daripada ns-3 API, dan boleh
tukar tanpa amaran antara keluaran. Sebagai tambahan, NS_LOG output hanya tersedia dalam
debug dibina, jadi bergantung padanya mengenakan penalti prestasi. Sudah tentu, jika
maklumat yang menarik tidak wujud dalam mana-mana mekanisme keluaran yang telah ditetapkan, ini
pendekatan gagal.

Jika anda perlu menambah sedikit maklumat pada mekanisme pukal yang telah ditetapkan, ini boleh
pasti dilakukan; dan jika anda menggunakan salah satu daripada ns-3 mekanisme, anda boleh menambah kod anda
sebagai sumbangan.

ns-3 menyediakan mekanisme lain, dipanggil Tracing, yang mengelakkan beberapa masalah yang wujud
dalam mekanisme keluaran pukal. Ia mempunyai beberapa kelebihan penting. Pertama, anda boleh
kurangkan jumlah data yang anda perlu uruskan dengan hanya menjejaki peristiwa yang menarik minat anda
(untuk simulasi besar, membuang segala-galanya ke cakera untuk pemprosesan pasca boleh mencipta I/O
kesesakan). Kedua, jika anda menggunakan kaedah ini, anda boleh mengawal format output
secara langsung supaya anda mengelakkan langkah pasca pemprosesan dengan sed, awk, perl or ular sawa skrip. Jika
yang anda inginkan, output anda boleh diformat terus ke dalam bentuk yang boleh diterima oleh gnuplot, untuk
contoh (lihat juga GnuplotHelper). Anda boleh menambah cangkuk dalam teras yang kemudiannya boleh
diakses oleh pengguna lain, tetapi yang tidak akan menghasilkan maklumat melainkan diminta secara jelas
berbuat demikian. Atas sebab-sebab ini, kami percaya bahawa ns-3 sistem pengesanan adalah cara terbaik untuk mendapatkan
maklumat daripada simulasi dan oleh itu juga merupakan salah satu mekanisme yang paling penting
untuk memahami dalam ns-3.

Blunt Instrumen
Terdapat banyak cara untuk mendapatkan maklumat daripada program. Cara yang paling mudah ialah
untuk hanya mencetak maklumat terus ke output standard, seperti dalam:

#termasuk
...
membatalkan
SomeFunction (kosong)
{
uint32_t x = SOME_INTERESTING_VALUE;
...
std::cout << "Nilai x ialah " << x << std::endl;
...
}

Tiada siapa yang akan menghalang anda daripada pergi jauh ke dalam inti ns-3 dan menambah cetakan
kenyataan. Ini adalah sangat mudah untuk dilakukan dan, selepas semua, anda mempunyai kawalan sepenuhnya ke atas anda
sendiri ns-3 cawangan. Ini mungkin tidak akan menjadi sangat memuaskan dalam masa yang lama
istilah, walaupun.

Apabila bilangan penyata cetakan meningkat dalam program anda, tugas untuk menangani
sejumlah besar output akan menjadi lebih dan lebih rumit. Akhirnya, anda mungkin merasa
keperluan untuk mengawal maklumat yang sedang dicetak dalam beberapa cara, mungkin dengan menghidupkan
dan di luar kategori cetakan tertentu, atau menambah atau mengurangkan jumlah
maklumat yang anda inginkan. Jika anda meneruskan jalan ini, anda mungkin mendapati bahawa anda telah melakukannya
melaksanakan semula NS_LOG mekanisme (lihat UsingLogging). Untuk mengelakkan itu, salah satu daripada
perkara pertama yang mungkin anda pertimbangkan ialah menggunakan NS_LOG sendiri.

Kami menyebut di atas bahawa satu cara untuk mendapatkan maklumat daripadanya ns-3 adalah untuk menghuraikan sedia ada NS_LOG
output untuk maklumat yang menarik. Jika anda mendapati bahawa beberapa berita gembira maklumat anda
keperluan tidak terdapat dalam output log sedia ada, anda boleh mengedit teras ns-3 dan hanya menambah
maklumat menarik anda kepada aliran keluaran. Sekarang, ini sudah tentu lebih baik daripada
menambah penyata cetakan anda sendiri sejak ia berikut ns-3 konvensyen pengekodan dan boleh
berpotensi berguna kepada orang lain sebagai tampalan kepada teras sedia ada.

Mari kita pilih contoh rawak. Jika anda ingin menambah lebih banyak pembalakan pada ns-3 soket TCP
(tcp-socket-base.cc) anda hanya boleh menambah mesej baharu dalam pelaksanaan. Notis
bahawa dalam TcpSocketBase::ReceivedAck() tiada mesej log untuk kes tiada ACK. awak
hanya boleh menambah satu, menukar kod. Inilah yang asal:

/** Proses ACK yang baru diterima */
membatalkan
TcpSocketBase::ReceivedAck (Ptr paket, const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION (ini << tcpHeader);

// Menerima ACK. Bandingkan nombor ACK dengan seqno tidak terkunci tertinggi
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // Abaikan jika tiada bendera ACK
}
...

Untuk log kes tanpa ACK, anda boleh menambah yang baharu NS_LOG_LOGIC dalam if badan kenyataan:

/** Proses ACK yang baru diterima */
membatalkan
TcpSocketBase::ReceivedAck (Ptr paket, const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION (ini << tcpHeader);

// Menerima ACK. Bandingkan nombor ACK dengan seqno tidak terkunci tertinggi
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // Abaikan jika tiada bendera ACK
NS_LOG_LOGIC ("TcpSocketBase " << ini << " tiada bendera ACK");
}
...

Ini mungkin kelihatan agak mudah dan memuaskan pada pandangan pertama, tetapi sesuatu yang perlu dipertimbangkan adalah
bahawa anda akan menulis kod untuk ditambahkan NS_LOG kenyataan dan anda juga perlu menulis
kod (seperti dalam grep, sed or awk skrip) untuk menghuraikan output log untuk mengasingkan anda
maklumat. Ini kerana walaupun anda mempunyai sedikit kawalan ke atas apa yang dikeluarkan oleh
sistem pembalakan, anda hanya mempunyai kawalan ke peringkat komponen log, yang biasanya
keseluruhan fail kod sumber.

Jika anda menambah kod pada modul sedia ada, anda juga perlu hidup dengan output
bahawa setiap pembangun lain mendapati menarik. Anda mungkin mendapati bahawa untuk mendapatkan
sedikit maklumat yang anda perlukan, anda mungkin perlu mengharungi sejumlah besar
mesej luar yang tidak menarik minat anda. Anda mungkin terpaksa menyimpan log yang besar
fail ke cakera dan memprosesnya sehingga beberapa baris apabila anda mahu melakukan apa-apa sahaja.

Oleh kerana tiada jaminan dalam ns-3 tentang kestabilan NS_LOG output, anda juga boleh
temui kepingan keluaran log yang anda bergantung pada hilang atau bertukar antara
keluaran. Jika anda bergantung pada struktur output, anda mungkin mendapati mesej lain sedang
ditambah atau dipadamkan yang boleh menjejaskan kod penghuraian anda.

Akhirnya, NS_LOG output hanya tersedia dalam binaan nyahpepijat, anda tidak boleh mendapatkan keluaran log daripada
binaan yang dioptimumkan, yang berjalan kira-kira dua kali lebih pantas. Bersandar pada NS_LOG mengenakan prestasi
hukuman.

Atas sebab ini, kami menganggap cetakan ke std::cout and NS_LOG mesej supaya cepat dan
cara kotor untuk mendapatkan maklumat lanjut ns-3, tetapi tidak sesuai untuk kerja yang serius.

Adalah wajar untuk mempunyai kemudahan yang stabil menggunakan API yang stabil yang membolehkan seseorang mencapainya
sistem teras dan hanya mendapatkan maklumat yang diperlukan. Ia adalah wajar untuk dapat dilakukan
ini tanpa perlu mengubah dan menyusun semula sistem teras. Lebih baik lagi a
sistem yang memberitahu kod pengguna apabila item minat berubah atau acara menarik
berlaku supaya pengguna tidak perlu aktif mencari-cari dalam sistem
perkara-perkara.

. ns-3 sistem pengesanan direka bentuk untuk berfungsi mengikut garisan tersebut dan disepadukan dengan baik
Atribut dan config subsistem yang membenarkan senario penggunaan yang agak mudah.

Pengenalan
. ns-3 sistem pengesanan dibina berdasarkan konsep sumber pengesanan bebas dan
menjejak singki, bersama-sama dengan mekanisme seragam untuk menyambungkan sumber ke singki.

Sumber surih ialah entiti yang boleh memberi isyarat peristiwa yang berlaku dalam simulasi dan menyediakan
akses kepada data asas yang menarik. Sebagai contoh, sumber surih boleh menunjukkan apabila a
paket diterima oleh peranti bersih dan menyediakan akses kepada kandungan paket untuk
tenggelam jejak berminat. Sumber surih mungkin juga menunjukkan apabila keadaan menarik
perubahan berlaku dalam model. Sebagai contoh, tetingkap kesesakan model TCP adalah perdana
calon untuk sumber surih. Setiap kali tetingkap kesesakan menukar jejak bersambung
singki dimaklumkan dengan nilai lama dan baharu.

Sumber surih tidak berguna dengan sendirinya; ia mesti disambungkan kepada kepingan kod lain
yang sebenarnya melakukan sesuatu yang berguna dengan maklumat yang diberikan oleh sumber. The
entiti yang menggunakan maklumat surih dipanggil sinki surih. Sumber surih adalah
penjana data dan sinki surih adalah pengguna. Pembahagian eksplisit ini membolehkan besar
bilangan sumber surih yang akan bertaburan di sekeliling sistem di tempat-tempat yang memodelkan pengarang
percaya mungkin berguna. Memasukkan sumber surih memperkenalkan pelaksanaan yang sangat kecil
atas kepala.

Mungkin terdapat sifar atau lebih pengguna peristiwa surih yang dijana oleh sumber surih. Satu boleh
anggap sumber surih sebagai sejenis pautan maklumat titik ke berbilang titik. Kod anda
mencari peristiwa surih daripada sekeping kod teras tertentu boleh wujud bersama dengan senang hati
kod lain melakukan sesuatu yang sama sekali berbeza daripada maklumat yang sama.

Melainkan pengguna menyambungkan singki surih ke salah satu sumber ini, tiada apa yang akan dikeluarkan. Dengan menggunakan
sistem pengesanan, kedua-dua anda dan orang lain yang disambungkan ke sumber surih yang sama mendapat
apa yang mereka mahu dan hanya apa yang mereka mahu daripada sistem. Anda berdua tidak
memberi kesan kepada mana-mana pengguna lain dengan menukar maklumat yang dikeluarkan oleh sistem. Jika awak
kebetulan menambah sumber surih, kerja anda sebagai warganegara sumber terbuka yang baik mungkin membenarkan yang lain
pengguna untuk menyediakan utiliti baharu yang mungkin sangat berguna secara keseluruhan, tanpa membuat apa-apa
perubahan kepada ns-3 teras.

Mudah Contoh
Mari ambil masa beberapa minit dan lihat contoh pengesanan mudah. Kami akan memerlukan
sedikit latar belakang tentang Panggilan Balik untuk memahami apa yang berlaku dalam contoh, jadi kami
perlu mengambil lencongan kecil segera.

Panggilan balik
Matlamat sistem Panggilan Balik dalam ns-3 adalah untuk membenarkan satu keping kod untuk memanggil fungsi
(atau kaedah dalam C++) tanpa sebarang pergantungan antara modul tertentu. Ini akhirnya bermakna
anda memerlukan beberapa jenis arahan -- anda menganggap alamat fungsi yang dipanggil sebagai a
pembolehubah. Pembolehubah ini dipanggil pembolehubah penunjuk kepada fungsi. Hubungan
antara fungsi dan penunjuk-ke-fungsi sebenarnya tidak berbeza dengan objek dan
penunjuk-ke-objek.

Dalam C contoh kanonik penunjuk-ke-fungsi ialah a
pointer-to-function-returning-integer (PFI). Untuk PFI mengambil satu int parameter, ini
boleh diisytiharkan seperti,

int (*pfi)(int arg) = 0;

(Tetapi baca C++-Soalan Lazim seksyen 33 sebelum menulis kod seperti ini!) Apa yang anda dapat daripada ini
ialah pembolehubah bernama ringkas pfi yang dimulakan kepada nilai 0. Jika anda mahu
mulakan penunjuk ini kepada sesuatu yang bermakna, anda perlu mempunyai fungsi dengan a
tandatangan yang sepadan. Dalam kes ini, anda boleh menyediakan fungsi yang kelihatan seperti:

int MyFunction (int arg) {}

Jika anda mempunyai sasaran ini, anda boleh memulakan pembolehubah untuk menunjuk ke fungsi anda:

pfi = MyFunction;

Anda kemudiannya boleh menghubungi MyFunction secara tidak langsung menggunakan bentuk panggilan yang lebih tidak senonoh:

int hasil = (*pfi) (1234);

Ini tidak semena-mena kerana nampaknya anda hanya menafikan penunjuk fungsi
seperti anda akan menyahrujuk mana-mana penunjuk. Lazimnya, bagaimanapun, orang mengambil kesempatan daripada
fakta bahawa pengkompil mengetahui apa yang sedang berlaku dan hanya akan menggunakan bentuk yang lebih pendek:

int hasil = pfi (1234);

Ini kelihatan seperti anda sedang memanggil fungsi bernama pfi, tetapi pengkompil cukup bijak untuk
tahu untuk memanggil melalui pembolehubah pfi secara tidak langsung kepada fungsi tersebut MyFunction.

Dari segi konsep, ini hampir tepat bagaimana sistem pengesanan berfungsi. Pada asasnya, jejak
sink is panggilan balik. Apabila sinki surih menyatakan minat untuk menerima peristiwa surih, ia
menambah dirinya sebagai Panggilan Balik pada senarai Panggilan Balik yang dipegang secara dalaman oleh sumber surih.
Apabila peristiwa menarik berlaku, sumber surih memanggilnya pengendali(...) menyediakan
sifar atau lebih hujah. The pengendali(...) akhirnya merayau ke dalam sistem dan
melakukan sesuatu yang luar biasa seperti panggilan tidak langsung yang baru anda lihat, memberikan sifar atau lebih
parameter, sama seperti panggilan ke pfi di atas melepasi satu parameter ke fungsi sasaran
MyFunction.

Perbezaan penting yang ditambahkan oleh sistem pengesanan ialah untuk setiap sumber jejak di sana
ialah senarai dalaman Panggilan Balik. Daripada hanya membuat satu panggilan tidak langsung, jejak
sumber boleh menggunakan berbilang Panggilan Balik. Apabila sinki surih menyatakan minat terhadap
pemberitahuan daripada sumber surih, ia pada asasnya hanya mengatur untuk menambah fungsinya sendiri
senarai panggilan balik.

Jika anda berminat untuk mendapatkan butiran lanjut tentang bagaimana ini sebenarnya disusun ns-3, rasa
percuma untuk meneliti bahagian Panggilan Balik pada ns-3 Manual.

Panduan: keempat.cc
Kami telah menyediakan beberapa kod untuk melaksanakan contoh pengesanan yang paling mudah
yang boleh dipasang. Anda boleh mencari kod ini dalam direktori tutorial sebagai keempat.cc.
Mari kita jalaninya:

/* -*- Mod:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Program ini adalah perisian percuma; anda boleh mengedarkannya semula dan/atau mengubah suai
* ia di bawah terma GNU General Public License versi 2 sebagai
* diterbitkan oleh Yayasan Perisian Percuma;
*
*Program ini diedarkan dengan harapan ianya bermanfaat,
* tetapi TANPA SEBARANG WARANTI; tanpa waranti tersirat pun
* KEBOLEHPERDAGANGAN atau KESESUAIAN UNTUK TUJUAN TERTENTU. Lihat
* Lesen Awam Am GNU untuk butiran lanjut.
*
* Anda sepatutnya menerima salinan Lesen Awam Am GNU
* bersama dengan program ini; jika tidak, tulis kepada Perisian Percuma
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include "ns3/object.h"
#include "ns3/uintger.h"
#include "ns3/traced-value.h"
#include "ns3/trace-source-accessor.h"

#termasuk

menggunakan ruang nama ns3;

Kebanyakan kod ini sepatutnya biasa kepada anda. Seperti yang dinyatakan di atas, sistem jejak
menggunakan banyak sistem Objek dan Atribut, jadi anda perlu memasukkannya.
Dua yang pertama termasuk di atas membawa masuk pengisytiharan untuk sistem tersebut secara eksplisit. awak
boleh menggunakan pengepala modul teras untuk mendapatkan semuanya sekaligus, tetapi kami melakukan termasuk
secara eksplisit di sini untuk menggambarkan betapa mudahnya semua ini sebenarnya.

Fail, nilai jejak.h membawa masuk pengisytiharan yang diperlukan untuk mengesan data yang
mematuhi nilai semantik. Secara umum, nilai semantik hanya bermakna anda boleh lulus
objek itu sendiri di sekeliling, dan bukannya menghantar alamat objek. Apa ini semua sebenarnya
bermakna anda akan dapat mengesan semua perubahan yang dibuat pada TracedValue secara benar-benar
cara mudah.

Memandangkan sistem pengesanan disepadukan dengan Atribut, dan Atribut berfungsi dengan Objek,
mesti ada ns-3 Objek untuk sumber surih untuk hidup. Coretan kod seterusnya
mengisytiharkan dan mentakrifkan Objek mudah yang boleh kita kerjakan.

kelas MyObject : Objek awam
{
awam:
TypeId statik GetTypeId (kosong)
{
static TypeId tid = TypeId ("MyObject")
.SetParent (Objek::GetTypeId ())
.AddConstructor ()
.AddTraceSource ("MyInteger",
"Nilai integer untuk dikesan.",
MakeTraceSourceAccessor (&MyObject::m_myInt),
"ns3::Traced::Value::Int32Callback")
;
tid balik;
}

MyObject () {}
TracedValue m_myInt;
};

Dua baris kod penting, di atas, berkenaan dengan pengesanan ialah .AddTraceSource
dan juga TracedValue pengisytiharan mengenai m_myInt.

. .AddTraceSource menyediakan "cangkuk" yang digunakan untuk menyambungkan sumber surih ke
dunia luar melalui sistem Config. Argumen pertama ialah nama untuk jejak ini
sumber, yang menjadikannya kelihatan dalam sistem Config. Hujah kedua ialah rentetan bantuan.
Sekarang lihat hujah ketiga, sebenarnya fokus pada hujah daripada hujah ketiga:
&MyObject::m_myInt. Ini ialah TracedValue yang sedang ditambahkan pada kelas; ia adalah
sentiasa ahli data kelas. (Hujah terakhir ialah nama a mesin taip bagi
Jenis TracedValue, sebagai rentetan. Ini digunakan untuk menjana dokumentasi untuk yang betul
Tandatangan fungsi panggil balik, yang berguna terutamanya untuk jenis yang lebih umum
Panggilan balik.)

. TracedValue<> pengisytiharan menyediakan infrastruktur yang mendorong panggilan balik
proses. Bila-bila masa nilai asas ditukar, mekanisme TracedValue akan disediakan
kedua-dua nilai lama dan baharu bagi pembolehubah itu, dalam kes ini an int32_t nilai. Jejak itu
fungsi sink untuk TracedValue ini memerlukan tandatangan

void (* TracedValueCallback)(const int32_t oldValue, const int32_t newValue);

Semua sinki surih yang mengaitkan sumber surih ini mesti mempunyai tandatangan ini. Kami akan membincangkan di bawah
bagaimana anda boleh menentukan tandatangan panggil balik yang diperlukan dalam kes lain.

Sudah tentu, meneruskan keempat.cc kita lihat:

membatalkan
IntTrace (int32_t oldValue, int32_t newValue)
{
std::cout << "Dijejaki "<< oldValue << " hingga " << newValue << std::endl;
}

Ini ialah definisi sinki surih yang sepadan. Ia sepadan terus dengan panggilan balik
tandatangan fungsi. Sebaik sahaja ia disambungkan, fungsi ini akan dipanggil pada bila-bila masa
TracedValue perubahan.

Kami kini telah melihat punca surih dan sinki surih. Apa yang tinggal ialah kod untuk menyambungkan
sumber kepada singki, yang berlaku di utama:

int
utama (int argc, char *argv[])
{
Ptr myObject = CreateObject ();
myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace));

myObject->m_myInt = 1234;
}

Di sini kita mula-mula mencipta contoh MyObject di mana sumber surih hidup.

Langkah seterusnya, iaitu TraceConnectTanpaKonteks, membentuk hubungan antara surih
sumber dan sinki surih. Argumen pertama hanyalah nama sumber surih "MyInteger"
kita lihat di atas. Perhatikan MakeCallback fungsi templat. Fungsi ini melakukan keajaiban
diperlukan untuk mencipta asas ns-3 Objek panggil balik dan kaitkan dengan fungsi
IntTrace. TraceConnect membuat perkaitan antara fungsi yang anda sediakan dan
terlalu banyak pengendali() dalam pembolehubah yang dikesan yang dirujuk oleh Atribut "MyInteger".
Selepas perkaitan ini dibuat, sumber surih akan "mematikan" panggilan balik yang anda berikan
fungsi.

Kod untuk membuat semua ini berlaku, sudah tentu, bukan remeh, tetapi intipatinya adalah itu
anda sedang mengatur sesuatu yang kelihatan seperti pfi() contoh di atas untuk dipanggil
oleh sumber surih. Pengisytiharan daripada TracedValue m_myInt; dalam Objek
sendiri melakukan keajaiban yang diperlukan untuk menyediakan pengendali tugasan terlebih beban yang akan
menggunakan pengendali() untuk benar-benar menggunakan Panggilan Balik dengan parameter yang dikehendaki. The
.AddTraceSource melakukan keajaiban untuk menyambungkan Panggilan Balik ke sistem Konfig, dan
TraceConnectTanpaKonteks melakukan keajaiban untuk menyambungkan fungsi anda kepada jejak
sumber, yang ditentukan oleh nama Atribut.

Mari kita abaikan sedikit tentang konteks buat masa ini.

Akhir sekali, baris yang memberikan nilai kepada m_myInt:

myObject->m_myInt = 1234;

hendaklah ditafsirkan sebagai seruan kepada operator= pada pembolehubah ahli m_myInt bersama
bilangan bulat 1234 diluluskan sebagai parameter.

Sejak m_myInt ialah TracedValue, operator ini ditakrifkan untuk melaksanakan panggilan balik yang
mengembalikan batal dan mengambil dua nilai integer sebagai parameter --- nilai lama dan nilai baharu
untuk integer yang dimaksudkan. Itulah sebenarnya tandatangan fungsi untuk panggilan balik
fungsi yang kami sediakan --- IntTrace.

Untuk meringkaskan, sumber surih adalah, pada dasarnya, pembolehubah yang memegang senarai panggilan balik. A
sinki surih ialah fungsi yang digunakan sebagai sasaran panggilan balik. Jenis Atribut dan objek
sistem maklumat digunakan untuk menyediakan cara untuk menyambungkan sumber surih kepada singki surih.
Tindakan "memukul" sumber surih sedang melaksanakan pengendali pada sumber surih yang
melancarkan panggilan balik. Ini mengakibatkan panggilan balik sinki surih yang mendaftar minat dalam
sumber dipanggil dengan parameter yang disediakan oleh sumber.

Jika anda kini membina dan menjalankan contoh ini,

$ ./waf --run keempat

anda akan melihat output daripada IntTrace berfungsi laksana sebaik sahaja sumber surih
pukul:

Dijejaki 0 ​​hingga 1234

Apabila kami melaksanakan kod itu, myObject->m_myInt = 1234;, sumber surih dipecat dan
secara automatik memberikan nilai sebelum dan selepas kepada sinki surih. Fungsinya
IntTrace kemudian mencetak ini ke output standard.

Hubungi bersama config
. TraceConnectTanpaKonteks panggilan yang ditunjukkan di atas dalam contoh mudah sebenarnya sangat
jarang digunakan dalam sistem. Lebih lazimnya, config subsistem digunakan untuk memilih surih
sumber dalam sistem menggunakan apa yang dipanggil a config jalan. Kami melihat contoh ini dalam
bahagian sebelumnya di mana kami mengaitkan acara "CourseChange" semasa kami membuat percubaan
ketiga.cc.

Ingat bahawa kami menentukan sinki surih untuk mencetak maklumat perubahan kursus daripada mobiliti
model simulasi kami. Ia kini sepatutnya menjadi lebih jelas kepada anda apakah fungsi ini
melakukan:

membatalkan
CourseChange (std::konteks rentetan, Ptr model)
{
Kedudukan vektor = model->GetPosition ();
NS_LOG_UNCOND (konteks <
" x = " << kedudukan.x << ", y = " << kedudukan.y);
}

Apabila kami menyambungkan sumber surih "CourseChange" ke sinki surih di atas, kami menggunakan a
Laluan konfigurasi untuk menentukan sumber apabila kami mengatur sambungan antara yang telah ditetapkan
sumber surih dan sinki surih baharu:

std::ostringstream oss;
oss << "/NodeList/"
<< wifiStaNodes.Get (nWifi - 1)->GetId ()
<< "/$ns3::MobilityModel/CourseChange";

Config::Connect (oss.str (), MakeCallback (&CourseChange));

Mari cuba dan fahami apa yang kadangkala dianggap sebagai kod yang agak misteri.
Untuk tujuan perbincangan, anggap bahawa nombor Nod dikembalikan oleh GetId() is
"7". Dalam kes ini, laluan di atas ternyata

"/NodeList/7/$ns3::MobilityModel/CourseChange"

Segmen terakhir laluan konfigurasi mestilah a atribut daripada Objek. Malah, jika anda mempunyai
penunjuk kepada Objek yang mempunyai "CourseChange" atribut berguna, anda boleh menulis ini
sama seperti yang kita lakukan dalam contoh sebelumnya. Anda tahu sekarang bahawa kami biasanya menyimpan
petunjuk kepada kami Nod dalam NodeContainer. Di dalam ketiga.cc contoh, Nod yang diminati
disimpan di dalam wifiStaNodes NodeContainer. Malah, semasa meletakkan jalan bersama-sama,
kami menggunakan bekas ini untuk mendapatkan a Ptr yang biasa kami panggil GetId(). Kita boleh ada
menggunakan ini Ptr untuk memanggil kaedah Sambung secara langsung:

Ptr theObject = wifiStaNodes.Get (nWifi - 1);
theObject->TraceConnectWithoutContext ("CourseChange", MakeCallback (&CourseChange));

Dalam ketiga.cc contoh, kami sebenarnya mahukan "konteks" tambahan dihantar bersama
dengan parameter Panggilan Balik (yang akan diterangkan di bawah) supaya kami sebenarnya boleh menggunakan
kod setara berikut:

Ptr theObject = wifiStaNodes.Get (nWifi - 1);
theObject->TraceConnect ("CourseChange", MakeCallback (&CourseChange));

Ternyata kod dalaman untuk Config::ConnectWithoutContext and Konfigurasi::Sambung
sebenarnya mencari a Ptr dan panggil yang sesuai TraceConnect kaedah paling rendah
peringkat.

. config fungsi mengambil laluan yang mewakili rantaian Objek petunjuk. Setiap segmen
laluan sepadan dengan Atribut Objek. Segmen terakhir ialah Atribut bagi
minat, dan segmen sebelumnya mesti ditaip untuk mengandungi atau mencari Objek. The config kod
menghuraikan dan "menjalani" laluan ini sehingga ia sampai ke segmen akhir laluan. Ia kemudian
mentafsirkan segmen terakhir sebagai atribut pada Objek terakhir yang ditemuinya semasa berjalan di
laluan. The config fungsi kemudian panggil yang sesuai TraceConnect or
TraceConnectTanpaKonteks kaedah pada Objek akhir. Mari lihat apa yang berlaku sebentar lagi
lebih terperinci apabila laluan di atas dilalui.

Watak "/" utama dalam laluan merujuk kepada ruang nama yang dipanggil. Salah satu daripada
ruang nama yang dipratentukan dalam sistem konfigurasi ialah "NodeList" yang merupakan senarai semua
nod dalam simulasi. Item dalam senarai dirujuk oleh indeks ke dalam senarai, jadi
"/NodeList/7" merujuk kepada Nod kelapan dalam senarai nod yang dibuat semasa simulasi
(indeks ingat bermula pada 0'). ini rujukan is sebenarnya a ``Ptr ` dan begitu juga a
subkelas an ns3::Objek.

Seperti yang diterangkan dalam bahagian Model Objek dalam ns-3 Manual, kami menggunakan secara meluas
pengagregatan objek. Ini membolehkan kita membentuk persatuan antara Objek yang berbeza
tanpa membina pokok warisan yang rumit atau mendahului objek yang akan menjadi bahagian
daripada Nod. Setiap Objek dalam Pengagregatan boleh dicapai daripada Objek lain.

Dalam contoh kami segmen laluan seterusnya yang dilalui bermula dengan aksara "$". ini
menunjukkan kepada sistem konfigurasi bahawa segmen adalah nama jenis objek, jadi a
GetObject panggilan harus dibuat mencari jenis itu. Ternyata bahawa MobilityHelper
digunakan dalam ketiga.cc mengatur kepada Agregat, atau mengaitkan, model mobiliti kepada setiap satu
wayarles Nod. Apabila anda menambah "$" anda meminta Objek lain yang mempunyai
mungkin telah diagregatkan sebelum ini. Anda boleh menganggap ini sebagai menukar petunjuk daripada
Ptr yang asal seperti yang ditentukan oleh "/NodeList/7" kepada model mobiliti yang berkaitan ---
yang jenis ns3::MobilityModel. Jika anda biasa dengan GetObject, kami telah bertanya
sistem untuk melakukan perkara berikut:

Ptr mobilitiModel = nod->GetObject ()

Kami kini berada di Objek terakhir dalam laluan, jadi kami mengalihkan perhatian kami kepada Atribut
Objek itu. The MobilityModel kelas mentakrifkan Atribut yang dipanggil "CourseChange". Awak boleh
lihat ini dengan melihat kod sumber dalam src/mobiliti/model/mobiliti-model.cc and
mencari "CourseChange" dalam editor kegemaran anda. Awak patut cari

.AddTraceSource ("CourseChange",
"Nilai kedudukan dan/atau vektor halaju berubah",
MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace),
"ns3::MobilityModel::CourseChangeCallback")

yang sepatutnya kelihatan sangat biasa pada ketika ini.

Jika anda mencari pengisytiharan yang sepadan bagi pembolehubah yang dikesan asas dalam
model mobiliti.h anda akan mendapati

TracedCallback > m_courseChangeTrace;

Pengisytiharan jenis TracedCallback mengenal pasti m_courseChangeTrace sebagai senarai khas
Panggilan balik yang boleh disambungkan menggunakan fungsi Config yang diterangkan di atas. The mesin taip khususnya
tandatangan fungsi panggil balik juga ditakrifkan dalam fail pengepala:

typedef void (* CourseChangeCallback)(Ptr * model);

. MobilityModel kelas direka bentuk untuk menjadi kelas asas yang menyediakan antara muka biasa untuk
semua subkelas tertentu. Jika anda mencari sehingga hujung fail, anda akan melihat a
kaedah yang ditakrifkan dipanggil NotifyCourseChange():

membatalkan
MobilityModel::NotifyCourseChange (kosong) const
{
m_courseChangeTrace(ini);
}

Kelas terbitan akan memanggil kaedah ini apabila mereka melakukan pertukaran kursus untuk menyokong
menjejak. Kaedah ini menyeru pengendali() pada asas m_courseChangeTrace, Yang
akan, pada gilirannya, menggunakan semua Panggilan Balik yang didaftarkan, memanggil semua surih itu menyekat itu
telah mendaftarkan minat dalam sumber surih dengan memanggil fungsi Config.

Jadi, dalam ketiga.cc contoh yang kita lihat, apabila perubahan kursus dibuat dalam salah satu
RandomWalk2dMobilityModel instance dipasang, akan ada a NotifyCourseChange() memanggil
yang menyeru ke dalam MobilityModel kelas asas. Seperti yang dilihat di atas, ini memanggil pengendali()
on m_courseChangeTrace, yang seterusnya, memanggil mana-mana sinki surih berdaftar. Dalam contoh,
satu-satunya kod yang mendaftar minat ialah kod yang menyediakan laluan Config.
Oleh itu, Tukar Kursus fungsi yang disambungkan dari Nod nombor tujuh akan menjadi
hanya Panggilan Balik yang dipanggil.

Bahagian akhir teka-teki ialah "konteks". Ingat bahawa kami melihat keluaran kelihatan
sesuatu seperti berikut dari ketiga.cc:

/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.27897, y =
2.22677

Bahagian pertama output ialah konteks. Ia hanyalah jalan yang melaluinya
kod konfigurasi terletak sumber surih. Dalam kes yang kita telah melihat mungkin ada
sebarang bilangan sumber surih dalam sistem yang sepadan dengan sebarang bilangan nod dengan
model mobiliti. Perlu ada beberapa cara untuk mengenal pasti sumber surih yang sebenarnya
yang mencetuskan Panggilan Balik. Cara mudah adalah untuk berhubung dengan Konfigurasi::Sambung, sebaliknya
of Config::ConnectWithoutContext.

Mencari Sumber
Soalan pertama yang pasti timbul untuk pengguna baharu sistem Pengesanan ialah, "Baik,
I Tahu Bahawa terdapat kemestian be mengesan sumber in yang simulasi teras, tetapi bagaimana do I mencari keluar apa
mengesan sumber adalah tersedia kepada saya?"

Soalan kedua ialah, "Baik, I ditemui a mengesan sumber, bagaimana do I memikirkan keluar yang config jalan
kepada penggunaan apabila I menyambung kepada ia?"

Soalan ketiga ialah, "Baik, I ditemui a mengesan sumber and yang config jalan, bagaimana do I memikirkan
keluar apa yang pulangan jenis and formal hujah of my panggil balik fungsi perlu kepada menjadi?"

Soalan keempat ialah, "Baik, I ditaip Bahawa semua in and mendapat ini sangat luar biasa pelik kesilapan
mesej, apa in yang dunia tidak it maksudnya?"

Kami akan menangani setiap perkara ini secara bergilir.

Boleh didapati Sumber
okay, I Tahu Bahawa terdapat kemestian be mengesan sumber in yang simulasi teras, tetapi bagaimana do I mencari
keluar apa mengesan sumber adalah tersedia kepada saya?

Jawapan kepada soalan pertama terdapat dalam ns-3 dokumentasi API. Jika anda pergi ke
laman web projek, ns-3 projek, anda akan menemui pautan ke "Dokumentasi" dalam navigasi
bar. Jika anda memilih pautan ini, anda akan dibawa ke halaman dokumentasi kami. Ada
pautan ke "Keluaran Terkini" yang akan membawa anda ke dokumentasi untuk kandang terbaharu
pelepasan ns-3. Jika anda memilih pautan "Dokumentasi API", anda akan dibawa ke
ns-3 halaman dokumentasi API.

Di bar sisi anda sepatutnya melihat hierarki yang bermula

· ns-3

· ns-3 Dokumentasi

· Semua TraceSources

· Semua Atribut

· Semua Nilai Global

Senarai minat kami di sini ialah "Semua Sumber Jejak". Teruskan dan pilih pautan itu.
Anda akan melihat, mungkin tidak terlalu mengejutkan, senarai semua sumber surih yang tersedia
in ns-3.

Sebagai contoh, tatal ke bawah ke ns3::MobilityModel. Anda akan menemui entri untuk

CourseChange: Nilai kedudukan dan/atau vektor halaju berubah

Anda harus mengenali ini sebagai sumber surih yang kami gunakan dalam ketiga.cc contoh. merenung
senarai ini akan membantu.

config Laluan
okay, I ditemui a mengesan sumber, bagaimana do I memikirkan keluar yang config jalan kepada penggunaan apabila I menyambung kepada
ia?

Jika anda tahu objek yang anda minati, bahagian "Penerangan Terperinci" untuk
kelas akan menyenaraikan semua sumber surih yang tersedia. Contohnya, bermula daripada senarai "Semua
TraceSources," klik pada ns3::MobilityModel pautan, yang akan membawa anda ke
dokumentasi untuk MobilityModel kelas. Hampir di bahagian atas halaman adalah satu baris
penerangan ringkas tentang kelas, berakhir dengan pautan "Lagi...". Klik pada pautan ini untuk melangkau
ringkasan API dan pergi ke "Penerangan Terperinci" kelas. Pada penghujung
perihalan akan menjadi (sehingga) tiga senarai:

· config Laluan: senarai laluan Config biasa untuk kelas ini.

· Atribut: senarai semua atribut yang dibekalkan oleh kelas ini.

· TraceSources: senarai semua TraceSources yang tersedia daripada kelas ini.

Mula-mula kita akan membincangkan laluan Config.

Mari kita anggap bahawa anda baru sahaja menemui sumber surih "CourseChange" dalam "Semua
TraceSources" dan anda ingin memikirkan cara untuk menyambung kepadanya. Anda tahu bahawa anda begitu
menggunakan (sekali lagi, daripada ketiga.cc contoh) an ns3::RandomWalk2dMobilityModel. Jadi sama ada
klik pada nama kelas dalam senarai "All TraceSources", atau cari
ns3::RandomWalk2dMobilityModel dalam "Senarai Kelas". Sama ada cara anda sekarang harus mencari
di halaman "ns3::RandomWalk2dMobilityModel Class Rujukan".

Jika anda kini tatal ke bawah ke bahagian "Perihalan Terperinci", selepas senarai ringkasan
kaedah dan atribut kelas (atau hanya klik pada pautan "Lagi..." di penghujung kelas
penerangan ringkas di bahagian atas halaman) anda akan melihat dokumentasi keseluruhan untuk
kelas. Meneruskan tatal ke bawah, cari senarai "Laluan Konfig":
config Laluan

ns3::RandomWalk2dMobilityModel boleh diakses melalui laluan berikut dengan
Konfigurasi::Tetapkan and Konfigurasi::Sambung:

· "/NodeList/[i]/$ns3::MobilityModel/$ns3::RandomWalk2dMobilityModel"

Dokumentasi memberitahu anda cara untuk pergi ke RandomWalk2dMobilityModel Objek. Bandingkan
rentetan di atas dengan rentetan yang sebenarnya kami gunakan dalam kod contoh:

"/NodeList/7/$ns3::MobilityModel"

Perbezaannya adalah disebabkan oleh fakta bahawa dua GetObject panggilan tersirat dalam rentetan yang ditemui
dalam dokumentasi. Yang pertama, untuk $ns3::MobilityModel akan menanyakan pengagregatan untuk
kelas asas. Yang kedua tersirat GetObject memanggil $ns3::RandomWalk2dMobilityModel,
digunakan untuk menghantar kelas asas kepada kelas pelaksanaan konkrit. Dokumentasi
menunjukkan kedua-dua operasi ini untuk anda. Ternyata sumber surih sebenar anda adalah
mencari ditemui dalam kelas asas.

Lihat lebih jauh ke bawah dalam bahagian "Perihalan Terperinci" untuk senarai sumber surih.
Anda akan mendapati
Tiada TraceSources ditakrifkan untuk jenis ini.

TraceSources ditakrifkan in ibu bapa kelas ``ns3::MobilityModel``

· Tukar Kursus: Nilai kedudukan dan/atau vektor halaju berubah.

Tandatangan panggilan balik: ns3::MobilityModel::CourseChangeCallback

Inilah sebenarnya yang anda perlu tahu. Sumber surih minat ditemui dalam
ns3::MobilityModel (yang anda tahu pula). Perkara yang menarik tentang API ini
Dokumentasi memberitahu anda bahawa anda tidak memerlukan cast tambahan dalam laluan konfigurasi di atas
pergi ke kelas konkrit, kerana sumber surih sebenarnya dalam kelas asas.
Oleh itu tambahan GetObject tidak diperlukan dan anda hanya menggunakan laluan:

"/NodeList/[i]/$ns3::MobilityModel"

yang sangat sepadan dengan laluan contoh:

"/NodeList/7/$ns3::MobilityModel"

Di samping itu, cara lain untuk mencari laluan Config adalah dengan grep sekitar di ns-3 asas kod
untuk seseorang yang sudah mengetahuinya. Anda harus sentiasa cuba meniru orang lain
kod kerja sebelum anda mula menulis sendiri. Cuba sesuatu seperti:

$ cari . -nama '*.cc' | xargs grep CourseChange | grep Sambung

dan anda mungkin menemui jawapan anda bersama kod kerja. Sebagai contoh, dalam kes ini,
src/mobiliti/contoh/topologi-rawak-utama.cc mempunyai sesuatu yang hanya menunggu untuk anda gunakan:

Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange",
MakeCallback (&CourseChange));

Kami akan kembali kepada contoh ini sebentar lagi.

Panggil balik Tandatangan
okay, I ditemui a mengesan sumber and yang config jalan, bagaimana do I memikirkan keluar apa yang pulangan jenis
and formal hujah of my panggil balik fungsi perlu kepada boleh?

Cara paling mudah ialah memeriksa tandatangan panggil balik mesin taip, yang diberikan dalam
"Tandatangan panggilan balik" sumber surih dalam "Perihalan Terperinci" untuk kelas, sebagai
ditunjukkan di atas.

Mengulangi entri sumber surih "CourseChange" daripada ns3::RandomWalk2dMobilityModel we
mempunyai:

· Tukar Kursus: Nilai kedudukan dan/atau vektor halaju berubah.

Tandatangan panggilan balik: ns3::MobilityModel::CourseChangeCallback

Tandatangan panggilan balik diberikan sebagai pautan kepada yang berkaitan mesin taip, di mana kita dapati
mesin taip membatalkan (* CourseChangeCallback)(const std :: tali konteks, Ptr
MobilityModel> * model);

TracedCallback tandatangan untuk pemberitahuan pertukaran kursus.

Jika panggilan balik disambungkan menggunakan SambungTanpaKonteks tinggalkan konteks hujah dari
tandatangan.

Parameter:
[dalam] konteks Rentetan konteks yang dibekalkan oleh sumber Surih.
[dalam] model The MobilityModel yang sedang mengubah haluan.

Seperti di atas, untuk melihat ini digunakan grep sekitar di ns-3 asas kod untuk contoh. Contoh
di atas, daripada src/mobiliti/contoh/topologi-rawak-utama.cc, menghubungkan "CourseChange"
jejak sumber ke Tukar Kursus fungsi dalam fail yang sama:

kekosongan statik
CourseChange (std::konteks rentetan, Ptr model)
{
...
}

Perhatikan bahawa fungsi ini:

· Mengambil hujah rentetan "konteks", yang akan kami huraikan dalam satu minit. (Jika panggilan balik
disambungkan menggunakan SambungTanpaKonteks berfungsi yang konteks hujah akan menjadi
ditinggalkan.)

· Mempunyai MobilityModel dibekalkan sebagai hujah terakhir (atau hanya hujah jika
SambungTanpaKonteks digunakan).

· Pemulangan membatalkan.

Jika, secara kebetulan, tandatangan panggil balik belum didokumenkan dan tiada contoh untuknya
bekerja daripada, menentukan tandatangan fungsi panggil balik yang betul boleh, baik, mencabar
sebenarnya mengetahui dari kod sumber.

Sebelum memulakan langkah melalui kod, saya akan berbaik hati dan hanya memberitahu anda cara yang mudah
untuk memikirkan perkara ini: Nilai pulangan panggilan balik anda akan sentiasa membatalkan. Yang formal
senarai parameter untuk a TracedCallback boleh didapati daripada senarai parameter templat dalam
pengisytiharan. Ingat bahawa untuk contoh semasa kami, ini adalah dalam model mobiliti.h, dimana kita
pernah menemui:

TracedCallback > m_courseChangeTrace;

Terdapat surat-menyurat satu dengan satu antara senarai parameter templat dalam
pengisytiharan dan hujah rasmi fungsi panggil balik. Di sini, ada satu
parameter templat, iaitu a Ptr MobilityModel>. Ini memberitahu anda bahawa anda memerlukan a
fungsi yang mengembalikan batal dan mengambil a Ptr MobilityModel>. Sebagai contoh:

membatalkan
Tukar Kursus (Ptr model)
{
...
}

Itu sahaja yang anda perlukan jika anda mahu Config::ConnectWithoutContext. Jika anda mahukan konteks,
anda perlu Konfigurasi::Sambung dan gunakan fungsi Panggilan Balik yang mengambil konteks rentetan, kemudian
hujah templat:

membatalkan
CourseChange (const std::string context, Ptr model)
{
...
}

Jika anda ingin memastikan bahawa anda CourseChangeCallback fungsi hanya boleh dilihat dalam anda
fail tempatan, anda boleh menambah kata kunci statik dan datang dengan:

kekosongan statik
CourseChange (const std::string path, Ptr model)
{
...
}

yang betul-betul apa yang kami gunakan dalam ketiga.cc contohnya.

Pelaksanaan
Bahagian ini adalah pilihan sepenuhnya. Ia akan menjadi perjalanan yang sukar, terutamanya bagi mereka
tidak biasa dengan butiran templat. Walau bagaimanapun, jika anda melalui ini, anda akan mempunyai
pemegang yang sangat baik pada banyak ns-3 simpulan bahasa peringkat rendah.

Jadi, sekali lagi, mari kita fikirkan tandatangan fungsi panggil balik yang diperlukan untuk
Sumber surih "CourseChange". Ini akan menyakitkan, tetapi anda hanya perlu melakukan ini
sekali. Selepas anda melalui ini, anda akan dapat melihat a TracedCallback and
fahamkan ia.

Perkara pertama yang perlu kita lihat ialah pengisytiharan sumber surih. Ingat itu
ini dalam model mobiliti.h, di mana kami pernah menemui:

TracedCallback > m_courseChangeTrace;

Pengisytiharan ini adalah untuk templat. Parameter templat berada di dalam kurungan sudut,
jadi kami sangat berminat untuk mengetahui apa itu TracedCallback<> ialah. Jika anda mempunyai
sama sekali tidak tahu di mana ini mungkin ditemui, grep adalah kawan anda.

Kami mungkin akan berminat dengan beberapa jenis pengisytiharan dalam ns-3 sumber, jadi
pertama bertukar menjadi src direktori. Kemudian, kita tahu pengisytiharan ini perlu
berada dalam beberapa jenis fail pengepala, jadi hanya grep untuknya menggunakan:

$ cari . -nama '*.h' | xargs grep TracedCallback

Anda akan melihat 303 baris berlalu (saya menyalurkannya wc untuk melihat betapa teruknya itu). walaupun
itu mungkin kelihatan seperti banyak, itu tidak terlalu banyak. Hanya paip output melalui lebih and
mula mengimbas melaluinya. Pada halaman pertama, anda akan melihat beberapa yang sangat mencurigakan
barangan yang kelihatan templat.

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 ...

Ternyata semua ini datang dari fail pengepala traced-callback.h yang berbunyi
sangat menjanjikan. Anda kemudian boleh melihat model mobiliti.h dan lihat ada garisan
yang mengesahkan firasat ini:

#include "ns3/traced-callback.h"

Sudah tentu, anda boleh pergi ke arah ini dari arah lain dan mulakan dengan melihat
termasuk dalam model mobiliti.h dan perasan termasuk daripada traced-callback.h and
membuat kesimpulan bahawa ini mestilah fail yang anda mahukan.

Dalam kedua-dua kes, langkah seterusnya adalah untuk melihat src/core/model/traced-callback.h in
editor kegemaran anda untuk melihat apa yang berlaku.

Anda akan melihat ulasan di bahagian atas fail yang sepatutnya menghiburkan:
ns3::TracedCallback mempunyai API yang hampir sama dengan ns3::Panggil balik biasa tetapi
bukannya memajukan panggilan ke satu fungsi (seperti yang biasa dilakukan oleh ns3::Panggil balik),
ia memajukan panggilan ke rangkaian ns3::Panggil balik.

Ini sepatutnya terdengar sangat biasa dan memberitahu anda bahawa anda berada di landasan yang betul.

Hanya selepas komen ini, anda akan dapati

templat
nama taip T3 = kosong, nama taip T4 = kosong,
nama taip T5 = kosong, nama taip T6 = kosong,
nama taip T7 = kosong, nama taip T8 = kosong>
kelas TracedCallback
{
...

Ini memberitahu anda bahawa TracedCallback ialah kelas templat. Ia mempunyai lapan jenis yang mungkin
parameter dengan nilai lalai. Kembali dan bandingkan ini dengan pengisytiharan anda
cuba memahami:

TracedCallback > m_courseChangeTrace;

. nama taip T1 dalam perisytiharan kelas templat sepadan dengan Ptr
MobilityModel> dalam pengisytiharan di atas. Semua parameter jenis lain dibiarkan sebagai
lalai. Melihat pembina benar-benar tidak memberitahu anda banyak. Satu tempat di mana
anda telah melihat sambungan dibuat antara fungsi Panggilan Balik anda dan sistem pengesanan
dalam Hubungi and SambungTanpaKonteks fungsi. Jika anda tatal ke bawah, anda akan melihat a
SambungTanpaKonteks kaedah di sini:

templat
nama taip T3, nama taip T4,
nama taip T5, nama taip T6,
nama taip T7, nama taip T8>
membatalkan
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext ...
{
Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> cb;
cb.Assign (panggilan balik);
m_callbackList.push_back (cb);
}

Anda kini berada di dalam perut binatang itu. Apabila templat dijadikan instantiated untuk
pengisytiharan di atas, pengkompil akan menggantikan T1 bersama Ptr MobilityModel>.

membatalkan
TracedCallback ::SambungTanpaKonteks ... cb
{
Panggilan balik > cb;
cb.Assign (panggilan balik);
m_callbackList.push_back (cb);
}

Anda kini boleh melihat pelaksanaan semua yang telah kami bincangkan. Kod itu
mencipta Panggilan Balik jenis yang betul dan memberikan fungsi anda kepadanya. Ini adalah
setara dengan pfi = MyFunction kami bincangkan pada permulaan bahagian ini. Kod itu
kemudian menambah Panggilan Balik pada senarai Panggilan Balik untuk sumber ini. Yang tinggal hanyalah
untuk melihat definisi Panggilan Balik. Menggunakan yang sama grep muslihat seperti yang biasa kita temui
TracedCallback, anda akan dapat mencari bahawa fail ./core/callback.h ialah kita
perlu tengok.

Jika anda melihat ke bawah melalui fail, anda akan melihat banyak perkara yang mungkin hampir tidak dapat difahami
kod templat. Anda akhirnya akan datang ke beberapa Dokumentasi API untuk Panggilan Balik
kelas templat, walaupun. Nasib baik, terdapat beberapa bahasa Inggeris:
Panggil balik kelas templat.

Templat kelas ini melaksanakan Corak Reka Bentuk Functor. Ia digunakan untuk mengisytiharkan
jenis a Panggil balik:

· argumen templat bukan pilihan pertama mewakili jenis pemulangan panggilan balik.

· argumen templat yang tinggal (pilihan) mewakili jenis yang berikutnya
hujah kepada panggilan balik.

· sehingga sembilan hujah disokong.

Kami cuba memikirkan apa yang

Panggilan balik > cb;

pengisytiharan bermaksud. Kini kami berada dalam kedudukan untuk memahami bahawa yang pertama (bukan pilihan)
hujah templat, membatalkan, mewakili jenis pemulangan Panggilan Balik. Yang kedua
hujah templat (pilihan), Ptr MobilityModel> mewakili jenis yang pertama
hujah kepada panggilan balik.

Panggilan Balik yang dimaksudkan ialah fungsi anda untuk menerima peristiwa surih. Daripada ini anda boleh
membuat kesimpulan bahawa anda memerlukan fungsi yang kembali membatalkan dan mengambil a Ptr MobilityModel>.
Sebagai contoh,

membatalkan
CourseChangeCallback (Ptr model)
{
...
}

Itu sahaja yang anda perlukan jika anda mahu Config::ConnectWithoutContext. Jika anda mahukan konteks,
anda perlu Konfigurasi::Sambung dan gunakan fungsi Panggilan Balik yang mengambil konteks rentetan. ini
adalah kerana Hubungi fungsi akan menyediakan konteks untuk anda. Anda perlukan:

membatalkan
CourseChangeCallback (std::konteks rentetan, Ptr model)
{
...
}

Jika anda ingin memastikan bahawa anda CourseChangeCallback hanya kelihatan dalam fail tempatan anda,
anda boleh menambah kata kunci statik dan datang dengan:

kekosongan statik
CourseChangeCallback (std::string path, Ptr model)
{
...
}

yang betul-betul apa yang kami gunakan dalam ketiga.cc contoh. Mungkin sekarang anda patut kembali dan
baca semula bahagian sebelumnya (Take My Word for It).

Jika anda berminat untuk mendapatkan butiran lanjut mengenai pelaksanaan Panggilan Balik, sila bebas
untuk melihat pada ns-3 manual. Ia adalah salah satu binaan yang paling kerap digunakan dalam
bahagian aras rendah daripada ns-3. Ia, pada pendapat saya, satu perkara yang agak elegan.

TracedValues
Terdahulu dalam bahagian ini, kami membentangkan sekeping kod ringkas yang menggunakan a
TracedValue untuk menunjukkan asas kod pengesanan. Kami hanya berpura-pura
apa sebenarnya TracedValue dan cara mencari jenis pulangan dan hujah formal
panggilan balik.

Seperti yang kami nyatakan, fail, nilai jejak.h membawa masuk pengisytiharan yang diperlukan untuk mengesan
data yang mematuhi nilai semantik. Secara umum, nilai semantik hanya bermakna anda boleh
lulus objek itu sendiri di sekeliling, dan bukannya menghantar alamat objek. Kami panjangkan
keperluan itu untuk memasukkan set penuh pengendali gaya tugasan yang
pratakrif untuk jenis data lama biasa (POD):

-
operator= (tugasan) │ │
├────────────────────────────────────────────────—․
pengendali*=pengendali/=
├────────────────────────────────────────────────—․
operator+=pengendali-=
├────────────────────────────────────────────────—․
pengendali++ (kedua-dua awalan dan │ │
│postfix) │ │
├────────────────────────────────────────────────—․
pengendali-- (kedua-dua awalan dan │ │
│postfix) │ │
├────────────────────────────────────────────────—․
pengendali<<=pengendali>>=
├────────────────────────────────────────────────—․
pengendali&=pengendali|=
├────────────────────────────────────────────────—․
operator%=pengendali^=
└───────────────────────────────────────────────—‴───‴

Maksud semua ini sebenarnya ialah anda akan dapat mengesan semua perubahan yang dibuat menggunakan perubahan tersebut
operator kepada objek C++ yang mempunyai nilai semantik.

. TracedValue<> pengisytiharan yang kita lihat di atas menyediakan infrastruktur yang membebankan
operator yang disebutkan di atas dan memacu proses panggil balik. Mengenai penggunaan mana-mana pengendali
di atas dengan a TracedValue ia akan memberikan nilai lama dan baharu bagi pembolehubah itu,
dalam kes ini an int32_t nilai. Dengan pemeriksaan ke atas TracedValue pengisytiharan, kita tahu
fungsi sinki surih akan mempunyai hujah (const int32_t oldValue, malar int32_t newValue).
Jenis pulangan untuk a TracedValue fungsi panggil balik sentiasa membatalkan, jadi yang diharapkan
tandatangan panggil balik ialah:

void (* TracedValueCallback)(const int32_t oldValue, const int32_t newValue);

. .AddTraceSource dalam GetTypeId kaedah menyediakan "cangkuk" yang digunakan untuk menyambungkan
mengesan sumber ke dunia luar melalui sistem Config. Kami telah membincangkan
tiga agruments pertama kepada AddTraceSource: nama Atribut untuk sistem Config, bantuan
rentetan, dan alamat ahli data kelas TracedValue.

Argumen rentetan terakhir, "ns3::Traced::Value::Int32" dalam contoh, ialah nama sebuah
mesin taip untuk tandatangan fungsi panggil balik. Kami memerlukan tandatangan ini ditakrifkan,
dan berikan nama jenis yang layak sepenuhnya kepada AddTraceSource, jadi dokumentasi API boleh
pautkan sumber surih kepada tandatangan fungsi. Untuk TracedValue tandatangannya ialah
terus terang; untuk TracedCallbacks kami telah melihat dokumen API sangat membantu.

Sebenar Contoh
Mari kita lakukan contoh yang diambil daripada salah satu buku yang paling terkenal tentang TCP. "TCP/IP
Illustrated, Jilid 1: The Protocols," oleh W. Richard Stevens adalah klasik. Saya baru sahaja membelek
buku itu dibuka dan merentasi plot yang bagus bagi kedua-dua tetingkap kesesakan dan turutan
nombor berbanding masa pada halaman 366. Stevens memanggil ini, "Rajah 21.10. Nilai cwnd dan
hantar nombor urutan semasa data sedang dihantar." Mari kita buat semula bahagian cwnd
plot itu dalam ns-3 menggunakan sistem pengesanan dan gnplot.

Boleh didapati Sumber
Perkara pertama yang perlu difikirkan ialah bagaimana kita ingin mengeluarkan data. Apa yang kita
perlu mengesan? Jadi mari kita rujuk senarai "Semua Sumber Surih" untuk melihat perkara yang perlu kita lakukan
dengan. Ingat bahawa ini terdapat dalam ns-3 Dokumentasi API. Jika anda menatal melalui
senarai, anda akhirnya akan mendapati:
ns3::TcpNewReno

· Tetingkap kesesakan: Tetingkap kesesakan sambungan TCP

· Ambang Perlahan: Ambang permulaan perlahan TCP (bait)

Ternyata bahawa ns-3 Pelaksanaan TCP hidup (kebanyakannya) dalam fail
src/internet/model/tcp-socket-base.cc manakala varian kawalan kesesakan berada dalam fail seperti itu
as src/internet/model/tcp-newreno.cc. Jika anda tidak tahu ini a priori, anda boleh menggunakannya
rekursif grep helah:

$ cari . -nama '*.cc' | xargs grep -i tcp

Anda akan menemui halaman demi halaman contoh tcp yang menunjukkan anda ke fail itu.

Membawa dokumentasi kelas untuk TcpNewReno dan melangkau ke senarai
TraceSources anda akan dapati
TraceSources

· Tetingkap kesesakan: Tetingkap kesesakan sambungan TCP

Tandatangan panggilan balik: ns3::Dijejaki::Nilai::Uint322Panggil Balik

Mengklik pada panggilan balik mesin taip pautan kami melihat tandatangan yang anda kini tahu jangkakan:

typedef void(* ns3::Traced::Value::Int32Callback)(const int32_t oldValue, const int32_t newValue)

Anda kini harus memahami kod ini sepenuhnya. Jika kita mempunyai penunjuk ke TcpNewReno,
kita boleh TraceConnect kepada sumber surih "CongestionWindow" jika kami menyediakan yang sesuai
sasaran panggil balik. Ini adalah jenis sumber surih yang sama yang kita lihat dalam contoh mudah
pada permulaan bahagian ini, kecuali yang kita bincangkan uint32_t bukan
int32_t. Dan kami tahu bahawa kami perlu menyediakan fungsi panggil balik dengan tandatangan itu.

Mencari Contoh
Adalah lebih baik untuk mencuba dan mencari kod yang berfungsi yang boleh anda ubah suai
daripada bermula dari awal. Jadi pesanan pertama perniagaan sekarang ialah mencari beberapa kod itu
sudah mengaitkan sumber surih "CongestionWindow" dan lihat sama ada kami boleh mengubah suainya. Seperti biasa,
grep adakah rakan anda:

$ cari . -nama '*.cc' | xargs grep CongestionWindow

Ini akan menunjukkan beberapa calon yang menjanjikan: contoh/tcp/tcp-large-transfer.cc
and src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc.

Kami belum melawat mana-mana kod ujian lagi, jadi mari kita lihat di sana. Anda akan
biasanya mendapati bahawa kod ujian adalah agak minimum, jadi ini mungkin pertaruhan yang sangat baik.
Buka src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc dalam editor kegemaran anda dan cari
"Tetingkap Kesesakan". Anda akan mendapati,

ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow",
MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, ini));

Ini sepatutnya kelihatan sangat biasa kepada anda. Kami menyebut di atas bahawa jika kami mempunyai penunjuk ke
TcpNewReno, kita boleh TraceConnect ke sumber surih "CongestionWindow". Itu betul-betul
apa yang kita ada di sini; jadi ternyata baris kod ini melakukan apa yang kita mahukan.
Mari kita teruskan dan ekstrak kod yang kita perlukan daripada fungsi ini (Ns3TcpCwndTestCase1::DoRun
(kosong)). Jika anda melihat fungsi ini, anda akan mendapati bahawa ia kelihatan seperti satu ns-3
skrip. Ternyata itulah yang sebenarnya. Ia adalah skrip yang dijalankan oleh ujian
rangka kerja, jadi kita boleh tarik keluar dan bungkusnya utama bukannya di DoRun. Sebaliknya
daripada berjalan melalui ini, langkah, demi langkah, kami telah menyediakan fail yang terhasil daripada pemindahan
ujian ini kembali kepada orang asli ns-3 skrip -- contoh/tutorial/kelima.cc.

Dinamik Trace Sumber
. kelima.cc contoh menunjukkan peraturan yang sangat penting yang mesti anda fahami
sebelum menggunakan sebarang jenis sumber surih: anda mesti memastikan bahawa sasaran a
Konfigurasi::Sambung arahan wujud sebelum cuba menggunakannya. Ini tidak berbeza dengan mengatakan
sesuatu objek mesti dibuat seketika sebelum cuba memanggilnya. Walaupun ini mungkin kelihatan jelas
apabila dinyatakan dengan cara ini, ia membingungkan ramai orang yang cuba menggunakan sistem untuk yang pertama
pada bila-bila masa.

Mari kita kembali kepada asas untuk seketika. Terdapat tiga fasa pelaksanaan asas yang wujud dalam
mana-mana ns-3 skrip. Fasa pertama kadangkala dipanggil "Masa Konfigurasi" atau "Persediaan
Masa," dan wujud dalam tempoh apabila utama fungsi skrip anda sedang berjalan, tetapi
sebelum Simulator::Lari dipanggil. Fasa kedua kadangkala dipanggil "Masa Simulasi"
dan wujud dalam tempoh masa apabila Simulator::Lari sedang giat melaksanakan acaranya.
Selepas ia selesai melaksanakan simulasi, Simulator::Lari akan mengembalikan kawalan kembali kepada
yang utama fungsi. Apabila ini berlaku, skrip memasuki apa yang boleh dipanggil "Teardown
Fasa," iaitu apabila struktur dan objek yang dicipta semasa persediaan diasingkan dan
dibebaskan.

Mungkin kesilapan yang paling biasa dilakukan dalam mencuba menggunakan sistem pengesanan adalah menganggapnya
entiti yang dibina secara dinamik semasa simulasi masa tersedia semasa konfigurasi
masa. Khususnya, an ns-3 Soket ialah objek dinamik yang sering dicipta oleh Aplikasi kepada
berkomunikasi antara Nod, Pada ns-3 Permohonan sentiasa mempunyai "Masa Mula" dan "Berhenti
Masa" yang dikaitkan dengannya. Dalam kebanyakan kes, an Permohonan tidak akan mencuba
untuk mencipta objek dinamik sehingga ia StartApplication kaedah dipanggil pada beberapa "Mula
Masa". Ini adalah untuk memastikan simulasi dikonfigurasikan sepenuhnya sebelum apl
cuba melakukan apa sahaja (apa yang akan berlaku jika ia cuba menyambung ke Nod yang tidak wujud
lagi semasa masa konfigurasi?). Akibatnya, semasa fasa konfigurasi anda tidak boleh
sambungkan sumber surih ke sinki surih jika salah satu daripadanya dicipta secara dinamik semasa
simulasi.

Dua penyelesaian kepada teka-teki ini ialah

1. Buat acara simulator yang dijalankan selepas objek dinamik dicipta dan cangkuk
mengesan apabila peristiwa itu dilaksanakan; atau

2. Cipta objek dinamik pada masa konfigurasi, sangkut kemudian, dan berikan objek itu
sistem untuk digunakan semasa masa simulasi.

Kami mengambil pendekatan kedua dalam kelima.cc contoh. Keputusan ini memerlukan kami untuk mencipta
yang Aplikasi Saya Permohonan, keseluruhan tujuannya adalah untuk mengambil a Soket sebagai parameter.

Panduan: kelima.cc
Sekarang, mari kita lihat contoh program yang kami bina dengan membedah kesesakan
ujian tingkap. Buka contoh/tutorial/kelima.cc dalam editor kegemaran anda. Awak patut lihat
beberapa kod yang kelihatan biasa:

/* -*- Mod:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Program ini adalah perisian percuma; anda boleh mengedarkannya semula dan/atau mengubah suai
* ia di bawah terma GNU General Public License versi 2 sebagai
* diterbitkan oleh Yayasan Perisian Percuma;
*
*Program ini diedarkan dengan harapan ianya bermanfaat,
* tetapi TANPA SEBARANG WARANTI; tanpa waranti tersirat pun
* KEBOLEHPERDAGANGAN atau KESESUAIAN UNTUK TUJUAN TERTENTU. Lihat
* Lesen Awam Am GNU untuk butiran lanjut.
*
* Anda sepatutnya menerima salinan Lesen Awam Am GNU
* bersama dengan program ini; jika tidak, tulis kepada Perisian Percuma
* Foundation, Include., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#termasuk
#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"

menggunakan ruang nama ns3;

NS_LOG_COMPONENT_DEFINE ("FifthScriptExample");

Ini semua telah dibincangkan, jadi kami tidak akan mengulanginya. Baris sumber seterusnya ialah
ilustrasi rangkaian dan ulasan menangani masalah yang diterangkan di atas dengan Soket.

// ================================================== ============================
//
// nod 0 nod 1
// +----------------+ +----------------+
// | ns-3 TCP | | ns-3 TCP |
// +----------------+ +----------------+
// | 10.1.1.1 | | 10.1.1.2 |
// +----------------+ +----------------+
// | titik ke titik | | titik ke titik |
// +----------------+ +----------------+
// | |
// +----------------------+
// 5 Mbps, 2 ms
//
//
// Kami ingin melihat perubahan dalam tetingkap kesesakan TCP ns-3. Kita perlu
// untuk menghidupkan aliran dan mengaitkan atribut CongestionWindow pada soket
// daripada pengirim. Biasanya seseorang akan menggunakan aplikasi on-off untuk menjana a
// aliran, tetapi ini mempunyai beberapa masalah. Pertama, soket on-off
// aplikasi tidak dibuat sehingga masa Mula Aplikasi, jadi kami tidak akan melakukannya
// dapat memaut soket (sekarang) pada masa konfigurasi. Kedua, walaupun kita
// boleh mengatur panggilan selepas masa mula, soket tidak awam jadi kami
// tidak dapat melakukannya.
//
// Jadi, kita boleh membuat versi ringkas aplikasi hidup-mati yang melakukan apa
// kami mahu. Kelebihannya kita tidak memerlukan semua kerumitan hidup-mati
// permohonan. Pada sisi tolak, kami tidak mempunyai pembantu, jadi kami perlu mendapatkan
// sedikit lagi terlibat dalam butiran, tetapi ini remeh.
//
// Jadi mula-mula, kita cipta soket dan buat jejak menyambung padanya; lepas tu kita lalu
// soket ini ke dalam pembina aplikasi mudah kami yang kemudiannya
// pasang dalam nod sumber.
// ================================================== ============================
//

Ini juga harus dijelaskan sendiri.

Bahagian seterusnya ialah pengisytiharan Aplikasi Saya Permohonan yang kami kumpulkan untuk membolehkan
yang Soket untuk dibuat pada masa konfigurasi.

kelas MyApp : Aplikasi awam
{
awam:

MyApp ();
maya ~MyApp();

Persediaan kosong (Ptr soket, alamat alamat, uint32_t packetSize,
uint32_t nPackets, DataRate dataRate);

peribadi:
virtual void StartApplication (void);
virtual void StopApplication (void);

void ScheduleTx (void);
void SendPacket (kosong);

Ptr m_soket;
Alamat m_peer;
uint32_t m_packetSize;
uint32_t m_nPaket;
Kadar Data m_dataRate;
EventId m_sendEvent;
bool m_running;
uint32_t m_packetsSent;
};

Anda boleh melihat bahawa kelas ini mewarisi daripada ns-3 Permohonan kelas. Lihatlah
src/network/model/application.h jika anda berminat dengan apa yang diwarisi. The Aplikasi Saya
kelas bertanggungjawab untuk mengatasi StartApplication and StopApplication kaedah. Ini
kaedah dipanggil secara automatik apabila Aplikasi Saya diperlukan untuk memulakan dan menghentikan penghantaran data
semasa simulasi.

Memulakan / Menghentikan Aplikasi
Adalah berbaloi untuk meluangkan sedikit masa untuk menerangkan bagaimana acara sebenarnya bermula dalam
sistem. Ini adalah satu lagi penjelasan yang agak mendalam, dan boleh diabaikan jika anda tidak
merancang untuk meneroka ke dalam keberanian sistem. Ia berguna, bagaimanapun, dalam hal itu
perbincangan menyentuh tentang bagaimana beberapa bahagian yang sangat penting ns-3 bekerja dan mendedahkan beberapa
simpulan bahasa penting. Jika anda merancang untuk melaksanakan model baharu, anda mungkin mahu melakukannya
faham bahagian ini.

Cara paling biasa untuk memulakan acara mengepam adalah dengan memulakan Permohonan. Ini dilakukan sebagai
hasil daripada baris familar berikut (mudah-mudahan) an ns-3 skrip:

Aplikasi ApplicationContainer = ...
apps.Start (Saat (1.0));
apps.Stop (Saat (10.0));

Kod bekas aplikasi (lihat src/network/helper/application-container.h jika anda adalah
berminat) menggelung melalui aplikasi dan panggilan yang terkandung di dalamnya,

app->SetStartTime (StartTime);

hasil daripada apps.Mula panggilan dan

app->SetStopTime (stopTime);

hasil daripada aplikasi.Berhenti panggil.

Keputusan muktamad panggilan ini ialah kami mahu mempunyai simulator secara automatik
membuat panggilan ke dalam kami Aplikasi untuk memberitahu mereka bila hendak mula dan berhenti. Dalam kes
Aplikasi Saya, ia mewarisi daripada kelas Permohonan dan mengatasi StartApplication, dan
StopApplication. Ini adalah fungsi yang akan dipanggil oleh simulator di
masa yang sesuai. Dalam kes Aplikasi Saya anda akan dapati itu MyApp::StartApplication tidak
permulaan Ikat, dan Hubungi pada soket, dan kemudian mulakan data mengalir dengan memanggil
MyApp::SendPacket. MyApp::StopApplication berhenti menjana paket dengan membatalkan mana-mana
menunggu acara hantar kemudian menutup soket.

Salah satu perkara yang menarik tentang ns-3 ialah anda boleh mengabaikan sepenuhnya pelaksanaannya
butiran bagaimana anda Permohonan dipanggil "secara automatik" oleh simulator di tempat yang betul
masa. Tetapi kerana kita telah pun meneroka lebih dalam ns-3 sudah, mari kita lakukannya.

Jika anda melihat src/network/model/application.cc anda akan mendapati bahawa SetStartTime kaedah
daripada Permohonan hanya menetapkan pembolehubah ahli m_startTime dan juga SetStopTime kaedah
hanya set m_stopTime. Dari sana, tanpa beberapa petunjuk, jejak mungkin akan berakhir.

Kunci untuk mengambil jejak semula ialah mengetahui bahawa terdapat senarai global semua
nod dalam sistem. Setiap kali anda mencipta nod dalam simulasi, penunjuk ke Nod itu
ditambah kepada global NodeList.

Sila lihat pada src/network/model/node-list.cc dan mencari NodeList::Tambah. Orang ramai
pelaksanaan statik panggilan ke dalam pelaksanaan persendirian dipanggil NodeListPriv::Tambah. ini
adalah idom yang agak biasa di ns-3. Jadi, lihatlah NodeListPriv::Tambah. Di sana awak
akan mencari,

Simulator::ScheduleWithContext (indeks, TimeStep (0), &Nod::Initialize, nod);

Ini memberitahu anda bahawa apabila Nod dicipta dalam simulasi, sebagai kesan sampingan, panggilan
kepada nod itu Inisialkan kaedah dijadualkan untuk anda yang berlaku pada masa sifar. jangan
terlalu banyak membaca nama itu, namun. Ia tidak bermakna bahawa Node akan mula melakukan
apa-apa sahaja, ia boleh ditafsirkan sebagai panggilan maklumat ke dalam Node yang memberitahunya bahawa
simulasi telah dimulakan, bukan panggilan untuk tindakan yang memberitahu Node untuk mula melakukan sesuatu.

Jadi, NodeList::Tambah secara tidak langsung menjadualkan panggilan ke Nod:: Mulakan pada masa sifar untuk menasihati a
Nod baharu yang simulasi telah dimulakan. Jika anda melihat ke dalam src/network/model/node.h anda
akan, bagaimanapun, tidak menemui kaedah yang dipanggil Nod:: Mulakan. Ternyata bahawa
Inisialkan kaedah diwarisi daripada kelas Objek. Semua objek dalam sistem boleh
dimaklumkan apabila simulasi bermula, dan objek kelas Node hanyalah satu jenis daripadanya
objek.

Sila lihat pada src/core/model/object.cc seterusnya dan cari Objek::Memulakan. Kod ini
tidak semudah yang anda jangkakan sejak itu ns-3 Objek menyokong
pengagregatan. Kod dalam Objek::Memulakan kemudian gelung melalui semua objek yang
telah diagregatkan bersama dan memanggil mereka LakukanInitialize kaedah. Ini satu lagi simpulan bahasa
yang sangat biasa dalam ns-3, kadangkala dipanggil "corak reka bentuk templat.": awam
kaedah API bukan maya, yang kekal malar merentas pelaksanaan, dan yang memanggil a
kaedah pelaksanaan maya persendirian yang diwarisi dan dilaksanakan oleh subkelas.
Nama-nama itu biasanya seperti Nama Kaedah untuk API awam dan DoMethodName khususnya
API persendirian.

Ini memberitahu kita bahawa kita harus mencari a Nod::DoInitialize kaedah dalam
src/network/model/node.cc untuk kaedah yang akan meneruskan jejak kita. Jika anda mencari
kod, anda akan menemui kaedah yang melingkari semua peranti dalam Node dan kemudian
semua aplikasi dalam panggilan Nod peranti->memulakan and aplikasi->Memulakan
masing-masing.

Anda mungkin sudah tahu bahawa kelas Peranti and Permohonan kedua-duanya mewarisi dari kelas Objek
maka langkah seterusnya adalah untuk melihat apa yang berlaku apabila Aplikasi::DoInitialize is
dipanggil. Lihatlah src/network/model/application.cc dan anda akan dapati:

membatalkan
Aplikasi::DoInitialize (kosong)
{
m_startEvent = Simulator::Jadual (m_startTime, &Application::StartApplication, this);
jika (m_stopTime != TimeStep (0))
{
m_stopEvent = Simulator::Jadual (m_stopTime, &Application::StopApplication, this);
}
Object::DoInitialize ();
}

Di sini, kami akhirnya sampai ke penghujung denai. Jika anda telah menyimpan semuanya lurus, apabila anda
melaksanakan sebuah ns-3 Permohonan, permohonan baharu anda diwarisi daripada kelas Permohonan. Anda
mengatasi StartApplication and StopApplication kaedah dan menyediakan mekanisme untuk
memulakan dan menghentikan aliran data daripada baharu anda Permohonan. Apabila Nod adalah
dicipta dalam simulasi, ia ditambah kepada global NodeList. Tindakan menambah Nod ke
ini NodeList menyebabkan acara simulator dijadualkan untuk masa sifar yang memanggil
Nod:: Mulakan kaedah Nod yang baru ditambah untuk dipanggil apabila simulasi bermula.
Memandangkan Nod mewarisi daripada Objek, ini memanggil Objek::Memulakan kaedah pada Node
yang, seterusnya, memanggil LakukanInitialize kaedah pada semua Objek diagregatkan kepada
Nod (fikirkan model mobiliti). Sejak Node Objek telah mengatasi LakukanInitialize, Yang
kaedah dipanggil apabila simulasi bermula. The Nod::DoInitialize kaedah memanggil
Inisialkan kaedah semua Aplikasi pada nod. Sejak Aplikasi juga
Objek, ini menyebabkan Aplikasi::DoInitialize untuk dipanggil. Bila
Aplikasi::DoInitialize dipanggil, ia menjadualkan acara untuk StartApplication and
StopApplication memanggil di Permohonan. Panggilan ini direka untuk memulakan dan menghentikan
aliran data daripada Permohonan

Ini adalah satu lagi perjalanan yang agak panjang, tetapi ia hanya perlu dibuat sekali, dan anda sekarang
memahami satu lagi bahagian yang sangat mendalam ns-3.

. Aplikasi Saya Permohonan
. Aplikasi Saya Permohonan memerlukan pembina dan pemusnah, sudah tentu:

MyApp::MyApp ()
: soket_m (0),
m_peer (),
m_packetSize (0),
m_nPaket (0),
m_dataRate (0),
m_sendEvent (),
m_running (salah),
m_paketHantar (0)
{
}

MyApp::~MyApp()
{
m_soket = 0;
}

Kewujudan bit kod seterusnya adalah sebab utama mengapa kami menulis ini Permohonan in
tempat pertama.

membatalkan
MyApp:: Persediaan (Ptr soket, alamat alamat, uint32_t packetSize,
uint32_t nPackets, DataRate dataRate)
{
m_soket = soket;
m_peer = alamat;
m_packetSize = Saiz paket;
m_nPaket = nPaket;
m_dataRate = dataRate;
}

Kod ini sepatutnya cukup jelas. Kami hanya memulakan pembolehubah ahli.
Yang penting dari perspektif pengesanan ialah Ptr soket yang kita
diperlukan untuk diberikan kepada aplikasi semasa masa konfigurasi. Ingat bahawa kita akan pergi
untuk mencipta Soket sebagai TcpSocket (yang dilaksanakan oleh TcpNewReno) dan cangkuknya
Sumber surih "CongestionWindow" sebelum menghantarnya ke Persediaan kaedah.

membatalkan
MyApp::StartApplication (tidak sah)
{
m_running = benar;
m_paketHantar = 0;
m_soket->Ikat ();
m_socket->Connect (m_peer);
SendPacket ();
}

Kod di atas ialah pelaksanaan yang diganti Permohonan::StartApplication yang akan
secara automatik dipanggil oleh simulator untuk memulakan kami Permohonan berjalan di tempat yang sesuai
masa. Anda boleh melihat bahawa ia melakukan a Soket Ikat operasi. Jika anda biasa dengan
Berkeley Sockets ini tidak sepatutnya mengejutkan. Ia melaksanakan kerja yang diperlukan pada tempatan
sebelah sambungan seperti yang anda jangkakan. Yang berikut Hubungi akan melakukan apa yang ada
diperlukan untuk mewujudkan sambungan dengan TCP di Alamat m_peer. Ia kini sepatutnya jelas
mengapa kita perlu menangguhkan banyak perkara ini kepada masa simulasi, kerana Hubungi akan memerlukan
rangkaian yang berfungsi sepenuhnya untuk diselesaikan. Selepas Hubungi, yang Permohonan kemudian bermula
mencipta acara simulasi dengan memanggil SendPacket.

Bit kod seterusnya menerangkan kepada Permohonan bagaimana untuk berhenti mencipta acara simulasi.

membatalkan
MyApp::StopApplication (kosong)
{
m_running = palsu;

jika (m_sendEvent.IsRunning ())
{
Simulator::Batal (m_sendEvent);
}

jika (m_socket)
{
m_socket->Tutup ();
}
}

Setiap kali acara simulasi dijadualkan, an Acara dicipta. Sekiranya Acara sedang menunggu
pelaksanaan atau pelaksanaan, kaedahnya Adalah berlari akan kembali benar. Dalam kod ini, jika
Adalah berlari() kembali benar, kami Batal peristiwa yang mengalihkannya daripada acara simulator
beratur. Dengan melakukan ini, kami memutuskan rantaian peristiwa yang Permohonan digunakan untuk menyimpan
menghantarnya Peket dan juga Permohonan menjadi senyap. Selepas kami senyapkan Permohonan we
Tutup soket yang meruntuhkan sambungan TCP.

Soket sebenarnya dipadamkan dalam pemusnah apabila m_soket = 0 dilaksanakan. ini
mengalih keluar rujukan terakhir kepada Ptr asas yang menyebabkan pemusnah daripada
Objek yang akan dipanggil.

Ingatlah bahawa StartApplication dipanggil SendPacket untuk memulakan rangkaian peristiwa yang menerangkan
yang Permohonan tingkah laku.

membatalkan
MyApp::SendPacket (kosong)
{
Ptr paket = Buat (m_packetSize);
m_socket->Hantar (paket);

jika (++m_packetSent <m_nPackets)
{
JadualTx ();
}
}

Di sini, anda melihatnya SendPacket melakukan itu sahaja. Ia mewujudkan a Bungkusan dan kemudian melakukan a HANTAR
yang, jika anda tahu Berkeley Sockets, mungkin hanya apa yang anda harapkan untuk dilihat.

Ia adalah tanggungjawab pihak Permohonan untuk terus menjadualkan rangkaian acara, jadi
talian seterusnya memanggil JadualTx untuk menjadualkan acara penghantaran lain (a SendPacket) sehingga
Permohonan memutuskan ia telah menghantar cukup.

membatalkan
MyApp::ScheduleTx (kosong)
{
jika (m_running)
{
Masa tSeterusnya (Saat (M_packetSize * 8 / static_cast (m_dataRate.GetBitRate ())));
m_sendEvent = Simulator::Jadual (tNext, &MyApp::SendPacket, ini);
}
}

Di sini, anda melihatnya JadualTx melakukannya dengan tepat. Sekiranya Permohonan sedang berjalan (jika
StopApplication belum dipanggil) ia akan menjadualkan acara baharu, yang memanggil SendPacket
sekali lagi. Pembaca amaran akan melihat sesuatu yang turut mengelirukan pengguna baharu. Kadar data
daripada Permohonan itu sahaja. Ia tiada kaitan dengan kadar data asas
Saluran. Ini adalah kadar di mana Permohonan menghasilkan bit. Ia tidak mengambil kira
kira sebarang overhed untuk pelbagai protokol atau saluran yang digunakan untuk mengangkut
data. Jika anda menetapkan kadar data a Permohonan kepada kadar data yang sama seperti asas anda
Saluran anda akhirnya akan mendapat limpahan penimbal.

Trace Tenggelam
Inti dari latihan ini adalah untuk mendapatkan jejak panggilan balik dari TCP yang menunjukkan
tetingkap kesesakan telah dikemas kini. Sekeping kod seterusnya melaksanakan yang sepadan
sinki surih:

kekosongan statik
CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
}

Ini sepatutnya sudah biasa kepada anda sekarang, jadi kami tidak akan memikirkan butirannya. Fungsi ini
hanya log masa simulasi semasa dan nilai baharu setiap tetingkap kesesakan
masa ia berubah. Anda mungkin boleh membayangkan bahawa anda boleh memuatkan output yang terhasil
ke dalam atur cara grafik (gnuplot atau Excel) dan segera lihat graf yang bagus
tingkah laku tingkap kesesakan dari semasa ke semasa.

Kami menambah sinki surih baharu untuk menunjukkan tempat paket digugurkan. Kami akan menambah ralat
model kepada kod ini juga, jadi kami ingin menunjukkan kerja ini.

kekosongan statik
RxDrop (Ptr p)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Sekarang ().GetSeconds ());
}

Sinki surih ini akan disambungkan kepada sumber surih "PhyRxDrop" titik-ke-titik
NetDevice. Sumber surih ini menyala apabila paket dijatuhkan oleh lapisan fizikal a
NetDevice. Jika anda mengambil lencongan kecil ke punca
(src/point-to-point/model/point-to-point-net-device.cc) anda akan melihat bahawa jejak ini
sumber merujuk kepada PointToPointNetDevice::m_phyRxDropTrace. Jika anda kemudian melihat ke dalam
src/point-to-point/model/point-to-point-net-device.h untuk pembolehubah ahli ini, anda akan
mendapati bahawa ia diisytiharkan sebagai a TracedCallback Paket> >. Ini sepatutnya memberitahu anda
bahawa sasaran panggil balik haruslah fungsi yang mengembalikan batal dan mengambil satu
parameter iaitu a Ptr Paket> (dengan andaian kita menggunakan SambungTanpaKonteks) -- cuma
apa yang kita ada di atas.

Utama Program
Kod berikut sepatutnya sudah biasa kepada anda sekarang:

int
utama (int argc, char *argv[])
{
NodeContainer nod;
nod.Buat (2);

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

Peranti NetDeviceContainer;
peranti = pointToPoint.Install (nod);

Ini mencipta dua nod dengan saluran titik ke titik di antara mereka, seperti yang ditunjukkan dalam
ilustrasi pada permulaan fail.

Beberapa baris kod seterusnya menunjukkan sesuatu yang baharu. Jika kita mengesan sambungan yang berkelakuan
dengan sempurna, kita akan berakhir dengan tingkap kesesakan yang semakin membosankan. Untuk melihat mana-mana
tingkah laku yang menarik, kami benar-benar ingin memperkenalkan ralat pautan yang akan menggugurkan paket,
menyebabkan ACK pendua dan mencetuskan gelagat tetingkap kesesakan yang lebih menarik.

ns-3 menyediakan ErrorModel objek yang boleh dilekatkan Saluran. Kami menggunakan
RateErrorModel yang membolehkan kita memperkenalkan ralat ke dalam a Saluran pada sesuatu yang diberikan kadar.

Ptr em = CreateObject ();
em->SetAttribute ("ErrorRate", DoubleValue (0.00001));
devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));

Kod di atas menunjukkan a RateErrorModel Objek, dan kami menetapkan "ErrorRate" atribut
kepada nilai yang dikehendaki. Kami kemudian menetapkan instantiated yang terhasil RateErrorModel sebagai kesilapan
model yang digunakan oleh titik-ke-titik NetDevice. Ini akan memberi kami beberapa penghantaran semula dan
jadikan plot kita lebih menarik.

Timbunan InternetStackHelper;
stack.Install (nod);

Alamat Ipv4AddressHelper;
address.SetBase ("10.1.1.0", "255.255.255.252");
Antara muka Ipv4InterfaceContainer = alamat.Assign (peranti);

Kod di atas sepatutnya biasa. Ia memasang tindanan internet pada dua nod kami dan
mencipta antara muka dan memberikan alamat IP untuk peranti point-to-point.

Memandangkan kami menggunakan TCP, kami memerlukan sesuatu pada Nod destinasi untuk menerima TCP
sambungan dan data. The PacketSink Permohonan biasa digunakan dalam ns-3 untuk itu
tujuan.

uint16_t sinkPort = 8080;
Alamat sinkAddress (InetSocketAddress(interfaces.GetAddress (1), sinkPort));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
sinkApps.Start (Saat (0.));
sinkApps.Berhenti (Saat (20.));

Ini semua mesti biasa, kecuali,

PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), sinkPort));

Kod ini membuat instantiate a PacketSinkHelper dan memberitahunya untuk mencipta soket menggunakan kelas
ns3::TcpSocketFactory. Kelas ini melaksanakan corak reka bentuk yang dipanggil "kilang objek"
yang merupakan mekanisme yang biasa digunakan untuk menentukan kelas yang digunakan untuk mencipta objek dalam
cara abstrak. Di sini, daripada perlu mencipta objek itu sendiri, anda menyediakannya
PacketSinkHelper rentetan yang menyatakan a JenisId rentetan yang digunakan untuk mencipta objek yang
kemudian boleh digunakan, seterusnya, untuk mencipta contoh Objek yang dicipta oleh kilang.

Parameter selebihnya memberitahu Permohonan alamat dan pelabuhan mana yang sepatutnya Ikat kepada.

Dua baris kod seterusnya akan mencipta soket dan menyambungkan sumber surih.

Ptr ns3TcpSocket = Soket::CreateSocket (nodes.Get (0),
TcpSocketFactory::GetTypeId ());
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow",
MakeCallback (&CwndChange));

Pernyataan pertama memanggil fungsi ahli statik Soket::CreateSocket dan menyediakan a
Nod dan eksplisit JenisId untuk kilang objek yang digunakan untuk mencipta soket. Ini adalah satu
panggilan tahap rendah sedikit daripada PacketSinkHelper panggil di atas, dan menggunakan C++ yang jelas
taip bukannya satu yang dirujuk oleh rentetan. Jika tidak, konsepnya adalah sama
benda.

Sebaik sahaja TcpSocket dicipta dan dilampirkan pada Node, kita boleh gunakan
TraceConnectTanpaKonteks untuk menyambungkan sumber surih CongestionWindow ke sinki surih kami.

Ingat bahawa kami mengekodkan Permohonan supaya kita boleh mengambilnya Soket baru kami buat (semasa
masa konfigurasi) dan gunakannya dalam masa simulasi. Kita kini perlu mewujudkannya
Permohonan. Kami tidak menghadapi sebarang masalah untuk mencipta pembantu untuk menguruskan Permohonan so
kita perlu mencipta dan memasangnya "secara manual". Ini sebenarnya agak mudah:

Ptr app = CreateObject ();
app->Persediaan (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
nodes.Get (0)->AddApplication (app);
app->Mula (Saat (1.));
app->Berhenti (Saat (20.));

Baris pertama mencipta satu Objek jenis Aplikasi Saya -- kami Permohonan. Baris kedua memberitahu
yang Permohonan apa Soket untuk digunakan, alamat yang hendak disambungkan, berapa banyak data untuk dihantar
setiap peristiwa penghantaran, bilangan peristiwa penghantaran untuk dijana dan kadar untuk menghasilkan data
daripada peristiwa tersebut.

Seterusnya, kami menambah secara manual Aplikasi Saya Permohonan kepada sumber Node dan secara eksplisit memanggil
Start and Berhenti kaedah pada Permohonan untuk memberitahunya bila untuk memulakan dan berhenti melakukannya
benda.

Kita perlu melakukan sambungan dari titik ke titik penerima NetDevice acara gugur
kepada kita RxDrop panggil balik sekarang.

devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));

Kini sepatutnya jelas bahawa kita mendapat rujukan kepada penerima nod NetDevice
daripada bekasnya dan menyambungkan sumber surih yang ditakrifkan oleh atribut "PhyRxDrop" pada
peranti itu ke sinki surih RxDrop.

Akhir sekali, kami memberitahu simulator untuk mengatasi mana-mana Aplikasi dan hanya berhenti memproses
peristiwa pada 20 saat ke dalam simulasi.

Simulator::Berhenti (Seconds(20));
Simulator::Jalankan ();
Simulator::Memusnahkan ();

0 kembali;
}

Ingat bahawa sebaik sahaja Simulator::Lari dipanggil, masa konfigurasi tamat, dan simulasi
masa bermula. Semua kerja yang kami atur dengan mencipta Permohonan dan mengajarnya
cara menyambung dan menghantar data sebenarnya berlaku semasa panggilan fungsi ini.

Sebaik sahaja Simulator::Lari kembali, simulasi selesai dan kami memasuki teardown
fasa. Dalam kes ini, Simulator:: Musnahkan menjaga butiran berdarah dan kami hanya kembali
kod kejayaan selepas ia selesai.

Berlari kelima.cc
Memandangkan kami telah menyediakan fail kelima.cc untuk anda, jika anda telah membina pengedaran anda (dalam
mod nyahpepijat kerana ia menggunakan NS_LOG -- ingat bahawa binaan yang dioptimumkan dioptimumkan NS_LOG) ia
akan menunggu anda untuk berlari.

$ ./waf --lari kelima
Waf: Memasuki direktori `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
Waf: Meninggalkan direktori `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
'bina' berjaya diselesaikan (0.684s)
1 536
1.0093 1072
1.01528 1608
1.02167 2144
...
1.11319 8040
1.12151 8576
1.12983 9112
RxDrop pada 1.13696
...

Anda mungkin dapat melihat serta-merta kelemahan menggunakan apa-apa jenis cetakan dalam kesan anda.
Kami mendapat mesej waf luar yang dicetak di seluruh maklumat menarik kami
dengan mesej RxDrop tersebut. Kami akan membetulkannya tidak lama lagi, tetapi saya pasti anda tidak sabar untuk melihatnya
hasil daripada semua kerja ini. Mari kita ubah hala output itu ke fail yang dipanggil cwnd.dat:

$ ./waf --run kelima > cwnd.dat 2>&1

Sekarang edit "cwnd.dat" dalam editor kegemaran anda dan alih keluar status binaan waf dan lepaskan
baris, hanya meninggalkan data yang dikesan (anda juga boleh mengulas
TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop)); dalam skrip untuk menyingkirkan
daripada cetakan jatuh dengan mudah.

Anda kini boleh menjalankan gnuplot (jika anda telah memasangnya) dan memberitahunya untuk menjana beberapa yang cantik
gambar:

$ gnplot
gnuplot> tetapkan terminal png saiz 640,480
gnuplot> tetapkan output "cwnd.png"
gnuplot> plot "cwnd.dat" menggunakan tajuk 1:2 'Tetingkap Kesesakan' dengan titik garis
gnplot> keluar

Anda kini sepatutnya mempunyai graf tetingkap kesesakan berbanding masa duduk dalam fail
"cwnd.png" loading="lazy" yang kelihatan seperti:
[gambar]

Menggunakan Tahap Pertengahan Pembantu
Dalam bahagian sebelumnya, kami menunjukkan cara mengaitkan sumber surih dan mendapat harapan
maklumat menarik daripada simulasi. Mungkin anda akan ingat bahawa kami menelefon
log masuk ke output standard menggunakan std::cout "alat tumpul" lebih awal dalam hal ini
bab. Kami juga menulis tentang masalah yang perlu dihuraikan keluaran log mengikut urutan
untuk mengasingkan maklumat yang menarik. Anda mungkin terfikir bahawa kami hanya berbelanja banyak
masa melaksanakan contoh yang mempamerkan semua masalah yang kami maksudkan untuk diselesaikan
yang ns-3 sistem pengesanan! Anda akan betul. Tetapi, bersabarlah dengan kami. Kami belum selesai.

Salah satu perkara yang paling penting yang kita mahu lakukan adalah untuk mempunyai keupayaan untuk dengan mudah
mengawal jumlah output yang keluar daripada simulasi; dan kami juga mahu menyelamatkan mereka
data ke fail supaya kita boleh merujuknya semula kemudian. Kita boleh menggunakan pembantu jejak peringkat pertengahan
disediakan dalam ns-3 untuk berbuat demikian dan melengkapkan gambar.

Kami menyediakan skrip yang menulis peristiwa perubahan dan pengguguran cwnd yang dibangunkan dalam contoh
kelima.cc ke cakera dalam fail berasingan. Perubahan cwnd disimpan sebagai ASCII yang dipisahkan dengan tab
fail dan peristiwa jatuh disimpan dalam fail PCAP. Perubahan untuk membuat ini berlaku ialah
agak kecil.

Panduan: keenam.cc
Mari kita lihat perubahan yang diperlukan untuk pergi dari kelima.cc kepada keenam.cc. Buka
contoh/tutorial/keenam.cc dalam editor kegemaran anda. Anda boleh melihat perubahan pertama dengan
mencari CwndChange. Anda akan mendapati bahawa kami telah menukar tandatangan untuk jejak itu
sinki dan telah menambah satu baris pada setiap sinki yang menulis maklumat yang dikesan kepada a
aliran mewakili fail.

kekosongan statik
CwndChange (Ptr strim, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*strim->GetStream () << Simulator::Sekarang ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}

kekosongan statik
RxDrop (Ptr fail, Ptr p)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Sekarang ().GetSeconds ());
fail->Tulis(Simulator::Now(), p);
}

Kami telah menambah parameter "strim" pada CwndChange singki jejak. Ini adalah objek yang
memegang (menyimpan selamat hidup) aliran keluaran C++. Ternyata ini adalah sangat mudah
objek, tetapi yang menguruskan isu seumur hidup untuk strim dan menyelesaikan masalah yang walaupun
pengguna C++ yang berpengalaman terserempak. Ia ternyata bahawa pembina salinan untuk std::ostream
ditandakan peribadi. Ini bermakna bahawa std::ostreams tidak mematuhi nilai semantik dan tidak boleh
digunakan dalam mana-mana mekanisme yang memerlukan strim untuk disalin. Ini termasuk ns-3
sistem panggil balik, yang mungkin anda ingat, memerlukan objek yang mematuhi nilai semantik.
Notis lanjut bahawa kami telah menambah baris berikut dalam CwndChange singki jejak
pelaksanaan:

*strim->GetStream () << Simulator::Sekarang ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;

Ini akan menjadi kod yang sangat biasa jika anda menggantikannya *strim->GetStream () bersama std::cout, Seperti
dalam:

std::cout << Simulator::Sekarang ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;

Ini menggambarkan bahawa Ptr sebenarnya hanya membawa a
std::ofstream untuk anda, dan anda boleh menggunakannya di sini seperti mana-mana aliran keluaran lain.

Keadaan yang sama berlaku di RxDrop kecuali objek yang dilalui (a
Ptr) mewakili fail PCAP. Terdapat satu pelapik dalam sinki surih ke
tulis cap masa dan kandungan paket digugurkan ke fail PCAP:

fail->Tulis(Simulator::Now(), p);

Sudah tentu, jika kita mempunyai objek yang mewakili kedua-dua fail, kita perlu menciptanya di suatu tempat
dan juga menyebabkan mereka dihantar ke singki surih. Jika anda melihat dalam utama fungsi,
anda akan menemui kod baharu untuk berbuat demikian:

AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));

...

PcapHelper pcapHelper;
Ptr fail = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP);
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));

Dalam bahagian pertama coretan kod di atas, kami sedang mencipta fail surih ASCII,
mencipta objek yang bertanggungjawab untuk mengurusnya dan menggunakan varian panggilan balik
fungsi penciptaan untuk mengatur objek yang akan dihantar ke singki. Jejak ASCII kami
pembantu menyediakan set fungsi yang kaya untuk memudahkan penggunaan fail teks (ASCII). Kami adalah
hanya akan menggambarkan penggunaan fungsi penciptaan aliran fail di sini.

. CreateFileStream fungsi pada asasnya akan membuat instantiate a std::ofstream objek dan
buat fail baharu (atau potong fail sedia ada). ini std::ofstream dibungkus dalam satu
ns-3 objek untuk pengurusan seumur hidup dan menyalin penyelesaian isu pembina.

Kami kemudian mengambil ini ns-3 objek yang mewakili fail dan hantar ke MakeBoundCallback().
Fungsi ini mencipta panggilan balik sama seperti MakeCallback(), tetapi ia "mengikat" nilai baharu kepada
panggilan balik. Nilai ini ditambah sebagai hujah pertama kepada panggilan balik sebelum ia
dipanggil.

Pada asasnya, MakeBoundCallback(&CwndChange, aliran) menyebabkan sumber surih menambah
parameter "strim" tambahan ke hadapan senarai parameter formal sebelum menggunakan
panggilan balik. Ini menukar tandatangan yang diperlukan bagi CwndChange tenggelam untuk dipadankan dengan yang satu
ditunjukkan di atas, yang termasuk parameter "tambahan". Ptr aliran.

Dalam bahagian kedua kod dalam coretan di atas, kami nyatakan a PcapHelper untuk melakukan
perkara yang sama untuk fail surih PCAP kami yang kami lakukan dengan AsciiTraceHelper. Barisan daripada
kod,

Ptr fail = pcapHelper.CreateFile ("sixth.pcap",
"w", PcapHelper::DLT_PPP);

mencipta fail PCAP bernama "sixth.pcap" dengan mod fail "w". Ini bermakna bahawa fail baru
dipenggal (kandungan dipadamkan) jika fail sedia ada dengan nama itu ditemui. perlawanan akhir
parameter ialah "jenis pautan data" bagi fail PCAP baharu. Ini adalah sama seperti PCAP
jenis pautan data perpustakaan ditakrifkan dalam bpf.h jika anda biasa dengan PCAP. Dalam kes ini,
DLT_PPP menunjukkan bahawa fail PCAP akan mengandungi paket yang diawali dengan titik ke
tajuk mata. Ini adalah benar kerana paket datang dari peranti point-to-point kami
pemandu. Jenis pautan data biasa lain ialah DLT_EN10MB (10 MB Ethernet) yang sesuai untuk csma
peranti dan DLT_IEEE802_11 (IEEE 802.11) sesuai untuk peranti wifi. Ini ditakrifkan
in src/network/helper/trace-helper.h jika anda berminat untuk melihat senarai tersebut. The
entri dalam senarai sepadan dengan yang masuk bpf.h tetapi kami menduplikasinya untuk mengelakkan sumber PCAP
pergantungan.

A ns-3 objek yang mewakili fail PCAP dikembalikan daripada BuatFile dan digunakan dalam terikat
panggil balik sama seperti dalam kes ASCII.

Lencongan penting: Adalah penting untuk diperhatikan bahawa walaupun kedua-dua objek ini
diisytiharkan dengan cara yang hampir sama,

Ptr fail...
Ptr aliran ...

Objek asas adalah sama sekali berbeza. Sebagai contoh, yang Ptr ialah
penunjuk pintar kepada an ns-3 Objek yang merupakan perkara yang cukup berat yang menyokong
Atribut dan disepadukan ke dalam sistem Config. The Ptr, Pada
Sebaliknya, adalah penunjuk pintar kepada objek terkira rujukan yang sangat ringan
benda. Ingat untuk melihat objek yang anda rujuk sebelum membuat sebarang andaian
tentang "kuasa" yang mungkin ada pada objek itu.

Sebagai contoh, lihat src/network/utils/pcap-file-wrapper.h dalam pengagihan dan
notis,

kelas PcapFileWrapper : Objek awam

kelas itu PcapFileWrapper merupakan ns-3 Objek berdasarkan warisannya. Lepas tu tengok
src/network/model/output-stream-wrapper.h dan perhatikan,

kelas OutputStreamWrapper : awam
SimpleRefCount

bahawa objek ini bukan ns-3 Objek sama sekali, ia adalah "semata-mata" objek C++ yang berlaku kepada
menyokong pengiraan rujukan mengganggu.

Maksudnya di sini ialah hanya kerana anda membaca Ptr ia tidak semestinya bermakna
Bahawa sesuatu merupakan ns-3 Objek yang anda boleh gantung ns-3 Atribut, contohnya.

Sekarang, kembali kepada contoh. Jika anda membina dan menjalankan contoh ini,

$ ./waf --run keenam

anda akan melihat mesej yang sama muncul seperti semasa anda menjalankan "kelima", tetapi dua fail baharu akan
muncul dalam direktori peringkat teratas anda ns-3 Pengedaran.

keenam.cwnd keenam.pcap

Memandangkan "sixth.cwnd" ialah fail teks ASCII, anda boleh melihatnya dengan kucing atau fail kegemaran anda
penonton.

1 0 536
1.0093 536 1072
1.01528 1072 1608
1.02167 1608 2144
...
9.69256 5149 5204
9.89311 5204 5259

Anda mempunyai fail yang diasingkan tab dengan cap masa, tetingkap kesesakan lama dan yang baharu
tetingkap kesesakan sesuai untuk mengimport terus ke dalam program plot anda. Tidak ada
cetakan luar dalam fail, tiada penghuraian atau penyuntingan diperlukan.

Memandangkan "sixth.pcap" ialah fail PCAP, anda boleh menggunakannya tcpdump.

membaca daripada fail sixth.pcap, PPP jenis pautan (PPP)
1.136956 IP 10.1.1.1.49153 > 10.1.1.2.8080: Bendera [.], seq 17177:17681, ack 1, menang 32768, pilihan [TS val 1133 ecr 1127], panjang
1.403196 IP 10.1.1.1.49153 > 10.1.1.2.8080: Bendera [.], seq 33280:33784, ack 1, menang 32768, pilihan [TS val 1399 ecr 1394], panjang
...
7.426220 IP 10.1.1.1.49153 > 10.1.1.2.8080: Bendera [.], seq 785704:786240, ack 1, menang 32768, pilihan [TS val 7423 ecr 7421], panjang
9.630693 IP 10.1.1.1.49153 > 10.1.1.2.8080: Bendera [.], seq 882688:883224, ack 1, menang 32768, pilihan [TS val 9620 ecr 9618], panjang

Anda mempunyai fail PCAP dengan paket yang digugurkan dalam simulasi. Tidak ada
paket lain hadir dalam fail dan tiada apa-apa lagi yang hadir untuk menghidupkan
sukar.

Ia adalah satu perjalanan yang panjang, tetapi kita kini berada di titik di mana kita boleh menghargai ns-3
sistem pengesanan. Kami telah menarik peristiwa penting daripada pertengahan pelaksanaan TCP
dan pemacu peranti. Kami menyimpan acara tersebut secara langsung dalam fail yang boleh digunakan dengan yang biasa dikenali
alatan. Kami melakukan ini tanpa mengubah suai mana-mana kod teras yang terlibat, dan kami melakukannya dalam
hanya 18 baris kod:

kekosongan statik
CwndChange (Ptr strim, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*strim->GetStream () << Simulator::Sekarang ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}

...

AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));

...

kekosongan statik
RxDrop (Ptr fail, Ptr p)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Sekarang ().GetSeconds ());
fail->Tulis(Simulator::Now(), p);
}

...

PcapHelper pcapHelper;
Ptr fail = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));

Trace Pembantu
. ns-3 pembantu jejak menyediakan persekitaran yang kaya untuk mengkonfigurasi dan memilih yang berbeza
mengesan peristiwa dan menulisnya ke fail. Dalam bahagian sebelumnya, terutamanya
BuildingTopologies, kami telah melihat beberapa jenis kaedah pembantu jejak yang direka
untuk digunakan di dalam pembantu (peranti) lain.

Mungkin anda akan ingat melihat beberapa variasi ini:

pointToPoint.EnablePcapAll ("second");
pointToPoint.EnablePcap ("second", p2pNodes.Get (0)->GetId (), 0);
csma.EnablePcap ("ketiga", csmaDevices.Get (0), benar);
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

Walau bagaimanapun, apa yang mungkin tidak jelas ialah terdapat model yang konsisten untuk semua
kaedah berkaitan jejak yang terdapat dalam sistem. Kami sekarang akan mengambil sedikit masa dan melihat
pada "gambaran besar".

Pada masa ini terdapat dua kes penggunaan utama pembantu pengesanan masuk ns-3: pembantu peranti
dan pembantu protokol. Pembantu peranti melihat masalah menentukan jejak yang mana
harus didayakan melalui pasangan (nod, peranti). Sebagai contoh, anda mungkin mahu menentukan
bahawa pengesanan PCAP harus didayakan pada peranti tertentu pada nod tertentu. ini
berikutan daripada ns-3 model konsep peranti, dan juga model konseptual
pelbagai pembantu peranti. Mengikuti secara semula jadi daripada ini, fail yang dibuat mengikut a
- - Konvensyen penamaan.

Pembantu protokol melihat masalah menentukan jejak yang harus didayakan
pasangan protokol dan antara muka. Ini berikutan daripada ns-3 berkonsepkan timbunan protokol
model, dan juga model konseptual pembantu tindanan internet. Sememangnya, jejak
fail hendaklah mengikut a - - Konvensyen penamaan.

Oleh itu, pembantu surih jatuh secara semula jadi ke dalam taksonomi dua dimensi. Disana ada
kehalusan yang menghalang keempat-empat kelas daripada berkelakuan sama, tetapi kami berusaha untuk melakukannya
buat mereka semua berfungsi dengan sama yang mungkin; dan bila boleh ada analog untuk
semua kaedah dalam semua kelas.

┌────────────────┬──────┬────────
│ │ PCAP │ ASCII │
└────────────────┴──────┴───────

│Pembantu Peranti │ │ │
├────────────────┼──────┼───────
│Pembantu Protokol │ │ │
└────────────────┴──────┴───────

Kami menggunakan pendekatan yang dipanggil a mixin untuk menambah fungsi pengesanan pada kelas pembantu kami. A
mixin ialah kelas yang menyediakan kefungsian apabila ia diwarisi oleh subkelas.
Mewarisi daripada mixin tidak dianggap sebagai satu bentuk pengkhususan tetapi benar-benar cara untuk
mengumpul fungsi.

Mari kita lihat dengan cepat keempat-empat kes ini dan masing-masing campuran.

Peranti Pembantu
PCAP
Matlamat pembantu ini adalah untuk memudahkan untuk menambah kemudahan jejak PCAP yang konsisten pada
ns-3 peranti. Kami mahu semua pelbagai rasa pengesanan PCAP berfungsi sama di seluruh
semua peranti, jadi kaedah pembantu ini diwarisi oleh pembantu peranti. Tengoklah
at src/network/helper/trace-helper.h kalau nak ikut perbincangan sambil tengok
kod sebenar.

Kelas PcapHelperForDevice ialah mixin menyediakan fungsi tahap tinggi untuk digunakan
Pengesanan PCAP dalam ns-3 peranti. Setiap peranti mesti melaksanakan kaedah maya tunggal
diwarisi daripada kelas ini.

kekosongan maya EnablePcapInternal (std::prefix string, Ptr nd, bool promiscuous, bool explicitFilename) = 0;

Tandatangan kaedah ini mencerminkan pandangan tertumpu peranti pada situasi ini
tahap. Semua kaedah awam yang diwarisi daripada kelas PcapUserHelperForDevice kurangkan kepada
memanggil kaedah pelaksanaan yang bergantung kepada peranti tunggal ini. Sebagai contoh, peringkat paling rendah
kaedah PCAP,

void EnablePcap (std::prefix string, Ptr nd, bool promiscuous = palsu, bool explicitFilename = false);

akan memanggil pelaksanaan peranti bagi EnablePcapInternal secara langsung. Semua PCAP awam lain
kaedah pengesanan membina pelaksanaan ini untuk menyediakan tahap pengguna tambahan
kefungsian. Maksudnya kepada pengguna ialah semua pembantu peranti dalam sistem akan melakukannya
mempunyai semua kaedah surih PCAP tersedia; dan kaedah ini semuanya akan berfungsi dengan sama
merentasi peranti jika peranti melaksanakan EnablePcapInternal betul.

Kaedah
void EnablePcap (std::prefix string, Ptr nd, bool promiscuous = palsu, bool explicitFilename = false);
void EnablePcap (std::prefix string, std::string ndName, bool promiscuous = false, bool explicitFilename = false);
void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false);
void EnablePcap (std::prefix string, NodeContainer n, bool promiscuous = false);
void EnablePcap (std::prefix string, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
void EnablePcapAll (std::prefix string, bool promiscuous = false);

Dalam setiap kaedah yang ditunjukkan di atas, terdapat parameter lalai yang dipanggil rambang mata Bahawa
lalai kepada palsu. Parameter ini menunjukkan bahawa jejak tidak boleh dikumpulkan
mod rambang mata. Jika anda mahu jejak anda memasukkan semua trafik yang dilihat oleh peranti
(dan jika peranti menyokong mod promiscuous) cuma tambahkan parameter sebenar pada mana-mana
panggilan di atas. Sebagai contoh,

Ptr nd;
...
helper.EnablePcap ("prefix", nd, true);

akan membolehkan tangkapan mod rambang pada NetDevice ditentukan oleh nd.

Dua kaedah pertama juga termasuk parameter lalai yang dipanggil Nama fail eksplisit itu akan
dibincangkan di bawah.

Anda digalakkan untuk meneliti Dokumentasi API untuk kelas PcapHelperForDevice untuk mencari
butiran kaedah ini; tapi untuk meringkaskan...

· Anda boleh mendayakan pengesanan PCAP pada pasangan nod/peranti bersih tertentu dengan menyediakan a
Ptr kepada EnablePcap kaedah. The Ptr adalah tersirat sejak peranti bersih
mesti tergolong dalam satu Nod. Sebagai contoh,

Ptr nd;
...
helper.EnablePcap ("prefix", nd);

· Anda boleh mendayakan pengesanan PCAP pada pasangan nod/peranti bersih tertentu dengan menyediakan a
std :: tali mewakili rentetan perkhidmatan nama objek kepada an EnablePcap kaedah. The
Ptr dilihat dari rentetan nama. Sekali lagi, yang adalah tersirat sejak
peranti bersih yang dinamakan mestilah milik tepat satu Nod. Sebagai contoh,

Nama::Tambah ("pelayan" ...);
Names::Add ("server/eth0" ...);
...
helper.EnablePcap ("prefix", "server/ath0");

· Anda boleh mendayakan pengesanan PCAP pada koleksi pasangan nod/peranti bersih dengan menyediakan a
NetDeviceContainer. Untuk setiap NetDevice dalam bekas jenis diperiksa. Untuk setiap
peranti jenis yang betul (jenis yang sama seperti yang diuruskan oleh pembantu peranti), pengesanan adalah
didayakan. Sekali lagi, yang adalah tersirat kerana peranti bersih yang ditemui mesti dimiliki
tepat satu Nod. Sebagai contoh,

NetDeviceContainer d = ...;
...
helper.EnablePcap ("prefix", d);

· Anda boleh mendayakan pengesanan PCAP pada koleksi pasangan nod/peranti bersih dengan menyediakan a
NodeContainer. Untuk setiap Nod dalam NodeContainer ia dilampirkan NetDevices diulang.
Bagi setiap NetDevice dilampirkan pada setiap Nod dalam bekas, jenis peranti itu
diperiksa. Untuk setiap peranti jenis yang betul (jenis yang sama seperti yang diuruskan oleh peranti
penolong), pengesanan didayakan.

NodeContainer n;
...
helper.EnablePcap ("prefix", n);

· Anda boleh mendayakan pengesanan PCAP berdasarkan Node ID dan ID peranti serta dengan
jelas Ptr. Setiap Nod dalam sistem mempunyai ID Nod integer dan setiap peranti disambungkan
kepada Nod mempunyai ID peranti integer.

helper.EnablePcap ("prefix", 21, 1);

· Akhir sekali, anda boleh mendayakan pengesanan PCAP untuk semua peranti dalam sistem, dengan jenis yang sama
seperti yang diuruskan oleh pembantu peranti.

helper.EnablePcapAll ("awalan");

Nama fail
Tersirat dalam huraian kaedah di atas ialah pembinaan nama fail lengkap oleh
kaedah pelaksanaan. Mengikut konvensyen, jejak PCAP dalam ns-3 sistem adalah dalam bentuk
- id>- id>.pcap

Seperti yang dinyatakan sebelum ini, setiap Nod dalam sistem akan mempunyai id Nod yang diberikan sistem; dan
setiap peranti akan mempunyai indeks antara muka (juga dipanggil id peranti) berbanding nodnya.
Secara lalai, fail jejak PCAP dibuat hasil daripada mendayakan pengesanan pada yang pertama
peranti Nod 21 menggunakan awalan "awalan" akan menjadi awalan-21-1.pcap.

Anda sentiasa boleh menggunakan ns-3 perkhidmatan nama objek untuk menjadikannya lebih jelas. Sebagai contoh, jika
anda menggunakan perkhidmatan nama objek untuk memberikan nama "pelayan" kepada Node 21, PCAP yang terhasil
nama fail jejak akan secara automatik menjadi, prefix-server-1.pcap dan jika anda juga menetapkan
namakan "eth0" pada peranti, nama fail PCAP anda akan secara automatik mengambilnya dan menjadi
dipanggil prefix-server-eth0.pcap.

Akhir sekali, dua daripada kaedah yang ditunjukkan di atas,

void EnablePcap (std::prefix string, Ptr nd, bool promiscuous = palsu, bool explicitFilename = false);
void EnablePcap (std::prefix string, std::string ndName, bool promiscuous = false, bool explicitFilename = false);

mempunyai parameter lalai yang dipanggil Nama fail eksplisit. Apabila ditetapkan kepada benar, parameter ini
melumpuhkan mekanisme penyiapan nama fail automatik dan membolehkan anda mencipta eksplisit
nama fail. Pilihan ini hanya tersedia dalam kaedah yang membolehkan pengesanan PCAP pada a
peranti tunggal.

Contohnya, untuk mengatur pembantu peranti untuk mencipta satu PCAP rambang
menangkap fail dengan nama tertentu my-pcap-file.pcap pada peranti tertentu, seseorang boleh:

Ptr nd;
...
helper.EnablePcap ("my-pcap-file.pcap", nd, true, true);

Yang pertama benar parameter membolehkan jejak mod promiscuous dan yang kedua memberitahu pembantu
untuk mentafsir awalan parameter sebagai nama fail lengkap.

ASCII
Tingkah laku pembantu jejak ASCII mixin hampir serupa dengan versi PCAP.
Sila lihat pada src/network/helper/trace-helper.h kalau nak ikut perbincangan
sambil melihat kod sebenar.

Kelas AsciiTraceHelperForDevice menambah fungsi tahap tinggi untuk menggunakan ASCII
mengesan ke kelas pembantu peranti. Seperti dalam kes PCAP, setiap peranti mesti melaksanakan a
kaedah maya tunggal yang diwarisi daripada jejak ASCII mixin.

kekosongan maya EnableAsciiInternal (Ptr aliran,
std:: awalan rentetan,
Ptr nd,
bool explicitFilename) = 0;

Tandatangan kaedah ini mencerminkan pandangan tertumpu peranti pada situasi ini
peringkat; dan juga fakta bahawa pembantu mungkin menulis kepada aliran output yang dikongsi. Semuanya
kaedah berkaitan jejak ASCII awam yang diwarisi daripada kelas AsciiTraceHelperForDevice
kurangkan untuk memanggil kaedah pelaksanaan yang bergantung kepada peranti tunggal ini. Sebagai contoh, yang
kaedah jejak ascii peringkat terendah,

void EnableAscii (std::prefix string, Ptr nd, bool explicitFilename = false);
batal EnableAscii (Ptr aliran, Ptr nd);

akan memanggil pelaksanaan peranti bagi EnableAsciiInternal secara langsung, menyediakan sama ada a
awalan atau aliran yang sah. Semua kaedah pengesanan ASCII awam lain akan dibina berdasarkan kaedah ini
fungsi peringkat rendah untuk menyediakan fungsi peringkat pengguna tambahan. Apakah maksudnya
pengguna ialah semua pembantu peranti dalam sistem akan mempunyai semua kaedah surih ASCII
tersedia; dan kaedah ini semuanya akan berfungsi dengan cara yang sama merentas peranti jika peranti itu
melaksanakan EnablAsciiInternal betul.

Kaedah
void EnableAscii (std::prefix string, Ptr nd, bool explicitFilename = false);
batal EnableAscii (Ptr aliran, Ptr nd);

void EnableAscii (std::prefix string, std::string ndName, bool explicitFilename = false);
batal EnableAscii (Ptr strim, std::string ndName);

void EnableAscii (std::prefix string, NetDeviceContainer d);
batal EnableAscii (Ptr strim, NetDeviceContainer d);

void EnableAscii (std::prefix string, NodeContainer n);
batal EnableAscii (Ptr strim, NodeContainer n);

batal EnableAsciiAll (std:: awalan rentetan);
batal EnableAsciiAll (Ptr aliran);

void EnableAscii (std::prefix string, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
batal EnableAscii (Ptr strim, uint32_t nodeid, uint32_t deviceid);

Anda digalakkan untuk meneliti Dokumentasi API untuk kelas AsciiTraceHelperForDevice kepada
cari butiran kaedah ini; tapi untuk meringkaskan...

· Terdapat dua kali lebih banyak kaedah yang tersedia untuk pengesanan ASCII berbanding PCAP
menjejak. Ini kerana, sebagai tambahan kepada model gaya PCAP di mana jejak dari setiap
pasangan nod/peranti unik ditulis pada fail unik, kami menyokong model di mana surih
maklumat untuk banyak pasangan nod/peranti ditulis pada fail biasa. Ini bermakna bahawa
- - mekanisme penjanaan nama fail digantikan dengan mekanisme untuk
merujuk kepada fail biasa; dan bilangan kaedah API digandakan untuk membolehkan semua
gabungan.

· Sama seperti dalam pengesanan PCAP, anda boleh mendayakan pengesanan ASCII pada (nod, peranti bersih) tertentu
berpasangan dengan menyediakan a Ptr kepada EnableAscii kaedah. The Ptr adalah tersirat
memandangkan peranti bersih mestilah milik tepat satu Nod. Sebagai contoh,

Ptr nd;
...
helper.EnableAscii ("prefix", nd);

· Empat kaedah pertama juga termasuk parameter lalai yang dipanggil Nama fail eksplisit Bahawa
beroperasi serupa dengan parameter yang setara dalam kes PCAP.

Dalam kes ini, tiada konteks jejak ditulis pada fail surih ASCII kerana ia akan menjadi
berlebihan. Sistem akan memilih nama fail yang akan dibuat menggunakan peraturan yang sama seperti
diterangkan dalam bahagian PCAP, kecuali fail tersebut akan mempunyai akhiran .tr bukan
.pcap.

· Jika anda ingin mendayakan pengesanan ASCII pada lebih daripada satu peranti bersih dan semua jejak dihantar
kepada satu fail, anda boleh melakukannya juga dengan menggunakan objek untuk merujuk kepada satu fail.
Kami telah melihat ini dalam contoh "cwnd" di atas:

Ptr nd1;
Ptr nd2;
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (strim, nd1);
helper.EnableAscii (strim, nd2);

Dalam kes ini, jejak konteks adalah ditulis ke fail surih ASCII kerana ia diperlukan
untuk menyahkekaburan kesan daripada kedua-dua peranti. Ambil perhatian bahawa sejak pengguna sepenuhnya
menyatakan nama fail, rentetan itu hendaklah termasuk ,tr akhiran untuk konsistensi.

· Anda boleh mendayakan pengesanan ASCII pada pasangan tertentu (nod, peranti bersih) dengan menyediakan a
std :: tali mewakili rentetan perkhidmatan nama objek kepada an EnablePcap kaedah. The
Ptr dilihat dari rentetan nama. Sekali lagi, yang adalah tersirat sejak
peranti bersih yang dinamakan mestilah milik tepat satu Nod. Sebagai contoh,

Nama::Tambah ("klien" ...);
Nama::Tambah ("klien/eth0" ...);
Nama::Tambah ("pelayan" ...);
Names::Add ("server/eth0" ...);
...
helper.EnableAscii ("prefix", "client/eth0");
helper.EnableAscii ("prefix", "server/eth0");

Ini akan menghasilkan dua fail bernama ``prefix-client-eth0.tr`` dan
``prefix-server-eth0.tr`` dengan kesan untuk setiap peranti dalam
fail surih masing-masing. Oleh kerana semua fungsi ``EnableAscii``
terbeban untuk mengambil pembalut aliran, anda boleh menggunakan borang itu sebagai
baiklah::

Nama::Tambah ("klien" ...);
Nama::Tambah ("klien/eth0" ...);
Nama::Tambah ("pelayan" ...);
Names::Add ("server/eth0" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (strim, "klien/eth0");
helper.EnableAscii (strim, "server/eth0");

Ini akan menghasilkan satu fail jejak dipanggil trace-file-name.tr yang mengandungi semua
peristiwa surih untuk kedua-dua peranti. Peristiwa itu akan dinyahkekaburan mengikut konteks jejak
tali.

· Anda boleh mendayakan pengesanan ASCII pada koleksi pasangan (nod, peranti bersih) dengan menyediakan a
NetDeviceContainer. Untuk setiap NetDevice dalam bekas jenis diperiksa. Untuk setiap
peranti jenis yang betul (jenis yang sama seperti yang diuruskan oleh pembantu peranti), pengesanan adalah
didayakan. Sekali lagi, yang adalah tersirat kerana peranti bersih yang ditemui mesti dimiliki
tepat satu Nod. Sebagai contoh,

NetDeviceContainer d = ...;
...
helper.EnableAscii ("awalan", d);

Ini akan menyebabkan beberapa fail surih ASCII dicipta,
yang setiap satunya mengikut `` - - .tr``
konvensyen.

Menggabungkan semua jejak ke dalam satu fail dicapai sama seperti contoh
atas:

NetDeviceContainer d = ...;
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (strim, d);

· Anda boleh mendayakan pengesanan ASCII pada koleksi pasangan (nod, peranti bersih) dengan menyediakan a
NodeContainer. Untuk setiap Nod dalam NodeContainer ia dilampirkan NetDevices diulang.
Bagi setiap NetDevice dilampirkan pada setiap Nod dalam bekas, jenis peranti itu
diperiksa. Untuk setiap peranti jenis yang betul (jenis yang sama seperti yang diuruskan oleh peranti
penolong), pengesanan didayakan.

NodeContainer n;
...
helper.EnableAscii ("awalan", n);

Ini akan menyebabkan beberapa fail surih ASCII dibuat, setiap satu daripadanya akan menyusul
yang - id>- id>.tr konvensyen. Menggabungkan semua jejak menjadi a
fail tunggal dicapai sama seperti contoh di atas.

· Anda boleh mendayakan pengesanan PCAP berdasarkan Node ID dan ID peranti serta dengan
jelas Ptr. Setiap Nod dalam sistem mempunyai ID Nod integer dan setiap peranti disambungkan
kepada Nod mempunyai ID peranti integer.

helper.EnableAscii ("prefix", 21, 1);

Sudah tentu, jejak boleh digabungkan menjadi satu fail seperti yang ditunjukkan di atas.

· Akhir sekali, anda boleh mendayakan pengesanan PCAP untuk semua peranti dalam sistem, dengan jenis yang sama
seperti yang diuruskan oleh pembantu peranti.

helper.EnableAsciiAll ("awalan");

Ini akan menyebabkan beberapa fail surih ASCII dibuat, satu untuk setiap peranti
dalam sistem jenis yang diuruskan oleh pembantu. Semua fail ini akan mengikuti
- id>- id>.tr konvensyen. Menggabungkan semua jejak menjadi satu
fail dicapai sama seperti contoh di atas.

Nama fail
Tersirat dalam huraian kaedah gaya awalan di atas ialah pembinaan lengkap
nama fail dengan kaedah pelaksanaan. Mengikut konvensyen, jejak ASCII dalam ns-3 sistem
adalah dalam bentuk - id>- id>.tr

Seperti yang dinyatakan sebelum ini, setiap Nod dalam sistem akan mempunyai id Nod yang diberikan sistem; dan
setiap peranti akan mempunyai indeks antara muka (juga dipanggil id peranti) berbanding nodnya.
Secara lalai, fail surih ASCII dibuat hasil daripada mendayakan pengesanan pada yang pertama
peranti Nod 21, menggunakan awalan "awalan", adalah awalan-21-1.tr.

Anda sentiasa boleh menggunakan ns-3 perkhidmatan nama objek untuk menjadikannya lebih jelas. Sebagai contoh, jika
anda menggunakan perkhidmatan nama objek untuk memberikan nama "pelayan" kepada Node 21, yang terhasil
Nama fail surih ASCII secara automatik akan menjadi, prefix-server-1.tr dan jika anda juga menetapkan
nama "eth0" pada peranti, nama fail surih ASCII anda akan mengambilnya secara automatik
dan dipanggil prefix-server-eth0.tr.

Beberapa kaedah mempunyai parameter lalai yang dipanggil Nama fail eksplisit. Apabila ditetapkan kepada
benar, parameter ini melumpuhkan mekanisme penyiapan nama fail automatik dan membolehkan anda
untuk mencipta nama fail yang jelas. Pilihan ini hanya tersedia dalam kaedah yang mengambil a
awalan dan dayakan pengesanan pada satu peranti.

Protokol Pembantu
PCAP
Matlamat ini campuran adalah untuk memudahkan menambah kemudahan jejak PCAP yang konsisten kepada
protokol. Kami mahu semua pelbagai rasa pengesanan PCAP berfungsi sama di semua
protokol, jadi kaedah pembantu ini diwarisi oleh pembantu tindanan. Lihatlah
src/network/helper/trace-helper.h kalau nak ikut perbincangan sambil tengok
kod sebenar.

Dalam bahagian ini kita akan menggambarkan kaedah seperti yang digunakan pada protokol IPv4. Untuk
nyatakan jejak dalam protokol yang serupa, cuma gantikan jenis yang sesuai. Sebagai contoh,
gunakan a Ptr bukan a Ptr dan panggil DayakanPcapIpv6 bukan DayakanPcapIpv4.

Kelas PcapHelperForIpv4 menyediakan fungsi tahap tinggi untuk menggunakan pengesanan PCAP
dalam IPv4 protokol. Setiap pembantu protokol yang membolehkan kaedah ini mesti melaksanakan satu
kaedah maya yang diwarisi daripada kelas ini. Akan ada pelaksanaan yang berasingan untuk
IPv6, sebagai contoh, tetapi satu-satunya perbezaan adalah dalam nama kaedah dan tandatangan.
Nama kaedah yang berbeza diperlukan untuk menyahkekaburan kelas IPv4 dari IPv6 yang kedua-duanya
berasal dari kelas Objek, dan kaedah yang berkongsi tandatangan yang sama.

kekosongan maya EnablePcapIpv4Internal (std::prefiks rentetan,
Ptr ipv4,
antara muka uint32_t,
bool explicitFilename) = 0;

Tandatangan kaedah ini mencerminkan protokol dan paparan berpusat antara muka
situasi di peringkat ini. Semua kaedah awam yang diwarisi daripada kelas PcapHelperForIpv4
kurangkan untuk memanggil kaedah pelaksanaan yang bergantung kepada peranti tunggal ini. Sebagai contoh, yang
kaedah PCAP tahap terendah,

void EnablePcapIpv4 (std::prefix string, Ptr ipv4, antara muka uint4_t, bool explicitFilename = false);

akan memanggil pelaksanaan peranti bagi EnablePcapIpv4Internal secara langsung. Semua orang awam lain
Kaedah pengesanan PCAP membina pelaksanaan ini untuk menyediakan tahap pengguna tambahan
kefungsian. Maksudnya kepada pengguna ialah semua pembantu protokol dalam sistem
akan mempunyai semua kaedah surih PCAP tersedia; dan kaedah ini semua akan berfungsi dalam
cara yang sama merentasi protokol jika pembantu melaksanakan EnablePcapIpv4Internal betul.

Kaedah
Kaedah-kaedah ini direka bentuk untuk berada dalam surat-menyurat satu dengan satu dengan Node- dan
NetDevice- versi sentrik versi peranti. Daripada Node dan NetDevice pasangan
kekangan, kami menggunakan protokol dan kekangan antara muka.

Ambil perhatian bahawa sama seperti dalam versi peranti, terdapat enam kaedah:

void EnablePcapIpv4 (std::prefix string, Ptr ipv4, antara muka uint4_t, bool explicitFilename = false);
void EnablePcapIpv4 (std::prefix string, std::string ipv4Name, antara muka uint32_t, bool explicitFilename = false);
void EnablePcapIpv4 (std::prefix string, Ipv4InterfaceContainer c);
void EnablePcapIpv4 (std::prefix string, NodeContainer n);
void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface, bool explicitFilename);
batal EnablePcapIpv4All (std::prefix string);

Anda digalakkan untuk meneliti Dokumentasi API untuk kelas PcapHelperForIpv4 untuk mencari
butiran kaedah ini; tapi untuk meringkaskan...

· Anda boleh mendayakan pengesanan PCAP pada pasangan protokol/antara muka tertentu dengan menyediakan a
Ptr and antara muka kepada EnablePcap kaedah. Sebagai contoh,

Ptr ipv4 = nod->GetObject ();
...
helper.EnablePcapIpv4 ("prefix", ipv4, 0);

· Anda boleh mendayakan pengesanan PCAP pada pasangan nod/peranti bersih tertentu dengan menyediakan a
std :: tali mewakili rentetan perkhidmatan nama objek kepada an EnablePcap kaedah. The
Ptr dilihat dari rentetan nama. Sebagai contoh,

Names::Add ("serverIPv4" ...);
...
helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1);

· Anda boleh mendayakan pengesanan PCAP pada koleksi pasangan protokol/antara muka dengan menyediakan satu
Ipv4InterfaceContainer. Untuk setiap IPv4 / antara muka pasangan dalam bekas protokol
jenis disemak. Untuk setiap protokol jenis yang betul (jenis yang sama seperti yang diuruskan oleh
pembantu peranti), pengesanan didayakan untuk antara muka yang sepadan. Sebagai contoh,

NodeContainer nod;
...
Peranti NetDeviceContainer = deviceHelper.Install (nod);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Antara muka Ipv4InterfaceContainer = ipv4.Assign (peranti);
...
helper.EnablePcapIpv4 ("awalan", antara muka);

· Anda boleh mendayakan pengesanan PCAP pada koleksi pasangan protokol/antara muka dengan menyediakan a
NodeContainer. Untuk setiap Nod dalam NodeContainer protokol yang sesuai ditemui.
Untuk setiap protokol, antara mukanya dikira dan pengesanan didayakan pada yang terhasil
berpasangan. Sebagai contoh,

NodeContainer n;
...
helper.EnablePcapIpv4 ("prefix", n);

· Anda boleh mendayakan pengesanan PCAP berdasarkan Node ID dan antara muka juga. Di dalam ini
kes, nod-id diterjemahkan kepada a Ptr dan protokol yang sesuai dicari
dalam nod. Protokol dan antara muka yang terhasil digunakan untuk menentukan yang terhasil
sumber jejak.

helper.EnablePcapIpv4 ("prefix", 21, 1);

· Akhir sekali, anda boleh mendayakan pengesanan PCAP untuk semua antara muka dalam sistem, dengan yang berkaitan
protokol adalah jenis yang sama seperti yang diuruskan oleh pembantu peranti.

helper.EnablePcapIpv4All ("awalan");

Nama fail
Tersirat dalam semua huraian kaedah di atas adalah pembinaan lengkap
nama fail dengan kaedah pelaksanaan. Mengikut konvensyen, jejak PCAP diambil untuk peranti dalam
yang ns-3 sistem adalah dalam bentuk " - - .pcap". Dalam kes
jejak protokol, terdapat surat-menyurat satu dengan satu antara protokol dan Nod. ini
adalah kerana protokol Objek diagregatkan kepada nod Objek. Oleh kerana tiada global
id protokol dalam sistem, kami menggunakan id Nod yang sepadan dalam penamaan fail. Oleh itu
terdapat kemungkinan perlanggaran nama fail dalam nama fail surih yang dipilih secara automatik.
Atas sebab ini, konvensyen nama fail ditukar untuk jejak protokol.

Seperti yang dinyatakan sebelum ini, setiap Nod dalam sistem akan mempunyai id Nod yang diberikan sistem.
Memandangkan terdapat surat-menyurat satu dengan satu antara contoh protokol dan tika Node
kami menggunakan id Nod. Setiap antara muka mempunyai id antara muka berbanding protokolnya. Kami guna
konvensyen" -n -i .pcap" untuk penamaan fail surih masuk
pembantu protokol.

Oleh itu, secara lalai, fail jejak PCAP dibuat hasil daripada mendayakan pengesanan dihidupkan
antara muka 1 protokol Ipv4 Node 21 menggunakan awalan "awalan" akan menjadi
"prefix-n21-i1.pcap".

Anda sentiasa boleh menggunakan ns-3 perkhidmatan nama objek untuk menjadikannya lebih jelas. Sebagai contoh, jika
anda menggunakan perkhidmatan nama objek untuk memberikan nama "serverIpv4" kepada Ptr pada Node
21, nama fail surih PCAP yang terhasil akan secara automatik menjadi,
"prefix-nserverIpv4-i1.pcap".

Beberapa kaedah mempunyai parameter lalai yang dipanggil Nama fail eksplisit. Apabila ditetapkan kepada
benar, parameter ini melumpuhkan mekanisme penyiapan nama fail automatik dan membolehkan anda
untuk mencipta nama fail yang jelas. Pilihan ini hanya tersedia dalam kaedah yang mengambil a
awalan dan dayakan pengesanan pada satu peranti.

ASCII
Tingkah laku pembantu surih ASCII adalah serupa dengan kes PCAP. Ambil a
lihat pada src/network/helper/trace-helper.h kalau nak ikut perbincangan sambil
melihat kod sebenar.

Dalam bahagian ini kita akan menggambarkan kaedah seperti yang digunakan pada protokol IPv4. Untuk
nyatakan jejak dalam protokol yang serupa, cuma gantikan jenis yang sesuai. Sebagai contoh,
gunakan a Ptr bukan a Ptr dan panggil EnableAsciiIpv6 bukan
EnableAsciiIpv4.

Kelas AsciiTraceHelperForIpv4 menambah fungsi tahap tinggi untuk menggunakan ASCII
mengesan kepada pembantu protokol. Setiap protokol yang membolehkan kaedah ini mesti melaksanakan a
kaedah maya tunggal yang diwarisi daripada kelas ini.

kekosongan maya EnableAsciiIpv4Internal (Ptr aliran,
std:: awalan rentetan,
Ptr ipv4,
antara muka uint32_t,
bool explicitFilename) = 0;

Tandatangan kaedah ini mencerminkan paparan protokol dan berpusat antara muka
keadaan pada tahap ini; dan juga fakta bahawa pembantu itu mungkin menulis kepada yang dikongsi
aliran keluaran. Semua kaedah awam yang diwarisi daripada kelas
PcapAndAsciiTraceHelperForIpv4 kurangkan panggilan yang bergantung kepada peranti tunggal ini
kaedah pelaksanaan. Sebagai contoh, kaedah surih ASCII tahap terendah,

batal EnableAsciiIpv4 (std::awalan rentetan, Ptr ipv4, antara muka uint4_t, bool explicitFilename = false);
batal EnableAsciiIpv4 (Ptr aliran, Ptr ipv4, antara muka uint4_t);

akan memanggil pelaksanaan peranti bagi EnableAsciiIpv4Internal secara langsung, menyediakan sama ada
awalan atau aliran. Semua kaedah pengesanan ASCII awam lain akan dibina berdasarkan kaedah ini
fungsi peringkat rendah untuk menyediakan fungsi peringkat pengguna tambahan. Apakah maksudnya
pengguna ialah semua pembantu peranti dalam sistem akan mempunyai semua kaedah surih ASCII
tersedia; dan kaedah ini semuanya akan berfungsi dengan cara yang sama merentas protokol jika
protokol dilaksanakan EnablAsciiIpv4Internal betul.

Kaedah
batal EnableAsciiIpv4 (std::awalan rentetan, Ptr ipv4, antara muka uint4_t, bool explicitFilename = false);
batal EnableAsciiIpv4 (Ptr aliran, Ptr ipv4, antara muka uint4_t);

void EnableAsciiIpv4 (std::prefix string, std::string ipv4Name, antara muka uint32_t, bool explicitFilename = false);
batal EnableAsciiIpv4 (Ptr strim, std::string ipv4Name, antara muka uint32_t);

void EnableAsciiIpv4 (std::prefix string, Ipv4InterfaceContainer c);
batal EnableAsciiIpv4 (Ptr strim, Ipv4InterfaceContainer c);

void EnableAsciiIpv4 (std::prefix string, NodeContainer n);
batal EnableAsciiIpv4 (Ptr strim, NodeContainer n);

batal EnableAsciiIpv4All (std::prefix string);
batal EnableAsciiIpv4All (Ptr aliran);

void EnableAsciiIpv4 (std:: rentetan awalan, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
batal EnableAsciiIpv4 (Ptr strim, nodeid uint32_t, antara muka uint32_t);

Anda digalakkan untuk meneliti Dokumentasi API untuk kelas PcapAndAsciiHelperForIpv4 kepada
cari butiran kaedah ini; tapi untuk meringkaskan...

· Terdapat dua kali lebih banyak kaedah yang tersedia untuk pengesanan ASCII berbanding PCAP
menjejak. Ini kerana, sebagai tambahan kepada model gaya PCAP di mana jejak dari setiap
pasangan protokol/antara muka unik ditulis pada fail unik, kami menyokong model di mana
maklumat surih untuk banyak pasangan protokol/antara muka ditulis pada fail biasa. ini
bermakna bahawa -n - mekanisme penjanaan nama fail ialah
digantikan dengan mekanisme untuk merujuk kepada fail biasa; dan bilangan kaedah API ialah
dua kali ganda untuk membenarkan semua kombinasi.

· Sama seperti dalam pengesanan PCAP, anda boleh mendayakan pengesanan ASCII pada protokol/antara muka tertentu
berpasangan dengan menyediakan a Ptr dan antara muka kepada EnableAscii kaedah. Sebagai contoh,

Ptr ipv4;
...
helper.EnableAsciiIpv4 ("prefix", ipv4, 1);

Dalam kes ini, tiada konteks jejak ditulis pada fail surih ASCII kerana ia akan menjadi
berlebihan. Sistem akan memilih nama fail yang akan dibuat menggunakan peraturan yang sama seperti
diterangkan dalam bahagian PCAP, kecuali fail itu akan mempunyai akhiran ".tr" sebaliknya
daripada ".pcap".

· Jika anda ingin mendayakan pengesanan ASCII pada lebih daripada satu antara muka dan semua jejak dihantar
kepada satu fail, anda boleh melakukannya juga dengan menggunakan objek untuk merujuk kepada satu fail.
Kami sudah mempunyai sesuatu yang serupa dengan ini dalam contoh "cwnd" di atas:

Ptr protocol4 = node1->GetObject ();
Ptr protocol4 = node2->GetObject ();
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (strim, protocol1, 1);
helper.EnableAsciiIpv4 (strim, protocol2, 1);

Dalam kes ini, konteks surih ditulis pada fail surih ASCII kerana ia diperlukan
untuk menyahkekaburan jejak daripada dua antara muka. Ambil perhatian bahawa sejak pengguna sepenuhnya
dengan menyatakan nama fail, rentetan harus memasukkan ",tr" untuk konsistensi.

· Anda boleh mendayakan pengesanan ASCII pada protokol tertentu dengan menyediakan a std :: tali
mewakili rentetan perkhidmatan nama objek kepada an EnablePcap kaedah. The Ptr is
mendongak dari rentetan nama. The dalam nama fail yang terhasil adalah tersirat sejak
terdapat korespondensi satu dengan satu antara contoh protokol dan nod, Contohnya,

Names::Add ("node1Ipv4" ...);
Names::Add ("node2Ipv4" ...);
...
helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1);
helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1);

Ini akan menghasilkan dua fail bernama "prefix-nnode1Ipv4-i1.tr" dan
"prefix-nnode2Ipv4-i1.tr" dengan jejak untuk setiap antara muka dalam fail surih masing-masing.
Memandangkan semua fungsi EnableAscii dibebankan untuk mengambil pembalut strim, anda boleh
gunakan borang itu juga:

Names::Add ("node1Ipv4" ...);
Names::Add ("node2Ipv4" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (strim, "node1Ipv4", 1);
helper.EnableAsciiIpv4 (strim, "node2Ipv4", 1);

Ini akan menghasilkan fail surih tunggal yang dipanggil "nama fail surih.tr" yang mengandungi semua
peristiwa surih untuk kedua-dua antara muka. Peristiwa-peristiwa itu akan diluahkan dengan jejak
rentetan konteks.

· Anda boleh mendayakan pengesanan ASCII pada koleksi pasangan protokol/antara muka dengan menyediakan satu
Ipv4InterfaceContainer. Untuk setiap protokol jenis yang betul (jenis yang sama seperti
diuruskan oleh pembantu peranti), pengesanan didayakan untuk antara muka yang sepadan.
Sekali lagi, adalah tersirat kerana terdapat surat-menyurat satu dengan satu antara setiap satu
protokol dan nodnya. Sebagai contoh,

NodeContainer nod;
...
Peranti NetDeviceContainer = deviceHelper.Install (nod);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Antara muka Ipv4InterfaceContainer = ipv4.Assign (peranti);
...
...
helper.EnableAsciiIpv4 ("awalan", antara muka);

Ini akan menyebabkan beberapa fail surih ASCII dibuat, setiap satu daripadanya akan menyusul
yang -n -i .tr konvensyen. Menggabungkan semua jejak menjadi a
fail tunggal dicapai sama seperti contoh di atas:

NodeContainer nod;
...
Peranti NetDeviceContainer = deviceHelper.Install (nod);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Antara muka Ipv4InterfaceContainer = ipv4.Assign (peranti);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (strim, antara muka);

· Anda boleh mendayakan pengesanan ASCII pada koleksi pasangan protokol/antara muka dengan menyediakan a
NodeContainer. Untuk setiap Nod dalam NodeContainer protokol yang sesuai ditemui.
Untuk setiap protokol, antara mukanya dikira dan pengesanan didayakan pada yang terhasil
berpasangan. Sebagai contoh,

NodeContainer n;
...
helper.EnableAsciiIpv4 ("prefix", n);

Ini akan menyebabkan beberapa fail surih ASCII dibuat, setiap satu daripadanya akan menyusul
yang - - .tr konvensyen. Menggabungkan semua jejak menjadi a
fail tunggal dicapai sama seperti contoh di atas.

· Anda boleh mendayakan pengesanan PCAP berdasarkan Node ID dan ID peranti juga. Di dalam ini
kes, nod-id diterjemahkan kepada a Ptr dan protokol yang sesuai dicari
dalam nod. Protokol dan antara muka yang terhasil digunakan untuk menentukan yang terhasil
sumber jejak.

helper.EnableAsciiIpv4 ("prefix", 21, 1);

Sudah tentu, jejak boleh digabungkan menjadi satu fail seperti yang ditunjukkan di atas.

· Akhir sekali, anda boleh mendayakan pengesanan ASCII untuk semua antara muka dalam sistem, dengan yang berkaitan
protokol adalah jenis yang sama seperti yang diuruskan oleh pembantu peranti.

helper.EnableAsciiIpv4All ("awalan");

Ini akan menyebabkan beberapa fail surih ASCII dicipta, satu untuk setiap
antara muka dalam sistem yang berkaitan dengan protokol jenis yang diuruskan oleh pembantu. Semuanya
fail ini akan mengikuti -n -i
semua jejak ke dalam satu fail dicapai sama seperti contoh di atas.

Nama fail
Tersirat dalam huraian kaedah gaya awalan di atas ialah pembinaan lengkap
nama fail dengan kaedah pelaksanaan. Mengikut konvensyen, jejak ASCII dalam ns-3 sistem
adalah dalam bentuk " - - .tr"

Seperti yang dinyatakan sebelum ini, setiap Nod dalam sistem akan mempunyai id Nod yang diberikan sistem.
Oleh kerana terdapat surat-menyurat satu dengan satu antara protokol dan nod yang kami gunakan untuk nod-id
untuk mengenal pasti identiti protokol. Setiap antara muka pada protokol tertentu akan mempunyai
indeks antara muka (juga dipanggil hanya antara muka) berbanding protokolnya. Secara lalai,
kemudian, fail surih ASCII dibuat hasil daripada mendayakan pengesanan pada peranti pertama
Nod 21, menggunakan awalan "awalan", akan menjadi "awalan-n21-i1.tr". Gunakan awalan untuk
nyahkekaburan berbilang protokol bagi setiap nod.

Anda sentiasa boleh menggunakan ns-3 perkhidmatan nama objek untuk menjadikannya lebih jelas. Sebagai contoh, jika
anda menggunakan perkhidmatan nama objek untuk memberikan nama "serverIpv4" kepada protokol pada Node
21, dan juga tentukan antara muka satu, nama fail surih ASCII yang terhasil akan secara automatik
menjadi, "prefix-nserverIpv4-1.tr".

Beberapa kaedah mempunyai parameter lalai yang dipanggil Nama fail eksplisit. Apabila ditetapkan kepada
benar, parameter ini melumpuhkan mekanisme penyiapan nama fail automatik dan membolehkan anda
untuk mencipta nama fail yang jelas. Pilihan ini hanya tersedia dalam kaedah yang mengambil a
awalan dan dayakan pengesanan pada satu peranti.

Ringkasan
ns-3 termasuk persekitaran yang sangat kaya yang membolehkan pengguna di beberapa peringkat untuk menyesuaikan
jenis maklumat yang boleh diekstrak daripada simulasi.

Terdapat fungsi pembantu peringkat tinggi yang membolehkan pengguna mengawal koleksi
output yang telah ditetapkan kepada butiran halus. Terdapat fungsi pembantu peringkat pertengahan untuk dibenarkan
pengguna yang lebih canggih untuk menyesuaikan cara maklumat diekstrak dan disimpan; dan di sana
ialah fungsi teras peringkat rendah untuk membolehkan pengguna pakar mengubah sistem untuk mempersembahkan yang baharu dan
maklumat yang tidak dieksport sebelum ini dengan cara yang boleh diakses serta-merta kepada pengguna di
peringkat yang lebih tinggi.

Ini adalah sistem yang sangat komprehensif, dan kami menyedari bahawa ia adalah banyak untuk dihadam, terutamanya
untuk pengguna baharu atau mereka yang tidak mengenali C++ dan simpulan bahasanya. Kami mempertimbangkan
sistem pengesanan bahagian yang sangat penting ns-3 dan oleh itu syorkan menjadi seperti biasa
mungkin dengannya. Ia mungkin kes yang memahami selebihnya ns-3 sistem
akan menjadi agak mudah apabila anda telah menguasai sistem pengesanan

DATA KOLEKSI


Bab tutorial terakhir kami memperkenalkan beberapa komponen yang telah ditambahkan ns-3 dalam versi
3.18, dan itu masih dalam pembangunan. Bahagian tutorial ini juga merupakan a
kerja dalam proses.

Motivasi
Salah satu perkara utama menjalankan simulasi adalah untuk menjana data output, sama ada untuk
tujuan penyelidikan atau hanya untuk mengetahui tentang sistem. Dalam bab sebelum ini, kita
memperkenalkan subsistem pengesanan dan contohnya keenam.cc. dari mana PCAP atau ASCII jejak
fail dihasilkan. Jejak ini berharga untuk analisis data menggunakan pelbagai
alat luaran, dan bagi kebanyakan pengguna, data keluaran tersebut adalah cara pengumpulan yang diutamakan
data (untuk analisis oleh alat luaran).

Walau bagaimanapun, terdapat juga kes penggunaan untuk lebih daripada penjanaan fail surih, termasuk
Berikut:

· penjanaan data yang tidak memetakan dengan baik kepada jejak PCAP atau ASCII, seperti bukan paket
data (cth peralihan mesin keadaan protokol),

· simulasi besar yang memerlukan I/O cakera untuk menjana fail surih
melarang atau menyusahkan, dan

· keperluan untuk talian pengurangan atau pengiraan data, semasa simulasi dijalankan.
Contoh yang baik tentang ini adalah untuk menentukan syarat penamatan untuk simulasi, untuk memberitahu
ia apabila perlu berhenti apabila ia telah menerima data yang mencukupi untuk membentuk keyakinan yang cukup sempit
selang sekitar anggaran beberapa parameter.

. ns-3 rangka kerja pengumpulan data direka bentuk untuk menyediakan keupayaan tambahan ini
melebihi keluaran berasaskan surih. Kami mengesyorkan agar pembaca yang berminat dalam topik ini berunding
yang ns-3 Manual untuk rawatan yang lebih terperinci tentang rangka kerja ini; di sini, kami ringkaskan dengan
program contoh beberapa keupayaan membangunkan.

Contoh Kod
Contoh tutorial contoh/tutorial/ketujuh.cc menyerupai keenam.cc contoh kita
disemak sebelum ini, kecuali untuk beberapa perubahan. Pertama, ia telah didayakan untuk IPv6
sokongan dengan pilihan baris arahan:

cmd Baris Perintah;
cmd.AddValue ("useIpv6", "Gunakan Ipv6", useV6);
cmd.Parse (argc, argv);

Jika pengguna menyatakan gunakanIpv6, pilihan, program akan dijalankan menggunakan IPv6 dan bukannya IPv4.
. membantu pilihan, tersedia untuk semua ns-3 program yang menyokong objek CommandLine sebagai
ditunjukkan di atas, boleh digunakan seperti berikut (sila ambil perhatian penggunaan petikan berganda):

./waf --run "ketujuh --help"

yang menghasilkan:

ns3-dev-seventh-debug [Argumen Program] [Argumen Umum]

Argumen Program:
--useIpv6: Gunakan Ipv6 [false]

Hujah Umum:
--PrintGlobals: Cetak senarai global.
--PrintGroups: Cetak senarai kumpulan.
--PrintGroup=[kumpulan]: Cetak semua TypeId kumpulan.
--PrintTypeIds: Cetak semua TypeIds.
--PrintAttributes=[typeid]: Cetak semua atribut typeid.
--PrintHelp: Cetak mesej bantuan ini.

Lalai ini (penggunaan IPv4, kerana useIpv6 adalah palsu) boleh ditukar dengan menogol boolean
nilai seperti berikut:

./waf --run "ketujuh --useIpv6=1"

dan lihat pcap yang dihasilkan, seperti dengan tcpdump:

tcpdump -r ketujuh.pcap -nn -tt

Ini telah menjadi penyimpangan singkat ke dalam sokongan IPv6 dan baris arahan, yang juga
diperkenalkan sebelum ini dalam tutorial ini. Untuk contoh khusus penggunaan baris arahan,
sila lihat src/core/example/command-line-example.cc.

Sekarang kembali ke pengumpulan data. Di dalam contoh/tutorial/ direktori, taip yang berikut
arahan: diff -u keenam.cc ketujuh.cc, dan periksa beberapa baris baharu perbezaan ini:

+ std::string probeType;
+ std::string tracePath;
+ jika (useV6 == palsu)
+ {
...
+ probeType = "ns3::Ipv4PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
+ }
+ lain
+ {
...
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
+ }
...
+ // Gunakan GnuplotHelper untuk merancang kiraan bait paket dari semasa ke semasa
+ GnuplotHelper plotHelper;
+
+ // Konfigurasikan plot. Argumen pertama ialah awalan nama fail
+ // untuk fail output yang dihasilkan. Yang kedua, ketiga, dan keempat
+ // argumen masing-masing ialah tajuk plot, paksi-x dan label paksi-y
+ plotHelper.ConfigurePlot ("kiraan bait-paket ketujuh",
+ "Kiraan Bait Paket lwn. Masa",
+ "Masa (Saat)",
+ "Kiraan Bait Paket");
+
+ // Nyatakan jenis probe, laluan sumber surih (dalam ruang nama konfigurasi), dan
+ // siasat sumber surih keluaran ("OutputBytes") untuk merancang. Hujah keempat
+ // menentukan nama label siri data pada plot. Yang terakhir
+ // argumen memformat plot dengan menyatakan tempat kunci harus diletakkan.
+ plotHelper.PlotProbe (probeType,
+ tracePath,
+ "OutputBytes",
+ "Kiraan Bait Paket",
+ GnuplotAggregator::KEY_BELOW);
+
+ // Gunakan FileHelper untuk menulis kiraan bait paket dari semasa ke semasa
+ FileHelper failHelper;
+
+ // Konfigurasikan fail yang akan ditulis, dan pemformatan data output.
+ fileHelper.ConfigureFile ("kiraan bait-paket ketujuh",
+ FileAggregator::FORMATTED);
+
+ // Tetapkan label untuk fail output berformat ini.
+ fileHelper.Set2dFormat ("Masa (Saat) = %.3e\tKiraan Bait Paket = %.0f");
+
+ // Nyatakan jenis siasatan, laluan siasatan (dalam ruang nama konfigurasi), dan
+ // siasat sumber surih keluaran ("OutputBytes") untuk menulis.
+ fileHelper.WriteProbe (probeType,
+ tracePath,
+ "OutputBytes");
+
Simulator::Berhenti (Saat (20));
Simulator::Jalankan ();
Simulator::Memusnahkan ();

Pembaca berhati-hati akan menyedari, apabila menguji atribut baris arahan IPv6 di atas,
Bahawa ketujuh.cc telah mencipta beberapa fail keluaran baharu:

ketujuh-packet-byte-count-0.txt
ketujuh-packet-byte-count-1.txt
ketujuh-packet-bait-count.dat
ketujuh-packet-byte-count.plt
ketujuh-packet-byte-count.png
ketujuh-packet-byte-count.sh

Ini dicipta oleh kenyataan tambahan yang diperkenalkan di atas; khususnya, oleh a
GnuplotHelper dan FileHelper. Data ini dihasilkan dengan mengaitkan pengumpulan data
komponen untuk ns-3 mengesan sumber, dan menyusun data ke dalam format gnplot and
ke dalam fail teks berformat. Dalam bahagian seterusnya, kami akan menyemak setiap satu daripada ini.

GnuplotHelper
GnuplotHelper ialah sebuah ns-3 objek pembantu bertujuan untuk penghasilan gnplot plot dengan
sesedikit mungkin kenyataan, untuk kes biasa. Ia cangkuk ns-3 mengesan sumber dengan data
jenis yang disokong oleh sistem pengumpulan data. Tidak semua ns-3 jenis data sumber surih ialah
disokong, tetapi kebanyakan jenis jejak biasa adalah, termasuk TracedValues ​​dengan lama biasa
jenis data (POD).

Mari lihat output yang dihasilkan oleh pembantu ini:

ketujuh-packet-bait-count.dat
ketujuh-packet-byte-count.plt
ketujuh-packet-byte-count.sh

Yang pertama ialah fail data gnuplot dengan satu siri cap waktu dan paket yang dibatasi ruang
kiraan bait. Kami akan membincangkan cara output data tertentu ini dikonfigurasikan di bawah, tetapi mari
teruskan dengan fail output. Fail ketujuh-packet-byte-count.plt ialah plot gnuplot
fail, yang boleh dibuka dari dalam gnuplot. Pembaca yang memahami sintaks gnuplot boleh
lihat bahawa ini akan menghasilkan fail PNG output berformat bernama
ketujuh-packet-byte-count.png. Akhirnya, skrip shell kecil
ketujuh-packet-byte-count.sh menjalankan fail plot ini melalui gnuplot untuk menghasilkan yang dikehendaki
PNG (yang boleh dilihat dalam editor imej); iaitu perintah:

sh ketujuh-packet-byte-count.sh

akan menghasilkan ketujuh-packet-byte-count.png. Mengapa PNG ini tidak dihasilkan pada mulanya
tempat? Jawapannya ialah dengan menyediakan fail plt, pengguna boleh mengkonfigurasi fail
hasil jika dikehendaki, sebelum menghasilkan PNG.

Tajuk imej PNG menyatakan bahawa plot ini ialah plot "Packet Byte Count vs. Time", dan
bahawa ia sedang merancang data yang disiasat sepadan dengan laluan sumber surih:

/NodeList/*/$ns3::Ipv6L3Protocol/Tx

Perhatikan kad liar dalam laluan jejak. Secara ringkasnya, apa yang ditangkap oleh plot ini ialah plot
bait paket yang diperhatikan pada sumber surih penghantaran objek Ipv6L3Protocol;
sebahagian besarnya segmen TCP 596-bait dalam satu arah, dan acks TCP 60-bait dalam arah yang lain (dua
sumber surih nod telah dipadankan oleh sumber surih ini).

Bagaimanakah ini dikonfigurasikan? Beberapa kenyataan perlu disediakan. Pertama, GnuplotHelper
objek mesti diisytiharkan dan dikonfigurasikan:

+ // Gunakan GnuplotHelper untuk merancang kiraan bait paket dari semasa ke semasa
+ GnuplotHelper plotHelper;
+
+ // Konfigurasikan plot. Argumen pertama ialah awalan nama fail
+ // untuk fail output yang dihasilkan. Yang kedua, ketiga, dan keempat
+ // argumen masing-masing ialah tajuk plot, paksi-x dan label paksi-y
+ plotHelper.ConfigurePlot ("kiraan bait-paket ketujuh",
+ "Kiraan Bait Paket lwn. Masa",
+ "Masa (Saat)",
+ "Kiraan Bait Paket");

Setakat ini, plot kosong telah dikonfigurasikan. Awalan nama fail ialah yang pertama
hujah, tajuk plot ialah yang kedua, label paksi-x yang ketiga, dan label paksi-y
hujah keempat.

Langkah seterusnya adalah untuk mengkonfigurasi data, dan di sinilah sumber surih disambungkan.
Pertama, perhatikan di atas dalam program kami mengisytiharkan beberapa pembolehubah untuk kegunaan kemudian:

+ std::string probeType;
+ std::string tracePath;
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";

Kami menggunakannya di sini:

+ // Nyatakan jenis probe, laluan sumber surih (dalam ruang nama konfigurasi), dan
+ // siasat sumber surih keluaran ("OutputBytes") untuk merancang. Hujah keempat
+ // menentukan nama label siri data pada plot. Yang terakhir
+ // argumen memformat plot dengan menyatakan tempat kunci harus diletakkan.
+ plotHelper.PlotProbe (probeType,
+ tracePath,
+ "OutputBytes",
+ "Kiraan Bait Paket",
+ GnuplotAggregator::KEY_BELOW);

Dua argumen pertama ialah nama jenis probe dan laluan sumber surih. Ini
dua mungkin yang paling sukar untuk ditentukan apabila anda cuba menggunakan rangka kerja ini untuk merancang yang lain
jejak. Jejak siasatan di sini ialah Tx jejak sumber kelas Ipv6L3Protokol. Apabila kita
periksa pelaksanaan kelas ini (src/internet/model/ipv6-l3-protocol.cc) kita boleh perhatikan:

.AddTraceSource ("Tx", "Hantar paket IPv6 ke antara muka keluar.",
MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace))

Ini mengatakan bahawa Tx ialah nama untuk pembolehubah m_txTrace, yang mempunyai pengisytiharan:

/ **
* \panggil balik ringkas untuk mengesan paket TX (penghantaran).
*/
TracedCallback , Ptr , uint6_t> m_txTrace;

Ternyata tandatangan sumber surih khusus ini disokong oleh kelas Probe (what
kami perlukan di sini) kelas Ipv6PacketProbe. Lihat fail
src/internet/model/ipv6-packet-probe.{h,cc}.

Jadi, dalam pernyataan PlotProbe di atas, kita melihat bahawa pernyataan itu mengaitkan jejak
sumber (dikenal pasti melalui rentetan laluan) dengan padanan ns-3 Jenis siasatan Ipv6PacketProbe. Jika
kami tidak menyokong jenis siasatan ini (tandatangan sumber surih yang sepadan), kami mungkin tidak
menggunakan pernyataan ini (walaupun beberapa pernyataan peringkat rendah yang lebih rumit mungkin
digunakan, seperti yang diterangkan dalam manual).

Ipv6PacketProbe mengeksport, sendiri, beberapa sumber surih yang mengekstrak data daripada
objek Paket yang disiasat:

JenisId
Ipv6PacketProbe::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::Ipv6PacketProbe")
.SetParent ()
.AddConstructor ()
.AddTraceSource ( "Output",
"Paket ditambah objek IPv6 dan antara muka yang berfungsi sebagai output untuk siasatan ini",
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_output))
.AddTraceSource ( "OutputBytes",
"Bilangan bait dalam paket",
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_outputBytes))
;
tid balik;
}

Hujah ketiga pernyataan PlotProbe kami menyatakan bahawa kami berminat dengan
bilangan bait dalam paket ini; khususnya, sumber surih "OutputBytes" bagi
Ipv6PacketProbe. Akhir sekali, dua hujah terakhir penyataan memberikan legenda plot
untuk siri data ini ("Packet Byte Count") dan pernyataan pemformatan gnuplot pilihan
(GnuplotAggregator::KEY_BELOW) bahawa kami mahu kunci plot dimasukkan di bawah plot.
Pilihan lain termasuk NO_KEY, KEY_INSIDE dan KEY_ABOVE.

Disokong Trace jenis
Nilai yang dikesan berikut disokong dengan Probes sejak penulisan ini:

┌─────────────────┬─────────────────┬─────────────. ────────────────────┐
│Jenis TracedValue │ Jenis probe │ Fail │
├─────────────────┼─────────────────┼─────────────. ────────────────────┤
│double │ DoubleProbe │ statistik/model/double-probe.h │
├─────────────────┼─────────────────┼─────────────. ────────────────────┤
│uint8_t │ Uinteger8Probe │ statistik/model/uinteger-8-probe.h │
├─────────────────┼─────────────────┼─────────────. ────────────────────┤
│uint16_t │ Uinteger16Probe │ statistik/model/uinteger-16-probe.h │
├─────────────────┼─────────────────┼─────────────. ────────────────────┤
│uint32_t │ Uinteger32Probe │ statistik/model/uinteger-32-probe.h │
├─────────────────┼─────────────────┼─────────────. ────────────────────┤
│bool │ BooleanProbe │ statistik/model/uinteger-16-probe.h │
├─────────────────┼─────────────────┼─────────────. ────────────────────┤
│ns3::Masa │ TimeProbe │ stats/model/time-probe.h │
└─────────────────┴─────────────────┴─────────────. ────────────────────┘

Jenis TraceSource berikut disokong oleh Probes sejak penulisan ini:

┌────────────────────┬────────────────────────┬───. ────────────┬─────────────────────────────────────. ──────────┐
├────────────────────┼────────────────────────┼───. ────────────┼─────────────────────────────────────. ──────────┤
├────────────────────┼────────────────────────┼───. ────────────┼─────────────────────────────────────. ──────────┤
├────────────────────┼────────────────────────┼───. ────────────┼─────────────────────────────────────. ──────────┤
├────────────────────┼────────────────────────┼───. ────────────┼─────────────────────────────────────. ──────────┤
├────────────────────┼────────────────────────┼───. ────────────┼─────────────────────────────────────. ──────────┤
└────────────────────┴────────────────────────┴───. ────────────┴─────────────────────────────────────. ──────────┘

Seperti yang dapat dilihat, hanya beberapa sumber surih disokong, dan semuanya berorientasikan
mengeluarkan saiz Paket (dalam bait). Walau bagaimanapun, kebanyakan jenis data asas
tersedia kerana TracedValues ​​boleh disokong dengan pembantu ini.

FileHelper
Kelas FileHelper hanyalah variasi daripada contoh GnuplotHelper sebelumnya. The
program contoh menyediakan output berformat data cap masa yang sama, seperti berikut:

Masa (Saat) = 9.312e+00 Kiraan Bait Paket = 596
Masa (Saat) = 9.312e+00 Kiraan Bait Paket = 564

Dua fail disediakan, satu untuk nod "0" dan satu untuk nod "1" seperti yang boleh dilihat dalam
nama fail. Mari lihat kod sekeping demi sekeping:

+ // Gunakan FileHelper untuk menulis kiraan bait paket dari semasa ke semasa
+ FileHelper failHelper;
+
+ // Konfigurasikan fail yang akan ditulis, dan pemformatan data output.
+ fileHelper.ConfigureFile ("kiraan bait-paket ketujuh",
+ FileAggregator::FORMATTED);

Awalan fail pembantu fail ialah hujah pertama dan penentu format seterusnya. Sesetengah
pilihan lain untuk pemformatan termasuk SPACE_SEPARATED, COMMA_SEPARATED dan TAB_SEPARATED.
Pengguna boleh menukar pemformatan (jika FORMATTED ditentukan) dengan rentetan format
seperti berikut:

+
+ // Tetapkan label untuk fail output berformat ini.
+ fileHelper.Set2dFormat ("Masa (Saat) = %.3e\tKiraan Bait Paket = %.0f");

Akhirnya, jejak sumber minat mesti dikaitkan. Sekali lagi, probeType dan tracePath
pembolehubah dalam contoh ini digunakan, dan sumber surih keluaran siasatan "OutputBytes" ialah
ketagih:

+
+ // Nyatakan jenis probe, laluan sumber surih (dalam ruang nama konfigurasi), dan
+ // siasat sumber surih keluaran ("OutputBytes") untuk menulis.
+ fileHelper.WriteProbe (probeType,
+ tracePath,
+ "OutputBytes");
+

Medan kad bebas dalam penentu sumber surih ini sepadan dengan dua sumber surih. Berbeza dengan
Contoh GnuplotHelper, di mana dua siri data ditindankan pada plot yang sama, di sini, dua
fail berasingan ditulis ke cakera.

Ringkasan
Sokongan pengumpulan data adalah baharu pada ns-3.18, dan sokongan asas untuk menyediakan siri masa
output telah ditambah. Corak asas yang diterangkan di atas boleh direplikasi dalam
skop sokongan probe dan sumber surih sedia ada. Lebih banyak keupayaan termasuk
pemprosesan statistik akan ditambah dalam keluaran akan datang.

KESIMPULAN


niaga hadapan
Dokumen ini bertujuan sebagai dokumen hidup. Kami berharap dan menjangkakan ia akan berkembang dari semasa ke semasa
untuk menutup lebih banyak lagi nat dan bolt ns-3.

Menulis bab manual dan tutorial bukanlah sesuatu yang kita semua teruja, tetapi memang begitu
sangat penting untuk projek itu. Jika anda pakar dalam salah satu bidang ini, sila
pertimbangkan untuk menyumbang kepada ns-3 dengan menyediakan salah satu daripada bab ini; atau mana-mana bab lain anda
mungkin fikir penting.

Penutup
ns-3 adalah sistem yang besar dan rumit. Adalah mustahil untuk merangkumi semua perkara yang anda
perlu tahu dalam satu tutorial kecil. Pembaca yang ingin mengetahui lebih lanjut adalah digalakkan untuk
baca dokumentasi tambahan berikut:

· The ns-3 manual

· The ns-3 dokumentasi perpustakaan model

· The ns-3 Doxygen (dokumentasi API)

· The ns-3 wiki

-- Yang ns-3 pasukan pembangunan.

Gunakan ns-3-tutorial dalam talian menggunakan perkhidmatan onworks.net


Pelayan & Stesen Kerja Percuma

Muat turun apl Windows & Linux

Arahan Linux

Ad




×
Pengiklanan
❤ ️Beli, tempah atau beli di sini — tanpa kos, membantu memastikan perkhidmatan percuma.