انگلیسیفرانسویاسپانیایی

فاویکون OnWorks

ns-3-tutorial - آنلاین در ابر

اجرای ns-3-tutorial در ارائه دهنده هاست رایگان OnWorks از طریق Ubuntu Online، Fedora Online، شبیه ساز آنلاین ویندوز یا شبیه ساز آنلاین MAC OS

این دستور ns-3-tutorial است که می تواند در ارائه دهنده هاست رایگان OnWorks با استفاده از یکی از چندین ایستگاه کاری آنلاین رایگان ما مانند Ubuntu Online، Fedora Online، شبیه ساز آنلاین ویندوز یا شبیه ساز آنلاین MAC OS اجرا شود.

برنامه:

نام


ns-3-tutorial - ns-3 Tutorial

این است ns-3 آموزش. اسناد اولیه برای پروژه ns-3 در پنج مورد موجود است
تشکیل می دهد:

· ns-3 اکسیژن: مستندسازی APIهای عمومی شبیه ساز

· آموزش (این سند)، کتابچه راهنمای و مدل کتابخانه برای آخرین آزاد و
توسعه درخت

· ns-3 ویکی

این سند در نوشته شده است restructuredText برای مجسمه ابوالهول و در آن نگهداری می شود
doc/tutorial دایرکتوری کد منبع ns-3.

معرفی


La ns-3 شبیه ساز یک شبیه ساز شبکه رویداد گسسته است که در درجه اول برای تحقیق هدف قرار گرفته است
و استفاده آموزشی در ns-3 پروژه، که در سال 2006 آغاز شد، یک پروژه منبع باز است
در حال توسعه ns-3.

هدف از این آموزش معرفی مطالب جدید است ns-3 کاربران به سیستم در یک ساختار
مسیر. گاهی اوقات برای کاربران جدید دشوار است که اطلاعات ضروری را از جزئیات جمع آوری کنند
کتابچه های راهنما و تبدیل این اطلاعات به شبیه سازی های کاری. در این آموزش ما
چندین نمونه شبیه سازی، معرفی و توضیح مفاهیم کلیدی و
ویژگی های در حالی که ما می رویم.

همانطور که آموزش باز می شود، ما به طور کامل معرفی خواهیم کرد ns-3 مستندات و ارائه
اشاره گر به کد منبع برای کسانی که علاقه مند به کاوش عمیق تر در کارکرد هستند
سیستم.

چند نکته کلیدی در ابتدا قابل ذکر است:

· ns-3 منبع باز است و پروژه در تلاش است تا یک محیط باز را برای آن حفظ کند
محققان برای مشارکت و به اشتراک گذاری نرم افزار خود.

· ns-3 یک پسوند سازگار با عقب نیست ns-2; این یک شبیه ساز جدید است. این دو
شبیه سازها هر دو در C++ نوشته شده اند اما ns-3 یک شبیه ساز جدید است که پشتیبانی نمی کند
ns-2 API ها چند مدل از ns-2 قبلا از منتقل شده اند ns-2 به ns-3.
پروژه به حفظ ادامه خواهد داد ns-2 در حین ns-3 در حال ساخت است و مطالعه خواهد کرد
مکانیسم های انتقال و ادغام

درباره ما ns-3
ns-3 برای ارائه یک پلت فرم شبیه سازی شبکه باز و قابل توسعه، برای
تحقیق و آموزش شبکه به طور خلاصه، ns-3 مدل هایی از نحوه بسته بندی داده ها را ارائه می دهد
شبکه ها کار می کنند و انجام می دهند و موتور شبیه سازی را برای کاربران فراهم می کند
آزمایش های شبیه سازی برخی از دلایل استفاده ns-3 شامل انجام مطالعاتی که
برای مطالعه رفتار سیستم، انجام آن با سیستم های واقعی دشوارتر است یا ممکن نیست
در یک محیط بسیار کنترل شده و قابل تکرار و برای یادگیری نحوه عملکرد شبکه ها.
کاربران متوجه خواهند شد که مدل موجود تنظیم شده است ns-3 تمرکز بر مدل سازی چگونه اینترنت است
پروتکل ها و شبکه ها کار می کنند، اما ns-3 محدود به سیستم های اینترنتی نیست. چندین کاربر
با استفاده از ns-3 برای مدل سازی سیستم های غیر مبتنی بر اینترنت.

ابزارهای شبیه سازی زیادی برای مطالعات شبیه سازی شبکه وجود دارد. در زیر چند مورد آورده شده است
ویژگی های متمایز از ns-3 بر خلاف سایر ابزارها

· ns-3 به عنوان مجموعه ای از کتابخانه ها طراحی شده است که می توانند با هم و همچنین با سایرین ترکیب شوند
کتابخانه های نرم افزار خارجی در حالی که برخی از پلتفرم های شبیه سازی به کاربران ارائه می دهند
یک محیط رابط کاربری گرافیکی یکپارچه که در آن تمام وظایف انجام می شود
خارج کردن ns-3 از این نظر ماژولارتر است. چندین انیماتور خارجی و تجزیه و تحلیل داده ها
و ابزارهای تجسم را می توان با استفاده کرد ns-3. با این حال، کاربران باید انتظار داشته باشند که در آن کار کنند
خط فرمان و با C++ و/یا ابزارهای توسعه نرم افزار پایتون.

· ns-3 در درجه اول در سیستم های لینوکس استفاده می شود، اگرچه پشتیبانی از FreeBSD، Cygwin وجود دارد
(برای ویندوز)، و پشتیبانی بومی ویندوز ویژوال استودیو در حال انجام است
توسعه یافته.

· ns-3 یک محصول نرم افزاری رسمی پشتیبانی شده هیچ شرکتی نیست. پشتیبانی از ns-3
بر اساس بهترین تلاش در لیست پستی کاربران ns-3 انجام می شود.

برای ns-2 کاربران
برای آشنایان ns-2 (ابزار محبوبی که قبل از ns-3) از بیرون قابل مشاهده ترین است
هنگام حرکت به ns-3 انتخاب زبان اسکریپت است. برنامه ها در ns-2 هستند
اسکریپت شده در OTcl و نتایج شبیه سازی ها را می توان با استفاده از Network Animator تجسم کرد
نام امکان اجرای شبیه سازی در آن وجود ندارد ns-2 صرفا از C++ (یعنی به عنوان main()
برنامه بدون OTcl). علاوه بر این، برخی از اجزای ns-2 به زبان C++ نوشته می شوند و
دیگران در OTcl. که در ns-3، شبیه ساز به طور کامل در C++ و با پایتون اختیاری نوشته شده است
اتصالات بنابراین اسکریپت های شبیه سازی را می توان در C++ یا پایتون نوشت. انیماتورهای جدید
و تصویرسازها در دسترس هستند و در حال توسعه هستند. از آنجا که ns-3 pcap تولید می کند
فایل های ردیابی بسته، از ابزارهای دیگر نیز می توان برای تجزیه و تحلیل ردیابی ها استفاده کرد. در این
ما ابتدا بر روی اسکریپت نویسی مستقیم در C++ و تفسیر نتایج تمرکز می کنیم
از طریق فایل های ردیابی

اما شباهت هایی نیز وجود دارد (برای مثال، هر دو بر اساس اشیاء C++ هستند و برخی
کد از ns-2 قبلاً به آن منتقل شده است ns-3). ما سعی خواهیم کرد تفاوت ها را برجسته کنیم
میان ns-2 و ns-3 همانطور که در این آموزش ادامه می دهیم.

سوالی که اغلب می شنویم این است که "آیا هنوز باید استفاده کنم؟ ns-2 یا حرکت به ns-3؟" در این
نظر نویسنده، مگر اینکه کاربر به نحوی در اختیار او باشد ns-2 (چه بر اساس موجود
راحتی شخصی با و آگاهی از ns-2، یا بر اساس یک مدل شبیه سازی خاص که
فقط در موجود است ns-2) کاربر با بهره وری بیشتری خواهد داشت ns-3 به شرح زیر است
دلایل:

· ns-3 به طور فعال با یک لیست پستی کاربران فعال و پاسخگو نگهداری می شود، در حالی که ns-2 is
فقط کمی نگهداری می شود و پیشرفت قابل توجهی در درخت کد اصلی خود مشاهده نکرده است
برای بیش از یک دهه

· ns-3 ویژگی هایی را ارائه می دهد که در آن موجود نیست ns-2، مانند اجرای کد پیاده سازی
محیط (به کاربران اجازه می دهد تا کد پیاده سازی واقعی را در شبیه ساز اجرا کنند)

· ns-3 سطح پایه پایین تری از انتزاع را در مقایسه با ns-2، به آن اجازه می دهد تا تراز شود
بهتر است با نحوه چیدمان سیستم های واقعی. برخی از محدودیت های موجود در ns-2 (مانند
پشتیبانی از چندین نوع واسط روی گره ها به درستی) اصلاح شده است ns-3.

ns-2 دارای مجموعه متنوع تری از ماژول های ارائه شده نسبت به آن است ns-3، به دلیل طولانی بودن آن
تاریخ. با این حال، ns-3 مدل های دقیق تری در چندین حوزه تحقیقاتی محبوب دارد
(از جمله مدل های پیشرفته LTE و WiFi)، و پشتیبانی آن از کد پیاده سازی
طیف بسیار گسترده ای از مدل های با وفاداری بالا را می پذیرد. کاربران ممکن است از یادگیری آن شگفت زده شوند
کل پشته شبکه لینوکس را می توان در یک کپسوله کرد ns-3 گره، با استفاده از Direct
چارچوب اجرای کد (DCE). ns-2 گاهی اوقات می توان مدل ها را به آن منتقل کرد ns-3، بخصوص
اگر در C++ پیاده سازی شده باشند.

اگر شک دارید، یک دستورالعمل خوب این است که به هر دو شبیه ساز (و همچنین سایر شبیه سازها) نگاه کنید
شبیه سازها) و به ویژه مدل های موجود برای تحقیق شما، اما به خاطر داشته باشید
که ممکن است تجربه شما در استفاده از ابزاری که به طور فعال در حال توسعه است بهتر باشد
نگهداری (ns-3).

مشارکت کننده
ns-3 یک شبیه ساز تحقیقاتی و آموزشی، توسط و برای جامعه پژوهشی است. خواهد شد
برای توسعه مدل های جدید، اشکال زدایی یا به کمک های مداوم جامعه تکیه کنید
موارد موجود را حفظ کنید و نتایج را به اشتراک بگذارید. چند سیاست وجود دارد که امیدواریم انجام شود
مردم را به مشارکت تشویق کنید ns-3 مانند آنها برای ns-2:

· مجوز منبع باز بر اساس سازگاری GNU GPLv2

· ویکی

· کمک رمز صفحه، شبیه به ns-2کد مشارکت محبوب با ما

· باز کن اشکال خواندن سریع پستهای انجمن

ما متوجه هستیم که اگر شما در حال خواندن این سند هستید، مشارکت مجدد در پروژه است
احتمالاً مهمترین نگرانی شما در این مرحله نیست، اما ما می خواهیم که شما از این موضوع آگاه باشید
مشارکت در روح پروژه است و حتی این که یک یادداشت به ما می‌دهیم
در مورد تجربه اولیه شما با ns-3 (به عنوان مثال "این بخش آموزشی واضح نبود...")
گزارش های اسناد قدیمی و غیره بسیار مورد استقبال قرار می گیرند.

آموزش سازمان
این آموزش فرض می کند که کاربران جدید در ابتدا ممکن است مسیری مانند زیر را دنبال کنند:

· سعی کنید یک کپی را دانلود و بسازید.

· سعی کنید چند برنامه نمونه را اجرا کنید.

· به خروجی شبیه سازی نگاه کنید و سعی کنید آن را تنظیم کنید.

در نتیجه، ما سعی کرده ایم آموزش را در امتداد توالی های گسترده بالا سازماندهی کنیم
مناسبت ها.

منابع


La وب
چندین منبع مهم وجود دارد که یکی از آنها ns-3 کاربر باید آگاه باشد وب اصلی
سایت در http://www.nsnam.org و دسترسی به اطلاعات اولیه در مورد را فراهم می کند
ns-3 سیستم. مستندات دقیق از طریق وب سایت اصلی در دسترس است
http://www.nsnam.org/documentation/. همچنین می توانید اسناد مربوط به سیستم را پیدا کنید
معماری از این صفحه

ویکی وجود دارد که مکمل اصلی است ns-3 وب سایتی که در آن پیدا خواهید کرد
http://www.nsnam.org/wiki/. سوالات متداول کاربر و توسعه دهنده را نیز در آنجا خواهید یافت
راهنماهای عیب یابی، کدهای ارائه شده توسط شخص ثالث، مقالات و غیره.

کد منبع را ممکن است در پیدا کنید و مرور کنید http://code.nsnam.org/. در آنجا خواهید یافت
درخت توسعه فعلی در مخزن به نام ns-3-dev. نسخه های گذشته و
مخازن تجربی توسعه دهندگان اصلی نیز ممکن است در آنجا یافت شوند.

تند
سیستم های نرم افزاری پیچیده به روشی برای مدیریت سازمان و تغییرات در سازمان نیاز دارند
کد و مستندات اساسی راه های زیادی برای انجام این شاهکار وجود دارد و ممکن است
در مورد برخی از سیستم هایی که در حال حاضر برای انجام این کار استفاده می شوند شنیده اید. همزمان
سیستم نسخه (CVS) احتمالاً شناخته شده ترین است.

La ns-3 پروژه از Mercurial به عنوان سیستم مدیریت کد منبع خود استفاده می کند. اگرچه شما این کار را نمی کنید
توصیه می کنیم برای تکمیل این آموزش، اطلاعات زیادی در مورد مرکوریال بدانید
آشنایی با Mercurial و استفاده از آن برای دسترسی به کد منبع. مرکوریال دارای یک
وب سایت در http://www.selenic.com/mercurial/، که از آن می توانید باینری یا منبع دریافت کنید
نسخه های این سیستم مدیریت پیکربندی نرم افزار (SCM). سلنیک (توسعه دهنده
of Mercurial) همچنین یک آموزش در
http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/و راهنمای QuickStart در
http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/.

همچنین می توانید اطلاعات حیاتی در مورد استفاده از Mercurial و ns-3 در اصلی ns-3 وب
سایت.

وف
هنگامی که کد منبع را در سیستم محلی خود دانلود کردید، باید آن را کامپایل کنید
منبع تولید برنامه های قابل استفاده همانطور که در مورد مدیریت کد منبع، وجود دارد
ابزارهای زیادی برای انجام این عملکرد موجود است. احتمالاً شناخته شده ترین آنها
ابزار است ساخت. در کنار شناخته شده ترین، ساخت احتمالا سخت ترین است
برای استفاده در یک سیستم بسیار بزرگ و بسیار قابل تنظیم. به همین دلیل، بسیاری از جایگزین ها
توسعه یافته اند. اخیراً این سیستم ها با استفاده از پایتون توسعه یافته اند
زبان

از سیستم ساخت Waf استفاده شده است ns-3 پروژه یکی از نسل جدید است
سیستم های ساخت مبتنی بر پایتون برای ساختن آن نیازی به درک هیچ پایتون نخواهید داشت
موجود ns-3 سیستم.

برای کسانی که به جزئیات غم انگیز Waf علاقه مند هستند، وب سایت اصلی را می توان در این آدرس یافت
http://code.google.com/p/waf/.

پروژه محیط
همانطور که در بالا ذکر شد، اسکریپت در ns-3 در C++ یا Python انجام می شود. بیشتر ns-3 API است
در پایتون موجود است، اما در هر صورت مدل ها به زبان C++ نوشته شده اند. یک کار
دانش C++ و مفاهیم شی گرا در این سند فرض شده است. خواهیم گرفت
زمانی برای مرور برخی از مفاهیم پیشرفته تر یا زبان احتمالاً ناآشنا
ویژگی ها، اصطلاحات و الگوهای طراحی همانطور که ظاهر می شوند. ما این آموزش را نمی خواهیم
با این حال، به یک آموزش C++ اختصاص دهید، بنابراین ما انتظار داریم که یک تسلط اولیه به زبان داشته باشیم.
تعداد تقریباً غیرقابل تصوری از منابع اطلاعاتی در ++C در دسترس هستند
وب یا به صورت چاپی

اگر در C++ تازه کار هستید، ممکن است بخواهید یک کتاب یا وب سایت مبتنی بر آموزش یا کتاب آشپزی پیدا کنید.
و حداقل ویژگی های اساسی زبان را قبل از ادامه کار بررسی کنید. برای
نمونه، مثال، این آموزش.

La ns-3 سیستم از چندین مؤلفه «زنجیره ابزار» گنو برای توسعه استفاده می کند. آ
زنجیره ابزار نرم افزار مجموعه ای از ابزارهای برنامه نویسی است که در محیط معین موجود است. برای
یک بررسی سریع از آنچه در زنجیره ابزار گنو گنجانده شده است را ببینید،
http://en.wikipedia.org/wiki/GNU_toolchain. ns-3 از gcc، GNU binutils و gdb استفاده می کند.
با این حال، ما از ابزارهای سیستم ساخت گنو، نه make و نه از ابزارهای خودکار استفاده نمی کنیم. ما از واف استفاده می کنیم
برای این توابع

به طور معمول یک ns-3 نویسنده در لینوکس یا محیطی شبیه لینوکس کار خواهد کرد. برای آن ها
در حال اجرا تحت ویندوز، محیط هایی وجود دارد که محیط لینوکس را شبیه سازی می کند
درجات مختلف در ns-3 پروژه در گذشته (اما نه در حال حاضر) پشتیبانی شده است
توسعه در محیط Cygwin برای این کاربران. دیدن http://www.cygwin.com/ برای
جزئیات دانلود، و مراجعه کنید ns-3 ویکی برای اطلاعات بیشتر در مورد Cygwin و
ns-3. MinGW در حال حاضر به طور رسمی پشتیبانی نمی شود. جایگزین دیگری برای Cygwin این است که
یک محیط ماشین مجازی مانند سرور VMware نصب کنید و یک مجازی لینوکس نصب کنید
ماشین

پریز برنامه نويسي
در مثال‌هایی که در این مورد استفاده می‌شود، یک تسهیلات اساسی با API سوکت‌های برکلی در نظر می‌گیریم
آموزش اگر تازه وارد سوکت‌ها شده‌اید، توصیه می‌کنیم API و برخی کاربردهای رایج را مرور کنید
موارد برای یک نمای کلی خوب از برنامه نویسی سوکت های TCP/IP توصیه می کنیم TCP / IP سوکت in
C, دوناهو و کالورت.

یک وب سایت مرتبط وجود دارد که شامل منبعی برای نمونه های موجود در کتاب است که
می توانید در: http://cs.baylor.edu/~donahoo/practical/CSockets/.

اگر چهار فصل اول کتاب را می فهمید (یا برای کسانی که دسترسی ندارند
به یک کپی از کتاب، کلاینت‌ها و سرورهای اکو نشان داده شده در وب‌سایت بالا).
برای درک آموزش در وضعیت خوبی باشید. کتاب مشابهی در مورد Multicast وجود دارد
پریز برق، چندپخشی پریز برق، ماکوفسکه و آلمروت. که مطالبی را که ممکن است به آن نیاز داشته باشید را پوشش می دهد
اگر به نمونه های چندپخشی در توزیع نگاه کنید، متوجه می شوید.

دست آوردن آغاز شده


هدف این بخش رساندن کاربر به حالت کار است که با ماشینی شروع می شود
ممکن است هرگز نداشته باشد ns-3 نصب شده است. این پلتفرم های پشتیبانی شده، پیش نیازها، راه هایی را پوشش می دهد
گرفتن ns-3، راه های ساخت ns-3و راه هایی برای تأیید ساخت و اجرای برنامه های ساده.

بررسی اجمالی
ns-3 به عنوان سیستمی از کتابخانه های نرم افزاری ساخته شده است که با هم کار می کنند. برنامه های کاربری می تواند باشد
نوشته شده است که با این کتابخانه ها پیوند دارد (یا از آنها وارد می شود. برنامه های کاربری در نوشته شده اند
زبان های برنامه نویسی C++ یا Python.

ns-3 به عنوان کد منبع توزیع می شود، به این معنی که سیستم هدف نیاز به داشتن یک
محیط توسعه نرم افزار برای ساخت کتابخانه ها ابتدا، سپس ساخت کاربر
برنامه است. ns-3 اصولاً می توان به عنوان کتابخانه های از پیش ساخته شده برای منتخب توزیع کرد
سیستم ها، و در آینده ممکن است به این طریق توزیع شود، اما در حال حاضر، کاربران زیادی
در واقع کار خود را با ویرایش انجام می دهند ns-3 خود، بنابراین داشتن کد منبع در اطراف برای بازسازی
کتابخانه ها مفید است اگر کسی دوست دارد کار ساخت پیش ساخته را بر عهده بگیرد
کتابخانه ها و بسته های سیستم عامل، لطفاً با ایمیل ns-developers تماس بگیرید
فهرست

در ادامه به دو روش دانلود و ساخت می پردازیم ns-3. اولین مورد
برای دانلود و ساخت نسخه رسمی از وب سایت اصلی. دومی واکشی است
و ساخت نسخه های توسعه از ns-3. ما هر دو مثال را از زمان ابزارها مرور خواهیم کرد
درگیر اندکی متفاوت هستند.

دانلود ns-3
La ns-3 سیستم به طور کلی یک سیستم نسبتاً پیچیده است و تعدادی وابستگی به آن دارد
اجزای دیگر همراه با سیستم هایی که به احتمال زیاد هر روز با آنها سر و کار خواهید داشت (
زنجیره ابزار گنو، مرکوریال، یک ویرایشگر متن) باید اطمینان حاصل کنید که تعدادی از
قبل از ادامه، کتابخانه های اضافی در سیستم شما وجود دارد. ns-3 ویکی ارائه می دهد
صفحه ای که شامل صفحاتی با نکات و نکات مفید فراوان است. یکی از این صفحات صفحه است
صفحه "نصب"، http://www.nsnam.org/wiki/Installation.

بخش «پیش‌نیازها» این صفحه ویکی توضیح می‌دهد که کدام بسته‌ها مورد نیاز هستند
پشتیبانی مشترک ns-3 گزینه ها، و همچنین دستورات مورد استفاده برای نصب آنها را فراهم می کند
انواع رایج لینوکس کاربران Cygwin باید از نصب کننده Cygwin استفاده کنند (اگر شما یک
کاربر Cygwin، شما از آن برای نصب Cygwin استفاده کردید).

ممکن است بخواهید از این فرصت برای کشف آن استفاده کنید ns-3 ویکی کمی از آنجایی که واقعا وجود دارد
انبوهی از اطلاعات وجود دارد.

از این نقطه به بعد، ما فرض می کنیم که خواننده در لینوکس یا a کار می کند
محیط شبیه سازی لینوکس (لینوکس، Cygwin و غیره) و زنجیره ابزار گنو نصب شده است و
همراه با پیش نیازهای ذکر شده در بالا تایید شده است. ما نیز این را فرض می کنیم
شما مرکوریال و وف را نصب کرده اید و روی سیستم هدف اجرا می کنید.

La ns-3 کد در مخازن Mercurial در سرور موجود است http://code.nsnam.org.
شما همچنین می توانید نسخه تاربال را از اینجا دانلود کنید http://www.nsnam.org/release/، یا می توانید کار کنید
با مخازن با استفاده از Mercurial. توصیه می کنیم از مرکوریال استفاده کنید مگر اینکه چیز خوبی وجود داشته باشد
دلیل برای عدم برای اطلاع از نحوه تهیه تاربال به انتهای این بخش مراجعه کنید
را آزاد کند.

ساده ترین راه برای شروع استفاده از مخازن Mercurial استفاده از آن است ns-3-allinone
محیط. این مجموعه ای از اسکریپت ها است که دانلود و ساختن را مدیریت می کند
زیر سیستم های مختلف از ns-3 برای شما. توصیه می کنیم کار خود را شروع کنید ns-3 در این کار کنید
محیط زیست است.

یکی از تمرین ها ایجاد دایرکتوری به نام است فضای کاری در فهرست اصلی یک نفر که تحت آن
می توان مخازن محلی مرکوریال را نگه داشت. هر نام دایرکتوری انجام می شود، اما ما فرض می کنیم
که فضای کاری در اینجا استفاده می شود (توجه داشته باشید: استراحت همچنین ممکن است در برخی از اسناد به عنوان یک مورد استفاده شود
مثال نام دایرکتوری).

دانلود ns-3 با استفاده از a تاربال
تاربال یک فرمت خاص از آرشیو نرم افزار است که در آن چندین فایل همراه است
با هم و بایگانی احتمالاً فشرده شده است. ns-3 نسخه های نرم افزاری از طریق a ارائه می شوند
تربال قابل دانلود فرآیند دانلود ns-3 از طریق تربال ساده است. شما فقط
باید نسخه ای را انتخاب کنید، دانلود کنید و از حالت فشرده خارج کنید.

بیایید فرض کنیم که شما به عنوان یک کاربر مایل به ساخت هستید ns-3 در یک فهرست محلی به نام
فضای کاری. اگر قبول کنید فضای کاری با رویکرد دایرکتوری، می توانید یک کپی از یک نسخه دریافت کنید
با تایپ کردن موارد زیر در پوسته لینوکس خود (شماره های نسخه مناسب را جایگزین کنید،
البته):

$ cd
فضای کاری $ mkdir
فضای کاری سی دی $
$ wget http://www.nsnam.org/release/ns-allinone-3.22.tar.bz2
$ TAR XJF NS-ALLINONE-3.22.TAR.BZ2

اگر وارد دایرکتوری شوید ns-allinone-3.22 شما باید تعدادی فایل را ببینید:

ls دلار
bake consists.py ns-3.22 README
build.py netanim-3.105 pybindgen-0.16.0.886 util.py

اکنون آماده ساختن پایه هستید ns-3 توزیع.

دانلود ns-3 با استفاده از پخت
Bake ابزاری برای یکپارچه سازی و ساختن توزیع شده است که برای ns-3 پروژه.
از Bake می توان برای واکشی نسخه های توسعه یافته استفاده کرد ns-3 نرم افزار، و برای دانلود و
پسوندهای پایه را بسازید ns-3 توزیع، مانند اجرای مستقیم کد
محیط، پایگاه شبیه سازی شبکه، توانایی ایجاد پیوندهای جدید پایتون و موارد دیگر.

اخیرا ns-3 نسخه های منتشر شده، Bake در تاربال انتشار گنجانده شده است. پیکربندی
فایل موجود در نسخه منتشر شده به شما این امکان را می دهد که هر نرم افزاری را که بود دانلود کنید
جاری در زمان انتشار یعنی مثلا نسخه Bake که هست
توزیع شده با ns-3.21 انتشار را می توان برای واکشی اجزای آن استفاده کرد ns-3 آزاد
یا قبل از آن، اما نمی توان برای واکشی مؤلفه ها برای نسخه های بعدی استفاده کرد (مگر اینکه
bakeconf.xml فایل به روز می شود).

همچنین می توانید جدیدترین نسخه را دریافت کنید پختن با تایپ کردن موارد زیر در لینوکس خود
پوسته (با فرض اینکه Mercurial را نصب کرده اید):

$ cd
فضای کاری $ mkdir
فضای کاری سی دی $
کلون دلار جیوه http://code.nsnam.org/bake

همانطور که دستور hg (Mercurial) اجرا می شود، باید چیزی شبیه به زیر را ببینید
نمایش داده،

...
فهرست مقصد: پخت
درخواست همه تغییرات
اضافه کردن تغییرات
افزودن مانیفست
اضافه کردن تغییرات فایل
339 مجموعه تغییرات را با 796 تغییر به 63 فایل اضافه کرد
به روز رسانی به پیش فرض شعبه
45 فایل به روز شد، 0 فایل ادغام شد، 0 فایل حذف شد، 0 فایل حل نشد

پس از تکمیل دستور کلون، باید دایرکتوری فراخوانی داشته باشید پختن، مطالب
که باید چیزی شبیه به زیر باشد:

ls دلار
bakeconf.xml doc generate-binary.py TODO
تست نمونه bake.py

توجه داشته باشید که شما واقعاً چند اسکریپت پایتون و یک ماژول پایتون به نام را دانلود کرده اید
پختن. گام بعدی استفاده از آن اسکریپت ها برای دانلود و ساختن خواهد بود ns-3
توزیع به انتخاب شما

چند هدف پیکربندی موجود است:

1. ns-3.22: ماژول مربوط به انتشار. کامپوننت های مشابه را دانلود می کند
به آزادی تربال.

2. ns-3-dev: یک ماژول مشابه اما با استفاده از درخت کد توسعه

3. ns-allinone-3.22: ماژولی که شامل سایر ویژگی های اختیاری مانند کلیک است
مسیریابی، جریان باز برای ns-3، و پایگاه شبیه سازی شبکه

4. ns-3-allinone: مشابه نسخه منتشر شده ماژول allinone، اما برای
کد توسعه

تصویر لحظه ای توسعه فعلی (منتشر نشده) از ns-3 ممکن است در پیدا شود
http://code.nsnam.org/ns-3-dev/. توسعه دهندگان سعی می کنند این مخزن را در خود نگه دارند
وضعیت‌های سازگار و کارآمد، اما در یک منطقه توسعه با کد منتشر نشده قرار دارند
در حال حاضر، بنابراین ممکن است بخواهید در صورت عدم نیاز به ماندن در یک نسخه رسمی فکر کنید
ویژگی های تازه معرفی شده

می توانید آخرین نسخه کد را با بررسی لیست مخزن بیابید
یا با رفتن به "ns-3 منتشر شده" صفحه وب و کلیک بر روی لینک آخرین نسخه.
ما در این مثال آموزشی ادامه خواهیم داد ns-3.22.

اکنون می خواهیم از ابزار پخت برای پایین کشیدن قطعات مختلف استفاده کنیم ns-3 شما خواهید بود
استفاده كردن. ابتدا یک کلمه در مورد دویدن پخت می گوییم.

bake با دانلود بسته های منبع در یک فهرست منبع و نصب کار می کند
کتابخانه ها در یک فهرست ساخت. bake را می توان با ارجاع به باینری اجرا کرد، اما اگر یکی باشد
اجرای bake را از خارج از دایرکتوری که در آن دانلود شده است انتخاب می کند، توصیه می شود
برای قرار دادن bake در مسیر خود، مانند زیر (مثال پوسته bash لینوکس). اول، تغییر دهید
در پوشه 'bake'، و سپس متغیرهای محیطی زیر را تنظیم کنید

$ export BAKE_HOME=`pwd`
$ صادرات PATH=$PATH:$BAKE_HOME:$BAKE_HOME/build/bin
$ صادرات PYTHONPATH=$PYTHONPATH:$BAKE_HOME:$BAKE_HOME/build/lib

این برنامه bake.py را در مسیر پوسته قرار می دهد و به برنامه های دیگر اجازه می دهد
فایل های اجرایی و کتابخانه های ایجاد شده توسط bake را پیدا کنید. اگرچه چندین مورد از پخت استفاده نمی کنند
نیاز به تنظیم PATH و PYTHONPATH مانند بالا، بیلدهای کامل ns-3-allinone (با
بسته های اختیاری) معمولا انجام می دهند.

وارد دایرکتوری فضای کاری شوید و موارد زیر را در پوسته خود تایپ کنید:

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

در مرحله بعد، از bake می خواهیم بررسی کند که آیا ابزار کافی برای دانلود کامپوننت های مختلف داریم یا خیر.
نوع:

$ ./bake.py چک کنید

شما باید چیزی شبیه به زیر را ببینید،

> Python - خوب
> کامپایلر GNU C++ - خوب
> مرکوریال - باشه
> CVS - خوب
> GIT - باشه
> بازار - باشه
> ابزار Tar - خوب
> ابزار باز کردن فشرده - خوب
> ابزار Unrar - گم شده است
> ابزار فشرده سازی داده 7z - خوب
> ابزار فشرده سازی داده XZ - خوب
> ساخت - باشه
> cMake - باشه
> ابزار پچ - خوب
> ابزار autoreconf - خوب

> مسیر جستجو شده برای ابزارها: /usr/lib64/qt-3.3/bin /usr/lib64/ccache
/ usr / local / bin / صندوقچه / usr / bin / usr / local / sbin / usr / sbin / sbin
/home/tomh/bin bin

به طور خاص، ابزارهای دانلود مانند Mercurial، CVS، GIT و Bazaar اصلی ما هستند
نگرانی در این مرحله وجود دارد، زیرا آنها به ما اجازه می دهند کد را واکشی کنیم. لطفا نصب کنید موجود نیست
ابزارها در این مرحله به روش معمول برای سیستم شما (در صورت امکان) یا تماس بگیرید
مدیر سیستم شما در صورت نیاز برای نصب این ابزارها.

در مرحله بعد سعی کنید نرم افزار را دانلود کنید:

$ ./bake.py دانلود کنید

باید چیزی شبیه به:

>> جستجو برای سیستم وابستگی pygoocanvas - OK
>> جستجو برای وابستگی سیستم python-dev - OK
>> جستجو برای سیستم وابستگی pygraphviz - OK
>> دانلود pybindgen-0.16.0.886 - خوب
>> جستجو برای وابستگی سیستم g++ - OK
>> جستجو برای وابستگی سیستم qt4 - OK
>> دانلود netanim-3.105 - خوب
>> دانلود ns-3.22 - خوب

موارد بالا نشان می دهد که سه منبع دانلود شده است. را بررسی کنید منبع فهرست راهنما
حالا و تایپ کنید ls; باید دید:

ls دلار
netanim-3.105 ns-3.22 pybindgen-0.16.0.886

اکنون برای ساختن آماده هستید ns-3 توزیع.

بنا ns-3
بنا با build.py
هنگام کار از یک تربال آزاد شده، اولین باری که آن را می سازید ns-3 پروژه شما می توانید
ساخت با استفاده از یک برنامه راحتی موجود در آلینون فهرست راهنما. این برنامه نام دارد
build.py. این برنامه پروژه را در متداول ترین موارد برای شما پیکربندی می کند
راه مفید با این حال، لطفا توجه داشته باشید که تنظیمات پیشرفته تر و کار با ns-3 اراده
معمولا شامل استفاده از بومی است ns-3 سیستم ساخت، Waf، که در ادامه معرفی خواهد شد
آموزش.

اگر با استفاده از تربال دانلود کردید، باید دایرکتوری به نام چیزی شبیه به آن داشته باشید
ns-allinone-3.22 تحت شما ~/فضای کاری فهرست راهنما. زیر را تایپ کنید:

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

چون در این آموزش با مثال ها و تست ها کار می کنیم و اینطور نیست
به طور پیش فرض ساخته شده است ns-3، آرگومان های build.py به آن می گوید که آنها را برای ما بسازد. در
برنامه همچنین به طور پیش فرض برای ساخت تمام ماژول های موجود است. بعداً می توانید بسازید ns-3
بدون مثال و تست، یا حذف ماژول هایی که برای کار شما ضروری نیستند،
در صورت تمایل

پیام های خروجی کامپایلر معمولی زیادی را خواهید دید که هنگام ساخت اسکریپت ساخت نمایش داده می شوند
قطعات مختلفی که دانلود کردید در نهایت باید موارد زیر را مشاهده کنید:

Waf: خروج از فهرست «/path/to/workspace/ns-allinone-3.22/ns-3.22/build»
"ساخت" با موفقیت به پایان رسید (6m25.032s)

ماژول های ساخته شده:
برنامه های آنتن aodv
ساختمان های پل پیکربندی-فروشگاه
core csma csma-layout
انرژی dsdv dsr
اینترنت fd-net-device flow-monitor
مش lr-wpan lte
mobility mpi netanim (بدون پایتون)
شبکه nix-vector-routing olsr
انتشار نقطه به نقطه طرح بندی نقطه به نقطه
آمار طیف شش لوپان
تست tap-bridge (بدون پایتون) توپولوژی خواندن
موج دستگاه شبکه مجازی uan
وای فای وایمکس

ماژول ها ساخته نشده اند (برای توضیح به آموزش ns-3 مراجعه کنید):
بریت کلیک openflow
تجسم

خروج از فهرست «./ns-3.22»

با توجه به بخش مربوط به ماژول های ساخته نشده:

ماژول ها ساخته نشده اند (برای توضیح به آموزش ns-3 مراجعه کنید):
بریت کلیک openflow
تجسم

این فقط به این معنی است که برخی ns-3 ماژول هایی که وابستگی به کتابخانه های بیرونی دارند ممکن است نداشته باشند
ساخته شده اند، یا اینکه پیکربندی به طور خاص خواسته است که آنها را ساخته نشود. این کار را انجام می دهد
به این معنی نیست که شبیه ساز با موفقیت ساخته نشده است یا اشتباه ارائه خواهد شد
نتایج برای ماژول های فهرست شده به عنوان ساخته شده است.

بنا با پختن
اگر از bake بالا برای واکشی کد منبع از مخازن پروژه استفاده کرده اید، می توانید به این کار ادامه دهید
از آن برای ساخت استفاده کنید ns-3. تایپ کنید

$ ./bake.py ساخت

و شما باید چیزی شبیه به:

>> ساختمان pybindgen-0.16.0.886 - خوب
>> Building netanim-3.105 - خوب
>> ساختمان ns-3.22 - خوب

نکته: شما می توان همچنین انجام دادن هر دو مراحل ، دانلود و ساختن by فراخوانی 'bake.py استقرار '.

اگر شکستی رخ داد، لطفاً به آنچه دستور زیر می گوید نگاه کنید
شما؛ ممکن است اشاره ای به یک وابستگی از دست رفته بدهد:

$ ./bake.py نشان می دهد

این وابستگی های مختلف بسته هایی را که می خواهید بسازید فهرست می کند.

بنا با وف
تا این مرحله، ما از هر دو استفاده کرده ایم build.py اسکریپت، یا پختن ابزار، به دست آوردن
با ساخت و ساز شروع شد ns-3. این ابزارها برای ساختن مفید هستند ns-3 و حمایت می کند
کتابخانه ها، و آنها را به ns-3 دایرکتوری برای فراخوانی ابزار ساخت Waf برای انجام این کار
ساختمان واقعی اکثر کاربران به سرعت به استفاده مستقیم از Waf برای پیکربندی و
ساختن ns-3. بنابراین، برای ادامه، لطفا دایرکتوری کاری خود را به تغییر دهید ns-3 فهرست راهنما
که در ابتدا ساخته اید.

در این مرحله به شدت مورد نیاز نیست، اما انحراف جزئی ارزشمند خواهد بود
و نحوه ایجاد تغییرات در پیکربندی پروژه را بررسی کنید. احتمالاً بیشترین
تغییر پیکربندی مفیدی که می‌توانید انجام دهید، ساختن نسخه بهینه‌سازی شده است
کد شما به طور پیش فرض پروژه خود را برای ساخت نسخه اشکال زدایی پیکربندی کرده اید. بیایید بگوییم
پروژه ساخت یک ساخت بهینه برای توضیح به واف که باید بهینه سازی شود
بیلدهایی که شامل مثال ها و تست ها هستند، باید موارد زیر را اجرا کنید
دستورات:

$ ./waf تمیز
$ ./waf --build-profile=optimized --enable-examples --enable-tests configure

این کار Waf را از دایرکتوری محلی خارج می کند (که به عنوان یک راحتی برای شما ارائه شده است).
اولین دستور برای پاک کردن ساخت قبلی معمولاً کاملاً ضروری نیست اما
تمرین خوبی است (اما ببینید ساختن پروفایل، زیر)؛ ساخته شده قبلی را حذف می کند
کتابخانه ها و فایل های شی موجود در دایرکتوری ساختن/. هنگامی که پروژه دوباره پیکربندی می شود
و سیستم ساخت وابستگی های مختلف را بررسی می کند، باید خروجی را ببینید که به نظر می رسد
مشابه موارد زیر:

تنظیم بالای : .
تنظیم به : ساختن
بررسی "gcc" (کامپایلر c): /usr/bin/gcc
بررسی نسخه سی سی: 4.2.1
بررسی «g++» (کامپایلر c++): /usr/bin/g++
بررسی تقویت شامل موارد زیر است: 1_46_1
چک کردن لیب های تقویتی: بسیار خوب
بررسی پیوند تقویت کننده: بسیار خوب
بررسی مکان کلیک: یافت نشد
بررسی برنامه pkg-config: /sw/bin/pkg-config
بررسی «gtk+-2.0» >= 2.12: بله
بررسی «libxml-2.0» >= 2.7: بله
بررسی نوع uint128_t: یافت نشد
بررسی نوع __uint128_t: بله
بررسی اجرای با دقت بالا: عدد صحیح 128 بیتی (پیش‌فرض)
بررسی هدر stdint.h : بله
بررسی هدر inttypes.h : بله
بررسی هدر sys/inttypes.h : یافت نشد
بررسی هدر sys/types.h : بله
بررسی هدر sys/stat.h: بله
بررسی هدر dirent.h : بله
بررسی هدر stdlib.h : بله
در حال بررسی هدر signal.h : بله
بررسی هدر pthread.h : بله
بررسی هدر stdint.h : بله
بررسی هدر inttypes.h : بله
بررسی هدر sys/inttypes.h : یافت نشد
در حال بررسی کتابخانه rt: یافت نشد
بررسی هدر netpacket/packet.h: یافت نشد
بررسی هدر sys/ioctl.h : بله
بررسی هدر net/if.h : یافت نشد
بررسی هدر net/ethernet.h : بله
بررسی هدر linux/if_tun.h: یافت نشد
بررسی هدر netpacket/packet.h: یافت نشد
بررسی مکان NSC: یافت نشد
بررسی "mpic++" : بله
بررسی "sqlite3": بله
بررسی هدر linux/if_tun.h: یافت نشد
بررسی برنامه sudo: /usr/bin/sudo
بررسی برنامه valgrind: /sw/bin/valgrind
بررسی "gsl" : بله
در حال بررسی پرچم کامپایل -Wno-error=deprecated-d... پشتیبانی: بسیار خوب
در حال بررسی پرچم کامپایل -Wno-error=deprecated-d... پشتیبانی: بسیار خوب
بررسی پرچم کامپایل -fstrict-aliasing... پشتیبانی: بسیار خوب
بررسی پرچم کامپایل -fstrict-aliasing... پشتیبانی: بسیار خوب
بررسی پرچم کامپایل -Wstrict-aliasing... پشتیبانی: بسیار خوب
بررسی پرچم کامپایل -Wstrict-aliasing... پشتیبانی: بسیار خوب
بررسی برنامه doxygen: /usr/local/bin/doxygen
---- خلاصه ای از ویژگی های اختیاری NS-3:
نمایه ساخت: اشکال زدایی
دایرکتوری ساخت: ساخت
Python Bindings: فعال است
یکپارچه سازی BRITE: فعال نیست (BRITE فعال نیست (به گزینه --with-brite مراجعه کنید)
NS-3 روی یکپارچه سازی کلیک کنید: فعال نیست (nsclick فعال نیست (به گزینه --with-nsclick مراجعه کنید)
GtkConfigStore: فعال است
XmlIo: فعال است
Threading Primitives: فعال است
شبیه ساز زمان واقعی: فعال (librt در دسترس نیست)
دستگاه شبکه شبیه سازی شده: فعال ( شامل شناسایی نشده است)
توصیف کننده فایل NetDevice: فعال است
روی FdNetDevice ضربه بزنید: فعال نیست (نیاز به linux/if_tun.h دارد)
شبیه سازی FdNetDevice: فعال نیست (نیاز به netpacket/packet.h دارد)
PlanetLab FdNetDevice: فعال نیست (سیستم عامل PlanetLab شناسایی نشد (به گزینه --force-planetlab مراجعه کنید)
پایگاه شبیه سازی شبکه: فعال نیست (NSC یافت نشد (به گزینه --with-nsc مراجعه کنید)
پشتیبانی MPI: فعال است
یکپارچه سازی OpenFlow NS-3: فعال نیست (کتابخانه های تقویت کننده مورد نیاز یافت نشد، وجود ندارد: سیستم، سیگنال ها، سیستم فایل)
خروجی داده آمار SQlite: فعال است
روی Bridge ضربه بزنید: فعال نیست ( شامل شناسایی نشده است)
PyViz visualizer: فعال است
از sudo برای تنظیم بیت suid استفاده کنید: فعال نیست (گزینه --enable-sudo انتخاب نشده است)
تست های ساخت: فعال است
نمونه های ساخت: فعال است
کتابخانه علمی گنو (GSL): فعال است
"پیکربندی" با موفقیت به پایان رسید (1.944s)

به قسمت آخر خروجی بالا توجه کنید. مقداری ns-3 گزینه ها به طور پیش فرض فعال نیستند یا
برای درست کار کردن نیاز به پشتیبانی از سیستم زیربنایی دارد. به عنوان مثال، برای فعال کردن
XmlTo، کتابخانه libxml-2.0 باید در سیستم پیدا شود. اگر این کتابخانه نبود
یافت، مربوطه ns-3 ویژگی فعال نمی شود و یک پیام خواهد بود
نمایش داده. همچنین توجه داشته باشید که یک ویژگی برای استفاده از برنامه وجود دارد کد: sudo برای تنظیم suid
کمی از برنامه های خاص این به طور پیش فرض فعال نیست و بنابراین این ویژگی گزارش می شود
به عنوان "فعال نشده است."

اکنون پیش بروید و به ساخت اشکال‌زدایی که شامل نمونه‌ها و تست‌ها است، برگردید.

$ ./waf تمیز
$ ./waf --build-profile=debug --enable-examples --enable-tests configure

اکنون سیستم ساخت پیکربندی شده است و می توانید نسخه های اشکال زدایی آن را بسازید ns-3
برنامه ها با تایپ ساده

$./waf

باشه، متاسفم، مجبورت کردم بسازی ns-3 بخشی از سیستم دو بار، اما اکنون می دانید که چگونه این کار را انجام دهید
پیکربندی را تغییر دهید و کد بهینه سازی کنید.

اسکریپت build.py که در بالا توضیح داده شد نیز از این پشتیبانی می کند --enable-examples و فعال کردن-تست ها
آرگومان ها، اما به طور کلی، به طور مستقیم از سایر گزینه های waf پشتیبانی نمی کند. مثلا این
کار نخواهد کرد:

$ ./build.py --disable-python

در نتیجه

build.py: خطا: چنین گزینه ای وجود ندارد: --disable-python

با این حال، اپراتور ویژه -- می توان برای ارسال گزینه های اضافی به waf استفاده کرد، بنابراین
به جای موارد فوق، موارد زیر کار خواهند کرد:

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

همانطور که دستور زیر را تولید می کند ./ واف پیکربندی - غیر فعال کردن پایتون.

در اینجا چند نکته مقدماتی دیگر در مورد Waf آورده شده است.

مجموعه در مقابل ساختن
برخی از دستورات Waf فقط در مرحله پیکربندی معنادار هستند و برخی از دستورات معنی دار هستند
معتبر در مرحله ساخت به عنوان مثال، اگر می خواهید از ویژگی های شبیه سازی استفاده کنید
ns-3، ممکن است بخواهید تنظیم بیت suid را با استفاده از sudo همانطور که در بالا توضیح داده شد فعال کنید. این
معلوم می شود که یک فرمان زمان پیکربندی است، و بنابراین می توانید با استفاده از آن پیکربندی مجدد کنید
دستور زیر که شامل مثال ها و تست ها نیز می شود.

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

اگر این کار را انجام دهید، Waf باید sudo را برای تغییر برنامه‌های سازنده سوکت اجرا کند
کد شبیه سازی برای اجرا به صورت روت

بسیاری دیگر از گزینه های پیکربندی و زمان ساخت در Waf موجود است. برای کشف اینها
گزینه ها، نوع:

$ ./waf -- کمک

ما از برخی از دستورات مربوط به تست در بخش بعدی استفاده خواهیم کرد.

ساختن پروفایل
قبلاً دیدیم که چگونه می توانید Waf را برای آن پیکربندی کنید اشکال زدایی کردن or بهینه می سازد:

$ ./waf --build-profile=debug

همچنین یک نمایه ساخت متوسط ​​وجود دارد، آزاد. -d مترادف با است
---build-profile.

به طور پیش فرض Waf آرتیفکت های ساخت را در قسمت قرار می دهد ساختن فهرست راهنما. می توانید a را مشخص کنید
دایرکتوری خروجی مختلف با -- خارج گزینه، به عنوان مثال

$ ./waf پیکربندی --out=foo

ترکیب آن با نمایه های ساخت به شما امکان می دهد بین گزینه های مختلف کامپایل جابجا شوید
به روشی تمیز:

$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf ساخت
...
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf ساخت
...

این به شما این امکان را می دهد که به جای اینکه همیشه آخرین ساخته ها را بازنویسی کنید، با چندین بیلد کار کنید
ساختن. وقتی جابجا می‌شوید، Waf به جای کامپایل مجدد، فقط آنچه را که باید جمع‌آوری کند
همه چیز.

وقتی پروفایل‌های ساخت سوئیچ را مانند این انجام می‌دهید، باید مراقب باشید که همان را ارائه دهید
هر بار پارامترهای پیکربندی ممکن است تعریف محیطی راحت باشد
متغیرهایی برای جلوگیری از اشتباهات:

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

$ ./waf پیکربندی $NS3CONFIG $NS3DEBUG
$ ./waf ساخت
...
$ ./waf پیکربندی $NS3CONFIG $NS3OPT
$ ./waf ساخت

کامپایلرها
در مثال های بالا، Waf از کامپایلر GCC C++ استفاده می کند. g ++، برای ساخت ns-3است. با این حال،
می توان کامپایلر C++ مورد استفاده توسط Waf را با تعریف کردن تغییر داد CXX محیط
متغیر. به عنوان مثال، برای استفاده از کامپایلر Clang C++، زنگ ++,

$ CXX="clang++" ./waf configure
$ ./waf ساخت

همچنین می توانید Waf را برای انجام کامپایل توزیع شده راه اندازی کنید distcc به روشی مشابه:

$ CXX="distcc g++" ./waf configure
$ ./waf ساخت

اطلاعات بیشتر در مورد distcc و مجموعه توزیع شده را می توان در آن یافت پروژه با ما زیر
بخش مستندات

نصب
Waf ممکن است برای نصب کتابخانه ها در مکان های مختلف سیستم استفاده شود. پیشفرض
محل ساخت کتابخانه ها و فایل های اجرایی در ساختن دایرکتوری، و به دلیل
Waf محل این کتابخانه ها و فایل های اجرایی را می داند، نصب آن ضروری نیست
کتابخانه های جاهای دیگر

اگر کاربران تصمیم بگیرند چیزهایی را خارج از فهرست ساخت نصب کنند، کاربران ممکن است آن را صادر کنند
./ واف نصب فرمان به طور پیش فرض، پیشوند برای نصب است / usr / محلی، به طوری که ./ واف
نصب برنامه ها را در آن نصب خواهد کرد / usr / local / bin، کتابخانه ها به / usr / local / libو
سرصفحه ها به /usr/local/include. معمولاً برای نصب به امتیازات Superuser نیاز است
پیشوند پیش فرض، بنابراین دستور معمولی خواهد بود کد: sudo ./ واف نصب. هنگام دویدن
برنامه هایی با Waf، Waf ابتدا ترجیح می دهد از کتابخانه های مشترک در فهرست ساخت استفاده کند.
سپس به دنبال کتابخانه ها در مسیر کتابخانه پیکربندی شده در محیط محلی می گردد. بنابراین
هنگام نصب کتابخانه ها در سیستم، تمرین خوبی است که بررسی کنید که آیا در نظر گرفته شده است
کتابخانه ها استفاده می شود.

کاربران می‌توانند با عبور از پیشوند دیگری نصب کنند -- پیشوند گزینه در
پیکربندی زمان، مانند:

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

اگر بعداً پس از ساخت، کاربر آن را صادر کرد ./ واف نصب فرمان، پیشوند /opt/local
استفاده خواهد شد.

La ./ واف تمیز اگر Waf باشد، باید از دستور قبل از پیکربندی مجدد پروژه استفاده شود
برای نصب چیزها با پیشوند دیگری استفاده می شود.

خلاصه نیازی به تماس نیست ./ واف نصب به استفاده از ns-3. اکثر کاربران این کار را نخواهند کرد
به این دستور نیاز دارید زیرا Waf کتابخانه‌های فعلی را از ساختن فهرست راهنما،
اما برخی از کاربران ممکن است آن را مفید بدانند اگر مورد استفاده آنها شامل کار با برنامه های بیرونی باشد
از ns-3 دایرکتوری.

یک وف
تنها یک اسکریپت Waf وجود دارد، در سطح بالایی ns-3 درخت منبع همانطور که کار می کنید، شما
ممکن است متوجه شوید که زمان زیادی را در آن صرف می کنید خراش /، یا در اعماق src/...، و نیاز به
واف را احضار کن. شما فقط می توانید به یاد بیاورید که کجا هستید و Waf را به این صورت فراخوانی کنید:

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

اما این کار خسته کننده و مستعد خطا است و راه حل های بهتری هم وجود دارد.

اگر کامل دارید ns-3 مخزن این جواهر کوچک یک شروع است:

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

حتی بهتر است این را به عنوان یک تابع پوسته تعریف کنیم:

تابع $ waff { cd $(hg root) && ./waf $* ; }

ساخت واف $

اگر فقط tarball دارید، یک متغیر محیطی می تواند کمک کند:

$ export NS3DIR="$PWD"
تابع $ waff { cd $NS3DIR && ./waf $* ; }

$ خراش سی دی
ساخت واف $

ممکن است در یک فهرست ماژول وسوسه انگیز باشد که یک چیز بی اهمیت اضافه کنید واف اسکریپت در امتداد خطوط
exec ../../واف. لطفا این کار را نکنید. این برای تازه واردان گیج کننده است، و زمانی که آن را ضعیف انجام شود
منجر به خطاهای ظریف در ساخت می شود. راه حل های بالا راه حل هستند.

تست ns-3
می توانید تست های واحد را اجرا کنید ns-3 توزیع با اجرای ./test.py -c هسته
متن:

هسته $ ./test.py -c

این تست ها به صورت موازی توسط Waf اجرا می شوند. در نهایت باید گزارشی را ببینید که این را بیان می کند

92 از 92 تست گذرانده شد (92 مورد قبول شد، 0 مورد ناموفق، 0 تصادف، 0 خطا valgrind)

این پیام مهم است.

همچنین خروجی خلاصه ای از Waf و اجرای آزمایشی را که هر تست را اجرا می کند، مشاهده خواهید کرد.
که در واقع چیزی شبیه به:

Waf: وارد کردن دایرکتوری «/path/to/workspace/ns-3-allinone/ns-3-dev/build»
Waf: خروج از فهرست «/path/to/workspace/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (1.799s)

ماژول های ساخته شده:
پل برنامه های کاربردی aodv
روی config-store core کلیک کنید
csma csma-layout dsdv
مانیتور جریان انرژی emu
اینترنت lte mesh
تحرک mpi netanim
شبکه nix-vector-routing ns3tcp
ns3wifi olsr openflow
انتشار نقطه به نقطه طرح بندی نقطه به نقطه
آمار طیف tap-bridge
ابزار تست قالب
توپولوژی خواندن و شبکه مجازی دستگاه
ویژوالایزر وای فای وایمکس

PASS: TestSuite ns3-wifi-interference
PASS: هیستوگرام TestSuite

...

PASS: شیء TestSuite
PASS: TestSuite تولید کننده اعداد تصادفی
92 از 92 تست گذرانده شد (92 مورد قبول شد، 0 مورد ناموفق، 0 تصادف، 0 خطا valgrind)

این دستور معمولاً توسط کاربران اجرا می شود تا سریعاً آن را تأیید کنند ns-3 توزیع دارد
درست ساخته شده (به ترتیب عبور: ... خطوط می توانند متفاوت باشند، که اشکالی ندارد. چه
مهم این است که خط خلاصه در پایان همه آزمون ها را گزارش کند. هیچ کدام شکست خوردند یا
سقوط کرد.)

محل دویدن و پیاده روی a خط
ما معمولاً اسکریپت ها را تحت کنترل Waf اجرا می کنیم. این به سیستم ساخت اجازه می دهد تا اطمینان حاصل کند
که مسیرهای کتابخانه مشترک به درستی تنظیم شده اند و کتابخانه ها در آن در دسترس هستند
زمان اجرا برای اجرای یک برنامه کافیست از --اجرا کن گزینه در Waf. بیایید اجرا کنیم ns-3
معادل برنامه hello world همه جا حاضر با تایپ کردن عبارت زیر است:

$ ./waf -- hello-simulator را اجرا کنید

Waf ابتدا بررسی می کند که برنامه به درستی ساخته شده است و یک build if را اجرا می کند
ضروری. سپس Waf برنامه را اجرا می کند که خروجی زیر را تولید می کند.

سلام شبیه ساز

تبریک می گویم! شما اکنون یک کاربر ns-3 هستید!

چی do I do if I نکن دیدن la خروجی؟

اگر پیام های Waf را می بینید که نشان می دهد ساخت با موفقیت به پایان رسیده است، اما این کار را نکنید
خروجی "Hello Simulator" را ببینید، به احتمال زیاد شما حالت ساخت خود را به آن تغییر داده اید
بهینه در بنا با وف بخش، اما تغییر بازگشت به را از دست داده اند اشکال زدایی کردن حالت.
تمام خروجی های کنسول استفاده شده در این آموزش از یک ویژگی خاص استفاده می کند ns-3 جزء ورود به سیستم که
برای چاپ پیام های کاربر در کنسول مفید است. خروجی از این جزء است
هنگامی که کد بهینه‌سازی شده را کامپایل می‌کنید، به‌طور خودکار غیرفعال می‌شود - بهینه‌سازی شده است. اگر شما
خروجی "Hello Simulator" را نمی بینید، عبارت زیر را تایپ کنید:

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

به Waf بگویید که نسخه های اشکال زدایی را بسازد ns-3 برنامه هایی که شامل مثال ها می شود
و تست ها همچنان باید با تایپ کردن، نسخه اشکال زدایی واقعی کد را بسازید

$./waf

حالا، اگر شما اجرا کنید سلام-شبیه ساز برنامه، باید خروجی مورد انتظار را ببینید.

برنامه استدلال
برای تغذیه آرگومان های خط فرمان به یک ns-3 برنامه از این الگو استفاده می کند:

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

نام برنامه خود را جایگزین کنید ، و استدلال برای .
--فرمان-الگو استدلال به Waf اساسا دستور العملی برای ساختن واقعی است
خط فرمان Waf باید برای اجرای برنامه استفاده کند. Waf بررسی می کند که ساختنی است
کامل، مسیرهای کتابخانه مشترک را تنظیم می کند، سپس فایل اجرایی را با استفاده از ارائه شده فراخوانی می کند
الگوی خط فرمان، درج نام برنامه برای %s نگهدارنده مکان (این را قبول دارم
کمی ناخوشایند است، اما این راه است. پچ ها خوش آمدید!)

مثال مفید دیگر اجرای یک مجموعه آزمایشی به تنهایی است. بیایید فرض کنیم که الف
mytest مجموعه آزمایشی وجود دارد (اینطور نیست). در بالا، ما از ./test.py اسکریپت برای اجرای یک کل
مجموعه ای از آزمایشات به صورت موازی، با فراخوانی مکرر برنامه آزمایش واقعی، دونده آزمون.
استناد کردن دونده آزمون به طور مستقیم برای یک آزمون:

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

این استدلال ها را به دونده آزمون برنامه از آنجا که mytest وجود ندارد،
پیام خطا ایجاد خواهد شد. برای چاپ موجود دونده آزمون گزینه ها:

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

اشکال زدایی
برای اجرا ns-3 برنامه های تحت کنترل یک ابزار دیگر، مانند دیباگر (به عنوان مثال gdb)
یا بررسی کننده حافظه (به عنوان مثال والگریند) از مشابه استفاده می کنید --command-template="..." فرم.

به عنوان مثال، برای اجرای خود ns-3 برنامه سلام-شبیه ساز با استدلال ها تحت
gdb دیباگر:

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

توجه کنید که ns-3 نام برنامه همراه با --اجرا کن آرگومان و ابزار کنترل
(اینجا gdb) اولین نشانه در است --command-template بحث و جدل. در --آرگس می گوید gdb
که باقیمانده خط فرمان متعلق به برنامه "فراهم" است. (مقداری gdb's
نمی فهمم --آرگس ویژگی. در این مورد، آرگومان های برنامه را حذف کنید
--فرمان-الگوو استفاده از gdb فرمان تنظیم قوس.)

ما می‌توانیم این دستور و دستور قبلی را برای اجرای آزمایشی در زیر دیباگر ترکیب کنیم:

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

کارگر فهرست راهنما
Waf باید از محل آن در بالای صفحه اجرا شود ns-3 درخت این کار می شود
دایرکتوری که فایل های خروجی در آن نوشته می شود. اما چه می شود اگر بخواهید آن ها را حفظ کنید
la ns-3 درخت منبع؟ استفاده کنید --cwd بحث و جدل:

$ ./waf --cwd=...

ممکن است راحت‌تر از دایرکتوری کاری خود شروع کنید، جایی که خروجی را می‌خواهید
فایل‌ها، که در این صورت کمی غیر مستقیم می‌تواند کمک کند:

تابع $ waff {
CWD = "$PWD"
cd $NS3DIR >/dev/null
./waf --cwd="$CWD" $*
cd - >/dev/null
}

این تزیین نسخه قبلی فهرست کاری فعلی را ذخیره می کند، cdبه
دایرکتوری Waf، سپس به Waf دستور می دهد تا دایرکتوری کاری را تغییر دهد به عقب به نجات یافتگان
دایرکتوری کاری فعلی قبل از اجرای برنامه

مفهومی بررسی اجمالی


اولین کاری که باید قبل از شروع به نگاه کردن یا نوشتن انجام دهیم ns-3 کد به است
چند مفهوم اصلی و انتزاعی را در سیستم توضیح دهید. بسیاری از این ممکن است ظاهر شود
برای برخی واضح است، اما توصیه می کنیم برای مطالعه این موضوع وقت بگذارید
بخش فقط برای اطمینان از شروع شما بر روی یک پایه محکم.

کلید انتزاعات
در این بخش، برخی از اصطلاحاتی را که معمولاً در شبکه‌سازی استفاده می‌شوند، اما دارای a
معنی خاص در ns-3.

گره
در اصطلاحات اینترنتی، دستگاه محاسباتی که به یک شبکه متصل می شود، a نامیده می شود میزبان or
گاهی اوقات یک پایان سیستم. زیرا ns-3 هست یک شبکه شبیه ساز، نه به طور خاص
اینترنت شبیه ساز، ما عمداً از عبارت میزبان استفاده نمی کنیم زیرا از نزدیک است
مرتبط با اینترنت و پروتکل های آن در عوض، ما از یک اصطلاح عمومی تر نیز استفاده می کنیم
توسط شبیه سازهای دیگر که در تئوری گراف سرچشمه می گیرند استفاده می شود --- the گره.

In ns-3 انتزاع اولیه دستگاه محاسباتی گره نامیده می شود. این انتزاع است
در C++ توسط کلاس نشان داده شده است گره. گره کلاس متدهایی را برای مدیریت ارائه می دهد
نمایش دستگاه های محاسباتی در شبیه سازی

باید به فکر الف باشید گره به عنوان یک کامپیوتر که قابلیت هایی را به آن اضافه خواهید کرد. یکی اضافه می کند
چیزهایی مانند برنامه‌ها، پشته‌های پروتکل و کارت‌های جانبی همراه با آنها
درایورها برای فعال کردن رایانه برای انجام کارهای مفید. ما از همان مدل اولیه استفاده می کنیم ns-3.

کاربرد
به طور معمول نرم افزارهای کامپیوتری به دو دسته کلی تقسیم می شوند. سیستم نرم افزار سازماندهی می کند
منابع مختلف کامپیوتر مانند حافظه، چرخه های پردازنده، دیسک، شبکه و غیره،
طبق برخی از مدل های محاسباتی نرم افزار سیستم معمولاً از آن منابع استفاده نمی کند
برای تکمیل وظایفی که مستقیماً به نفع کاربر است. یک کاربر معمولاً یک را اجرا می کند استفاده
که منابع کنترل شده توسط نرم افزار سیستم را به دست می آورد و برای انجام برخی از آنها استفاده می کند
هدف.

اغلب، خط جدایی بین نرم افزار سیستم و نرم افزار کاربردی در
تغییر سطح امتیاز که در تله های سیستم عامل اتفاق می افتد. که در ns-3 واقعی وجود ندارد
مفهوم سیستم عامل و به خصوص هیچ مفهومی از سطوح امتیاز یا فراخوانی سیستم.
با این حال، ما ایده یک برنامه کاربردی را داریم. درست همانطور که برنامه های نرم افزاری اجرا می شوند
کامپیوترها برای انجام وظایف در "دنیای واقعی"، ns-3 برنامه ها اجرا می شوند ns-3 گره ها به
شبیه سازی درایو در دنیای شبیه سازی شده

In ns-3 انتزاع اولیه برای یک برنامه کاربری که فعالیتی را ایجاد می کند
شبیه سازی شده برنامه است. این انتزاع در C++ توسط کلاس نمایش داده می شود
کاربرد. کاربرد class متدهایی را برای مدیریت بازنمایی های ارائه می دهد
نسخه ما از برنامه های کاربردی سطح کاربر در شبیه سازی. از توسعه دهندگان انتظار می رود
تخصصی کردن کاربرد کلاس در مفهوم برنامه نویسی شی گرا برای ایجاد جدید
برنامه های کاربردی. در این آموزش از تخصص های کلاس استفاده خواهیم کرد کاربرد نام
UdpEchoClientApplication و UdpEchoServerApplication. همانطور که ممکن است انتظار داشته باشید، اینها
برنامه ها یک مجموعه برنامه کاربردی کلاینت/سرور را می سازند که برای تولید و شبیه سازی پژواک استفاده می شود
بسته های شبکه

کانال
در دنیای واقعی، می توان یک کامپیوتر را به یک شبکه متصل کرد. اغلب رسانه ها که بیش از
جریان داده در این شبکه ها نامیده می شود کانال. هنگامی که کابل اترنت خود را به
با اتصال به دیوار، کامپیوتر خود را به یک ارتباط اترنت وصل می کنید
کانال در دنیای شبیه سازی شده از ns-3، یکی متصل می شود گره به یک شی که نشان دهنده a
کانال ارتباطی در اینجا انتزاع اصلی زیرشبکه ارتباطی نامیده می شود
کانال و در C++ توسط کلاس نمایش داده می شود کانال.

La کانال کلاس متدهایی را برای مدیریت اشیاء زیرشبکه ارتباطی و
اتصال گره ها به آنها کانال ها همچنین ممکن است توسط توسعه دهندگان در شیء تخصصی باشد
حس برنامه نویسی گرا آ کانال تخصص ممکن است چیزی به سادگی مدلسازی کند
سیم تخصصی کانال همچنین می تواند چیزهایی را به پیچیدگی یک اترنت بزرگ مدل کند
سوئیچ یا فضای سه بعدی پر از موانع در مورد شبکه های بی سیم.

ما از نسخه های تخصصی آن استفاده خواهیم کرد کانال نام CsmaChannel, PointToPointChannel
و کانال Wifi در این آموزش در CsmaChannelبرای مثال، نسخه ای از a را مدل می کند
زیرشبکه ارتباطی که a حامل حس چندگانه دسترسی ارتباط
متوسط. این به ما عملکردی شبیه اترنت می دهد.

خالص دستگاه
قبلاً اینطور بود که اگر می خواستید یک رایانه را به یک شبکه وصل کنید، مجبور بودید
نوع خاصی از کابل شبکه و یک دستگاه سخت افزاری به نام (در اصطلاح رایانه شخصی) a
پیرامونی کارت که باید در کامپیوتر شما نصب شود. اگر کارت جانبی
برخی از عملکردهای شبکه را پیاده سازی کردند، آنها را کارت رابط شبکه نامیدند NIC ها.
امروزه اکثر کامپیوترها دارای سخت افزار رابط شبکه هستند و کاربران آن را نمی بینند
این بلوک های ساختمانی

یک NIC بدون درایور نرم افزاری برای کنترل سخت افزار کار نخواهد کرد. در یونیکس (یا
لینوکس)، یک قطعه سخت افزار جانبی به عنوان یک طبقه بندی می شود دستگاه. دستگاه ها کنترل می شوند
با استفاده از دستگاه درایور، و دستگاه های شبکه (NIC) با استفاده از کنترل می شوند شبکه دستگاه
درایور در مجموع به عنوان شناخته می شود خالص دستگاه. در یونیکس و لینوکس شما به این نت مراجعه می کنید
دستگاه ها با نام هایی مانند eth0.

In ns-3 la خالص دستگاه انتزاع هم درایور نرم افزار و هم شبیه سازی شده را پوشش می دهد
سخت افزار یک دستگاه شبکه در یک "نصب" شده است گره به منظور فعال کردن گره به
با دیگران ارتباط برقرار کند گره ها در شبیه سازی از طریق کانال ها. درست مثل یک کامپیوتر واقعی،
a گره ممکن است به بیش از یک متصل شود کانال از طریق چندگانه NetDevices.

انتزاع دستگاه خالص در C++ توسط کلاس نمایش داده می شود NetDevice. NetDevice
class متدهایی برای مدیریت اتصالات به گره و کانال اشیاء؛ و شاید
توسط توسعه دهندگان در مفهوم برنامه نویسی شی گرا تخصصی شده است. ما استفاده خواهیم کرد
چندین نسخه تخصصی از NetDevice نام CsmaNetDevice, PointToPointNetDevice,
و WifiNetDevice در این آموزش همانطور که یک NIC اترنت برای کار با یک طراحی شده است
شبکه اترنت، CsmaNetDevice برای کار با a طراحی شده است CsmaChannel؛
PointToPointNetDevice برای کار با a طراحی شده است PointToPointChannel و یک WifiNetNevice
برای کار با a طراحی شده است کانال Wifi.

توپولوژی یاران
در یک شبکه واقعی، کامپیوترهای میزبان را با NIC های اضافه شده (یا داخلی) خواهید یافت. که در ns-3 we
می گویند که پیدا خواهید کرد گره ها با پیوست NetDevices. در یک شبکه بزرگ شبیه سازی شده
شما باید ارتباطات زیادی را بین آنها ترتیب دهید گره ها, NetDevices و کانال ها.

از زمان اتصال NetDevices به گره ها, NetDevices به کانال ها، اختصاص آدرس های IP،
و غیره، از جمله وظایف رایج در ns-3، ما آنچه را که می نامیم ارائه می دهیم توپولوژی یاران برای ساختن این
تا حد امکان آسان به عنوان مثال، ممکن است بسیار متمایز باشد ns-3 عملیات اصلی به
یک NetDevice ایجاد کنید، یک آدرس MAC اضافه کنید، آن دستگاه نت را روی یک نصب کنید گره، پیکربندی کنید
پشته پروتکل گره، و سپس وصل کنید NetDevice به کانال. حتی عملیات بیشتر
برای اتصال چندین دستگاه به کانال های چند نقطه ای و سپس اتصال مورد نیاز است
شبکه های فردی با هم به اینترنت ورک تبدیل می شوند. ما اشیاء کمکی توپولوژی را ارائه می دهیم که
این بسیاری از عملیات متمایز را در یک مدل آسان برای استفاده برای راحتی خود ترکیب کنید.

A نام خانوادگی ns-3 خط
اگر سیستم را همانطور که در بالا پیشنهاد شد دانلود کردید، نسخه ای از آن را خواهید داشت ns-3 در
دایرکتوری فراخوانی شد استراحت تحت فهرست اصلی شما به آن دایرکتوری انتشار تغییر دهید، و
شما باید یک ساختار دایرکتوری چیزی شبیه به زیر پیدا کنید:

AUTHORS نمونه هایی از scratch utils waf.bat*
bindings LICENSE src utils.py waf-tools
ساخت ns3 test.py* utils.pyc wscript
CHANGES.html README testpy-output VERSION wutils.py
doc RELEASE_NOTES testpy.supp waf* wutils.pyc

تغییر به نمونه ها/آموزش فهرست راهنما. شما باید فایلی به نام را ببینید first.cc واقع شده
آنجا. این یک اسکریپت است که یک پیوند نقطه به نقطه ساده بین دو گره ایجاد می کند
و یک بسته واحد را بین گره ها اکو کنید. بیایید نگاهی به خط آن اسکریپت بیندازیم
خط، پس جلو بروید و باز کنید first.cc در ویرایشگر مورد علاقه شما

تکرار واضحات
خط اول فایل یک خط حالت emacs است. این به emacs در مورد قالب بندی می گوید
قراردادها (سبک کدنویسی) که ما در کد منبع خود استفاده می کنیم.

/* -*- حالت:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

این همیشه یک موضوع بحث برانگیز است، بنابراین ممکن است آن را از سر راه برداریم
بلافاصله. مستقیما. ns-3 پروژه نیز مانند بسیاری از پروژه های بزرگ، از سبک کدنویسی استفاده کرده است
که همه کدهای ارائه شده باید به آن پایبند باشند. اگر می خواهید کد خود را به
پروژه، در نهایت باید با ns-3 استاندارد کدگذاری همانطور که در
فایل doc/codingstd.txt یا در صفحه وب پروژه نشان داده شده است اینجا کلیک نمایید.

ما به شما توصیه می کنیم، خوب، فقط به ظاهر و احساس عادت کنید ns-3 کد و اتخاذ کنید
این استاندارد هر زمان که با کد ما کار می کنید. همه تیم توسعه و
مشارکت کنندگان این کار را با مقادیر مختلف غرغر انجام داده اند. خط حالت emacs در بالا
اگر از ویرایشگر emacs استفاده می کنید، دریافت قالب بندی صحیح را آسان تر می کند.

La ns-3 شبیه ساز با استفاده از مجوز عمومی عمومی گنو مجوز دارد. را خواهید دید
قانونی مناسب گنو در سر هر فایل موجود در ns-3 توزیع اغلب شما
یک اعلان حق چاپ برای یکی از موسسات درگیر در آن مشاهده خواهد شد ns-3 پروژه بالا
متن GPL و نویسنده ای که در زیر ذکر شده است.

/*
* این برنامه نرم افزار رایگان است. شما می توانید آن را دوباره توزیع کنید و/یا تغییر دهید
* آن را تحت شرایط مجوز عمومی عمومی گنو نسخه 2 به عنوان
* منتشر شده توسط بنیاد نرم افزار آزاد؛
*
* این برنامه به امید اینکه مفید واقع شود توزیع شده است
* اما بدون ضمانت؛ حتی بدون ضمانت ضمنی
* قابلیت خرید و فروش یا تناسب اندام برای یک هدف خاص. را ببینید
* مجوز عمومی عمومی گنو برای جزئیات بیشتر.
*
* شما باید یک کپی از مجوز عمومی عمومی گنو دریافت کرده باشید
* همراه با این برنامه؛ اگر نه، به نرم افزار آزاد بنویسید
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

ماژول ها شامل
کد مناسب با تعدادی عبارت include شروع می شود.

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"

برای کمک به کاربران سطح بالای اسکریپت ما با تعداد زیادی فایل شامل موجود در آن مقابله کنند
سیستم، ما شامل ماژول های نسبتا بزرگ است. ما یک تک ارائه می دهیم
شامل فایلی است که به صورت بازگشتی همه فایل های شامل مورد استفاده در هر ماژول را بارگیری می کند.
به جای اینکه دقیقاً سرفصل مورد نیاز خود را جستجو کنید و احتمالاً باید یک هدر دریافت کنید
تعداد وابستگی‌ها درست است، ما به شما این امکان را می‌دهیم که گروهی از فایل‌ها را به صورت گسترده بارگیری کنید
دانه دانه بودن. این کارآمدترین رویکرد نیست، اما مطمئناً باعث نوشتن می شود
اسکریپت ها بسیار ساده تر

هر کدام از ns-3 شامل فایل ها در دایرکتوری به نام قرار می گیرد ns3 (در زیر ساخت
دایرکتوری) در طول فرآیند ساخت به جلوگیری از برخورد نام فایل کمک می کند. در
ns3/core-module.h فایل مربوط به ماژول ns-3 است که در دایرکتوری پیدا خواهید کرد
src/core در توزیع نسخه دانلود شده شما. اگر این دایرکتوری را فهرست کنید، این کار را خواهید کرد
تعداد زیادی فایل هدر را پیدا کنید. وقتی ساختنی را انجام می دهید، Waf هدر عمومی را قرار می دهد
پرونده ها در ns3 دایرکتوری تحت مناسب ساخت / اشکال زدایی or ساخت/بهینه سازی فهرست راهنما
بسته به پیکربندی شما Waf همچنین به طور خودکار یک ماژول شامل تولید می کند
فایل برای بارگیری همه فایل های هدر عمومی.

از آنجایی که مطمئناً این آموزش را به صورت مذهبی دنبال می کنید، قبلاً انجام داده اید
a

$ ./waf -d اشکال زدایی --enable-examples --enable-tests configure

به منظور پیکربندی پروژه برای اجرای اشکال‌زدایی بیلدهایی که شامل مثال‌ها و آزمایش‌ها می‌شود.
شما همچنین یک را انجام داده اید

$./waf

برای ساخت پروژه پس حالا اگر به دایرکتوری نگاه کنید ../../build/debug/ns3 شما خواهد شد
پیدا کردن چهار ماژول شامل فایل های نشان داده شده در بالا. می توانید به محتویات آن نگاهی بیندازید
این فایل ها و متوجه می شوند که شامل همه فایل های عمومی شامل فایل های خود می شوند
ماژول های مربوطه

Ns3 فضای نام
خط بعدی در first.cc اسکریپت یک اعلان فضای نام است.

با استفاده از فضای نام ns3;

La ns-3 پروژه در یک فضای نام ++C به نام پیاده سازی می شود ns3. این همه را گروه بندی می کند
ns-3-اعلامیه های مرتبط در محدوده ای خارج از فضای نام جهانی، که امیدواریم کمک کند
با ادغام با سایر کدها ++C با استفاده از بیانیه را معرفی می کند ns-3 فضای نام
به منطقه اعلامی فعلی (جهانی). این یک راه فانتزی برای گفتن آن بعد است
این اعلامیه، شما مجبور نخواهید بود تایپ کنید ns3:: عملگر وضوح محدوده قبل از همه
la ns-3 کد برای استفاده از آن اگر با فضاهای نام آشنا نیستید، لطفاً مشورت کنید
تقریباً هر آموزش ++ C و مقایسه کنید ns3 فضای نام و استفاده در اینجا با نمونه هایی از
STD فضای نام و با استفاده از فضای نام std; جملاتی که اغلب در بحث ها پیدا می کنید
of دادگاه و جریان ها

ورود به سیستم
خط بعدی فیلمنامه به شرح زیر است

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample")؛

ما از این بیانیه به عنوان مکانی مناسب برای صحبت در مورد مستندات Doxygen خود استفاده خواهیم کرد
سیستم. اگر به وب سایت پروژه نگاه کنید، ns-3 پروژه، پیوندی به آن پیدا خواهید کرد
"اسناد" در نوار ناوبری. اگر این لینک را انتخاب کنید، به ما منتقل خواهید شد
صفحه مستندات پیوندی به "آخرین نسخه" وجود دارد که شما را به آن می برد
اسناد برای آخرین نسخه پایدار ns-3. اگر "API" را انتخاب کنید
لینک مستندات"، به آدرس زیر هدایت خواهید شد ns-3 صفحه اسناد API.

در سمت چپ، یک نمایش گرافیکی از ساختار آن را خواهید دید
مستندات. یک مکان خوب برای شروع این است NS-3 ماژول ها "کتاب" در ns-3 ناوبری
درخت اگر گسترش دهید ماژول ها لیستی از ns-3 مستندات ماژول در
مفهوم ماژول در اینجا مستقیماً به ماژول پیوند می خورد شامل فایل هایی است که در بالا مورد بحث قرار گرفت. در
ns-3 زیرسیستم ورود به سیستم در مورد بحث قرار گرفته است ++C می سازد استفاده می شود by همه ماژول ها بخش، بنابراین
ادامه دهید و آن گره مستندسازی را گسترش دهید. حالا، گسترش دهید اشکال زدایی کتاب و سپس
انتخاب کنید ورود به سیستم احتمال برد مراجعه کنید.

اکنون باید به مستندات Doxygen برای ماژول Logging نگاه کنید. در
لیستی از #تعريف كردن's در بالای صفحه شما ورودی برای را خواهید دید
NS_LOG_COMPONENT_DEFINE. قبل از پریدن به داخل، احتمالاً خوب است که به دنبال آن بگردید
"توضیحات تفصیلی" ماژول ورود به سیستم برای درک عملکرد کلی. شما
می توانید به پایین پیمایش کنید یا پیوند "بیشتر..." را در زیر نمودار همکاری برای انجام انتخاب کنید
این.

هنگامی که یک ایده کلی از آنچه در حال وقوع است دارید، ادامه دهید و نگاهی به موارد خاص بیندازید
NS_LOG_COMPONENT_DEFINE مستندات. من اسناد را در اینجا کپی نمی کنم، اما به
به طور خلاصه، این خط یک مؤلفه ورود به سیستم به نام را اعلام می کند FirstScriptExample اجازه میدهد
شما می توانید ثبت پیام های کنسول را با اشاره به نام فعال و غیرفعال کنید.

اصلی عملکرد
خطوط بعدی اسکریپت که خواهید یافت عبارتند از:

INT
اصلی (int argc، char *argv[])
{

این فقط اعلان عملکرد اصلی برنامه شما (اسکریپت) است. همانطور که در
هر برنامه ++C، باید یک تابع اصلی تعریف کنید که اولین تابع اجرا شود.
اینجا اصلا چیز خاصی نیست شما ns-3 اسکریپت فقط یک برنامه ++C است.

خط بعدی وضوح زمانی را روی یک نانوثانیه تنظیم می کند که اتفاقاً پیش فرض است
مقدار:

Time::SetResolution (زمان::NS)؛

وضوح کوچکترین مقدار زمانی است که می توان نمایش داد (و همچنین کوچکترین
تفاوت قابل نمایش بین دو مقدار زمانی). می توانید وضوح تصویر را دقیقاً تغییر دهید
یک بار. مکانیسمی که این انعطاف‌پذیری را قادر می‌سازد تا حدودی تشنه حافظه است، بنابراین یک بار
وضوح به صراحت تنظیم شده است، ما حافظه را آزاد می کنیم و از به روز رسانی بیشتر جلوگیری می کنیم.
(اگر وضوح را به طور صریح تنظیم نکنید، به طور پیش فرض روی یک نانوثانیه خواهد بود و
با شروع شبیه سازی حافظه آزاد می شود.)

دو خط بعدی اسکریپت برای فعال کردن دو مؤلفه ورود به سیستم استفاده می شود
به برنامه های Echo Client و Echo Server:

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

اگر مستندات مؤلفه Logging را خوانده باشید، آن را در آنجا دیده اید
تعدادی از سطوح پرحرفی/جزئیات ورود به سیستم هستند که می توانید روی هر جزء فعال کنید.
این دو خط کد، ثبت اشکال زدایی را در سطح INFO برای مشتریان echo و
سرورها این باعث می شود که برنامه به هنگام ارسال بسته ها، پیام ها را چاپ کند
و در طول شبیه سازی دریافت شد.

اکنون مستقیماً به تجارت ایجاد توپولوژی و اجرای شبیه سازی خواهیم پرداخت.
ما از اشیاء کمکی توپولوژی استفاده می کنیم تا این کار را تا حد امکان آسان کنیم.

توپولوژی یاران
NodeContainer
دو خط کد بعدی در اسکریپت ما در واقع کد را ایجاد خواهند کرد ns-3 گره اشیایی که
رایانه های موجود در شبیه سازی را نشان خواهد داد.

گره های NodeContainer.
nodes.Create (2);

بیایید مستندات را پیدا کنیم NodeContainer قبل از ادامه کلاس یک راه دیگر
برای ورود به مستندات یک کلاس معین از طریق کلاس تب در Doxygen
صفحات اگر هنوز Doxygen را دارید، فقط به بالای صفحه بروید و
انتخاب کنید کلاس زبانه باید مشاهده کنید که مجموعه جدیدی از تب ها ظاهر می شوند که یکی از آنها این است طبقه
فهرست. در زیر آن تب، لیستی از همه موارد را مشاهده خواهید کرد ns-3 کلاس ها. به پایین اسکرول کنید،
دنبال ns3::NodeContainer. وقتی کلاس را پیدا کردید، پیش بروید و آن را برای رفتن انتخاب کنید
مستندات کلاس

شاید به خاطر داشته باشید که یکی از انتزاعات کلیدی ما این است گره. این نشان دهنده یک کامپیوتر است
که می خواهیم چیزهایی مانند پشته های پروتکل، برنامه های کاربردی و لوازم جانبی را به آن اضافه کنیم
کارت ها در NodeContainer کمک کننده توپولوژی راهی مناسب برای ایجاد، مدیریت و
دسترسی به هر گره اشیایی که برای اجرای یک شبیه سازی ایجاد می کنیم. خط اول بالا
فقط یک NodeContainer را اعلام می کند که ما آن را فراخوانی می کنیم گره. خط دوم به ساختن
روش در گره شی و از ظرف می خواهد دو گره ایجاد کند. همانطور که در
داکسیژن، ظرف را به داخل می خواند ns-3 سیستم مناسب برای ایجاد دو گره
اشیاء و اشاره گرها به آن اشیا را در داخل ذخیره می کند.

گره هایی که در اسکریپت ایستاده اند هیچ کاری نمی کنند. مرحله بعدی در ساخت الف
توپولوژی این است که گره های خود را به یکدیگر به یک شبکه متصل کنیم. ساده ترین شکل شبکه ما
پشتیبانی یک پیوند نقطه به نقطه واحد بین دو گره است. ما یکی از آن ها را خواهیم ساخت
لینک های اینجا

PointToPointHelper
ما در حال ساخت یک پیوند نقطه به نقطه، و در الگویی هستیم که کاملاً تبدیل می شود
برای شما آشنا، ما از یک شی کمک کننده توپولوژی برای انجام کارهای سطح پایین مورد نیاز برای قرار دادن استفاده می کنیم
لینک با هم به یاد داشته باشید که دو مورد از انتزاعات کلیدی ما عبارتند از NetDevice و
کانال. در دنیای واقعی، این اصطلاحات تقریباً با کارت های جانبی و
کابل های شبکه معمولاً این دو چیز کاملاً به هم گره خورده اند و یکی نمی تواند
به عنوان مثال، دستگاه‌های اترنت و کانال‌های بی‌سیم را انتظار داشته باشید. توپولوژی ما
کمک کنندگان این جفت صمیمی را دنبال می کنند و بنابراین شما از یک تک استفاده خواهید کرد
PointToPointHelper برای پیکربندی و اتصال ns-3 PointToPointNetDevice و
PointToPointChannel اشیاء در این اسکریپت

سه خط بعدی در فیلمنامه عبارتند از:

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("تاخیر"، StringValue ("2 میلی ثانیه"));

خط اول ،

PointToPointHelper pointToPoint;

مصداق الف PointToPointHelper شی روی پشته از دیدگاه سطح بالا
خط بعدی،

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

می گوید PointToPointHelper شیء استفاده از مقدار "5 مگابیت در ثانیه" (پنج مگابیت در ثانیه) به عنوان
"DataRate" هنگامی که یک را ایجاد می کند PointToPointNetDevice هدف - شی.

از منظری دقیق تر، رشته "DataRate" مطابق با چیزی است که ما آن را an می نامیم
صفت از PointToPointNetDevice. اگر به Doxygen برای کلاس نگاه کنید
ns3::PointToPointNetDevice و اسناد مربوط به آن را پیدا کنید GetTypeId روش، شما
لیستی از خواص برای دستگاه تعریف شده است. در این میان "DataRate" است
صفت. قابل مشاهده ترین برای کاربر ns-3 اشیاء دارای لیست های مشابه هستند خواص. ما از این استفاده می کنیم
مکانیزم برای پیکربندی آسان شبیه سازی ها بدون کامپایل مجدد همانطور که در a مشاهده خواهید کرد
بخش زیر

مشابه "DataRate" در PointToPointNetDevice شما یک "تاخیر" پیدا خواهید کرد صفت
مرتبط با PointToPointChannel. خط پایانی،

pointToPoint.SetChannelAttribute ("تاخیر"، StringValue ("2 میلی ثانیه"));

می گوید PointToPointHelper برای استفاده از مقدار "2ms" (دو میلی ثانیه) به عنوان مقدار
تاخیر انتقال هر نقطه به نقطه کانال که متعاقبا ایجاد می کند.

NetDeviceContainer
در این مرحله از فیلمنامه، ما یک NodeContainer که شامل دو گره است. ما یک
PointToPointHelper که آماده و آماده ساخت است PointToPointNetDevices و سیم
PointToPointChannel اشیاء بین آنها همانطور که ما از آن استفاده کردیم NodeContainer توپولوژی
شی کمکی برای ایجاد گره ها برای شبیه سازی ما، از PointToPointHelper
برای انجام کارهای مربوط به ایجاد، پیکربندی و نصب دستگاه های ما برای ما. ما
باید لیستی از تمام اشیاء NetDevice ایجاد شده داشته باشد، بنابراین از a استفاده می کنیم
NetDeviceContainer برای نگه داشتن آنها همانطور که از NodeContainer برای نگه داشتن گره های خود استفاده کردیم
ایجاد شده. دو خط کد زیر،

دستگاه های NetDeviceContainer؛
دستگاه ها = pointToPoint.Install (گره ها);

پیکربندی دستگاه ها و کانال به پایان می رسد. خط اول دستگاه را اعلام می کند
کانتینری که در بالا ذکر شد و دومی بار سنگین را انجام می دهد. در نصب روش
la PointToPointHelper طول می کشد NodeContainer به عنوان یک پارامتر در داخل، الف
NetDeviceContainer خلق شده است. برای هر گره در NodeContainer (دقیقا باید وجود داشته باشد
دو برای پیوند نقطه به نقطه) الف PointToPointNetDevice ایجاد و در دستگاه ذخیره می شود
ظرف آ PointToPointChannel ایجاد شده است و این دو PointToPointNetDevices هستند
پیوست شده است. هنگامی که اشیاء توسط PointToPointHelperاز خواص قبلا
مجموعه در helper برای مقداردهی اولیه مورد مربوطه استفاده می شود خواص در ایجاد شده
اشیاء.

پس از اجرای pointToPoint.Install (گره ها) فراخوانی ما دو گره خواهیم داشت که هر کدام دارای یک
دستگاه شبکه نقطه به نقطه و یک کانال نقطه به نقطه واحد بین آنها نصب شده است.
هر دو دستگاه به گونه‌ای پیکربندی می‌شوند که داده‌ها را با سرعت پنج مگابیت در ثانیه از طریق اینترنت انتقال دهند
کانالی که دارای تاخیر انتقال دو میلی ثانیه است.

InternetStackHelper
اکنون گره‌ها و دستگاه‌ها را پیکربندی کرده‌ایم، اما هیچ پشته پروتکلی نصب نکرده‌ایم
روی گره های ما دو خط کد بعدی به این موضوع رسیدگی خواهد کرد.

پشته InternetStackHelper;
stack.Install (گره ها)؛

La InternetStackHelper یک کمک کننده توپولوژی است که به پشته های اینترنت می باشد
PointToPointHelper به دستگاه های شبکه نقطه به نقطه است. در نصب روش طول می کشد
NodeContainer به عنوان یک پارامتر وقتی اجرا شد، یک پشته اینترنت نصب می کند
(TCP، UDP، IP، و غیره) روی هر یک از گره های موجود در ظرف گره.

IPv4AddressHelper
در مرحله بعد باید دستگاه های موجود در گره های خود را با آدرس های IP مرتبط کنیم. ما ارائه می دهیم
کمک کننده توپولوژی برای مدیریت تخصیص آدرس های IP. تنها API قابل مشاهده توسط کاربر این است که
آدرس IP پایه و ماسک شبکه را برای استفاده در هنگام انجام آدرس واقعی تنظیم کنید
تخصیص (که در سطح پایین تری در داخل کمک کننده انجام می شود).

دو خط کد بعدی در اسکریپت مثال ما، first.cc,

آدرس Ipv4AddressHelper;
address.SetBase ("10.1.1.0"، "255.255.255.0");

یک شی کمکی آدرس را اعلام کنید و به آن بگویید که باید شروع به تخصیص آدرس های IP کند
از شبکه 10.1.1.0 با استفاده از ماسک 255.255.255.0 برای تعریف بیت های قابل تخصیص. توسط
به طور پیش فرض آدرس های تخصیص داده شده از یک شروع می شود و به طور یکنواخت افزایش می یابد، بنابراین اولین
آدرس اختصاص داده شده از این پایگاه 10.1.1.1 و به دنبال آن 10.1.1.2 و غیره خواهد بود.
سطح ns-3 سیستم در واقع تمام آدرس های IP اختصاص داده شده را به خاطر می آورد و a را ایجاد می کند
اگر به طور تصادفی باعث ایجاد یک آدرس دو بار (که یک
به هر حال، اشکال زدایی خطا بسیار سخت است).

خط بعدی کد،

رابط های Ipv4InterfaceContainer = address.Assign (دستگاه ها)؛

تخصیص آدرس واقعی را انجام می دهد. که در ns-3 ما بین IP ارتباط برقرار می کنیم
آدرس و دستگاهی با استفاده از Ipv4 Interface هدف - شی. همانطور که گاهی اوقات به لیستی از آنها نیاز داریم
دستگاه های شبکه ای که توسط یک کمک کننده برای مراجعات بعدی ایجاد می شوند، گاهی اوقات به لیستی از آنها نیاز داریم
Ipv4 Interface اشیاء. IPv4InterfaceContainer این قابلیت را فراهم می کند.

اکنون ما یک شبکه نقطه به نقطه ساخته ایم که پشته های نصب شده و آدرس های IP را در خود جای داده است
اختصاص داده. آنچه در این مرحله به آن نیاز داریم، اپلیکیشن هایی برای تولید ترافیک هستند.

اپلیکیشن‌ها
یکی دیگر از انتزاعات اصلی سیستم ns-3 این است کاربرداست. در این
اسکریپت ما از دو تخصص اصلی استفاده می کنیم ns-3 کلاس کاربرد نام
UdpEchoServerApplication و UdpEchoClientApplication. درست همانطور که در قبلی خود داشتیم
توضیحات، ما از اشیاء کمکی برای کمک به پیکربندی و مدیریت اشیاء زیربنایی استفاده می کنیم.
در اینجا، ما استفاده می کنیم UdpEchoServerHelper و UdpEchoClientHelper اشیاء برای آسان تر کردن زندگی ما

UdpEchoServerHelper
خطوط کد زیر در اسکریپت مثال ما، first.cc، برای راه اندازی پژواک UDP استفاده می شود
برنامه سرور در یکی از گره هایی که قبلا ایجاد کرده ایم.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (ثانیه (1.0))؛
serverApps.Stop (ثانیه (10.0))؛

اولین خط کد در قطعه بالا، این را اعلام می کند UdpEchoServerHelper. مثل همیشه،
این خود برنامه نیست، یک شی است که برای کمک به ما در ایجاد واقعی استفاده می شود
برنامه های کاربردی. یکی از کنوانسیون های ما قرار دادن است ضروری خواص در کمک کننده
سازنده در این صورت کمک کننده نمی تواند کار مفیدی انجام دهد مگر اینکه فراهم شود
شماره پورتی که مشتری نیز از آن اطلاع دارد. به جای اینکه فقط یکی را انتخاب کنید و امیدوار باشید
همه چیز درست می شود، ما به شماره پورت به عنوان پارامتر سازنده نیاز داریم. در
سازنده، به نوبه خود، به سادگی a SetAttribute با مقدار پاس شده اگر می خواهید، شما
می تواند "پورت" را تنظیم کند صفت به مقدار دیگری بعداً استفاده کنید SetAttribute.

مشابه بسیاری از اشیاء کمکی دیگر، UdpEchoServerHelper شی دارای یک نصب
روش. اجرای این روش است که در واقع باعث ایجاد پژواک زیرین می شود
برنامه سرور باید نمونه سازی شود و به یک گره متصل شود. جالب اینجاست که نصب
روش طول می کشد NodeContainer به عنوان یک پارامتر درست مانند دیگری نصب روش هایی که داریم
مشاهده گردید. این در واقع همان چیزی است که به روش منتقل می شود، حتی اگر اینطور به نظر نمی رسد
این مورد. C++ وجود دارد ضمنی تبدیل در محل کار در اینجا که نتیجه می گیرد
گره ها. دریافت (1) (که یک اشاره گر هوشمند را به یک شی گره برمی گرداند --- Ptr) و از آن استفاده می کند
در یک سازنده برای یک بی نام NodeContainer که سپس به منتقل می شود نصب. اگر شما
همیشه در یافتن یک امضای متد خاص در کد C++ که کامپایل و اجرا می‌شود، دچار مشکل شده‌اید
خوب، به دنبال این نوع تبدیل های ضمنی باشید.

ما اکنون آن را می بینیم echoServer.Install در حال نصب a UdpEchoServerApplication در
گره در فهرست شماره یک یافت شد NodeContainer ما برای مدیریت گره های خود استفاده می کردیم. نصب
ظرفی را برمی گرداند که نشانگرها را به همه برنامه ها نگه می دارد (یکی در این مورد
از زمانی که ما گذشتیم NodeContainer حاوی یک گره) ایجاد شده توسط کمک کننده.

برنامه‌ها برای «شروع» ایجاد ترافیک به زمان نیاز دارند و ممکن است زمان اختیاری داشته باشند
"متوقف کردن". ما هر دو را ارائه می دهیم. این زمان ها با استفاده از کانتینر برنامه روش
آغاز و توقف. این روش ها می گیرند زمان مولفه های. در این مورد از an استفاده می کنیم صریح ++C
دنباله تبدیل برای گرفتن C++ double 1.0 و تبدیل آن به an ns-3 زمان با استفاده از شی
a ثانیه قالب. توجه داشته باشید که قوانین تبدیل ممکن است توسط نویسنده مدل کنترل شود،
و C++ قوانین خاص خود را دارد، بنابراین همیشه نمی توانید فرض کنید که پارامترها با خوشحالی خواهند بود.
برای شما تبدیل شده است. دو خط،

serverApps.Start (ثانیه (1.0))؛
serverApps.Stop (ثانیه (10.0))؛

باعث می شود که برنامه سرور اکو به آغاز (خود را فعال کنید) در یک ثانیه در
شبیه سازی و به توقف (خود را غیرفعال کنید) در ده ثانیه به شبیه سازی. با ایمان به
این واقعیت که ما یک رویداد شبیه سازی (رویداد توقف برنامه) را اعلام کرده ایم
در ده ثانیه اجرا شود، شبیه سازی دوام خواهد آورد at کمترین ده ثانیه.

UdpEchoClientHelper
برنامه کاربردی اکو کلاینت به روشی کاملاً مشابه با روشی تنظیم شده است
سرور زمینه ای وجود دارد UdpEchoClientApplication که توسط یک مدیریت می شود
UdpEchoClientHelper.

UdpEchoClientHelper echoClient (interfaces.GetAddress (1)، 9);
echoClient.SetAttribute ("MaxPackets"، UintegerValue (1));
echoClient.SetAttribute ("Interval"، TimeValue (ثانیه (1.0)));
echoClient.SetAttribute ("PacketSize"، UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (ثانیه (2.0));
clientApps.Stop (ثانیه (10.0));

با این حال، برای اکو کلاینت، باید پنج متفاوت تنظیم کنیم خواص. دو تا اول
خواص در طول ساخت و ساز تنظیم می شوند UdpEchoClientHelper. پارامترها را پاس می کنیم
که برای تنظیم "RemoteAddress" و "RemotePort" (به صورت داخلی برای کمک کننده) استفاده می شوند.
خواص مطابق با کنوانسیون ما لازم است خواص پارامترها در
سازندگان کمکی

به یاد داشته باشید که ما از an استفاده کردیم IPv4InterfaceContainer برای پیگیری آدرس های IP ما
به دستگاه های ما اختصاص داده شده است. رابط صفر در رابط ظرف در حال رفتن به
مطابق با آدرس IP گره صفر در گره ظرف اولین
رابط در رابط ظرف مربوط به آدرس IP اولین گره در است
la گره ظرف بنابراین، در خط اول کد (از بالا)، ما در حال ایجاد کد هستیم
کمک کننده و به آن بگویید بنابراین آدرس راه دور مشتری را به عنوان آدرس IP تنظیم کنید
به گره ای که سرور در آن قرار دارد اختصاص داده می شود. ما هم می گوییم برای ارسال هماهنگ کند
بسته ها به پورت نهم.

"MaxPackets" صفت حداکثر تعداد بسته هایی را که به مشتری اجازه می دهیم به مشتری می گوید
ارسال در حین شبیه سازی "فاصله" صفت به مشتری می گوید که چقدر صبر کند
بین بسته ها و "PacketSize" صفت به مشتری می گوید بسته آن چقدر است
محموله ها باید باشد. با این ترکیب خاص از خواص، ما به آن می گوییم
مشتری برای ارسال یک بسته 1024 بایتی.

همانطور که در مورد سرور اکو، به مشتری اکو می گوییم آغاز و توقف، اما
در اینجا ما کلاینت را یک ثانیه پس از فعال شدن سرور راه اندازی می کنیم (دو ثانیه بعد از آن
شبیه سازی).

شبیه ساز
کاری که در این مرحله باید انجام دهیم اجرای واقعی شبیه سازی است. این کار با استفاده از
عملکرد جهانی شبیه ساز::اجرا کنید.

شبیه ساز::Run ();

وقتی قبلاً متدها را فراخوانی کردیم،

serverApps.Start (ثانیه (1.0))؛
serverApps.Stop (ثانیه (10.0))؛
...
clientApps.Start (ثانیه (2.0));
clientApps.Stop (ثانیه (10.0));

ما در واقع رویدادها را در شبیه ساز در 1.0 ثانیه، 2.0 ثانیه و دو رویداد برنامه ریزی کردیم
در 10.0 ثانیه چه زمانی شبیه ساز::اجرا کنید نامیده می شود، سیستم شروع به جستجو از طریق
لیست رویدادهای برنامه ریزی شده و اجرای آنها ابتدا رویداد را در 1.0 ثانیه اجرا می کند،
که برنامه سرور اکو را فعال می کند (این رویداد ممکن است به نوبه خود برنامه ریزی بسیاری را انجام دهد
رویدادهای دیگر). سپس رویداد برنامه ریزی شده برای t=2.0 ثانیه را اجرا می کند که شروع می شود
برنامه مشتری اکو باز هم، این رویداد ممکن است رویدادهای بیشتری را برنامه ریزی کند. آغاز
اجرای رویداد در برنامه مشتری اکو مرحله انتقال داده را آغاز خواهد کرد
شبیه سازی با ارسال یک بسته به سرور.

عمل ارسال بسته به سرور باعث ایجاد زنجیره ای از رویدادها خواهد شد
به طور خودکار در پشت صحنه برنامه ریزی می شود و مکانیک های آن را انجام می دهد
پژواک بسته با توجه به پارامترهای زمانی مختلفی که در اسکریپت تنظیم کرده ایم.

در نهایت، از آنجایی که ما فقط یک بسته ارسال می کنیم (به یاد بیاورید MaxPackets صفت تنظیم شد
یک)، زنجیره رویدادهایی که توسط آن درخواست پژواک مشتری منفرد ایجاد می‌شوند، کاهش می‌یابند و
شبیه سازی بیکار خواهد ماند. هنگامی که این اتفاق می افتد، رویدادهای باقی مانده خواهد بود توقف
رویدادها برای سرور و مشتری وقتی این رویدادها اجرا می شوند، وجود ندارند
رویدادهای بیشتر برای پردازش و شبیه ساز::اجرا کنید برمی گرداند. سپس شبیه سازی کامل می شود.

تنها چیزی که باقی می ماند تمیز کردن است. این کار با فراخوانی تابع global انجام می شود
شبیه ساز:: نابود کردن. به عنوان کمک کننده (یا سطح پایین ns-3 کد) اجرا شد، آنها
آن را طوری تنظیم کرد که قلاب هایی در شبیه ساز قرار داده شد تا همه اشیا را از بین ببرد
که ایجاد شدند. شما مجبور نبودید خودتان هیچ یک از این اشیاء را پیگیری کنید ---
تنها کاری که باید می کردی این بود که زنگ بزنی شبیه ساز:: نابود کردن و خروج در ns-3 سیستم مراقبت کرد
بخش سخت برای شما خطوط باقی مانده از اولین ما ns-3 اسکریپت first.cc، فقط انجام بده
که:

شبیه ساز::Destroy ();
0 بازگشت؛
}

چه زمانی la شبیه ساز اراده متوقف کردن؟
ns-3 یک شبیه ساز رویداد گسسته (DE) است. در چنین شبیه سازی، هر رویداد مرتبط است
با زمان اجرای آن، و شبیه سازی با اجرای رویدادها در زمانی پیش می رود
ترتیب زمان شبیه سازی رویدادها ممکن است باعث برنامه ریزی رویدادهای آینده شوند (به عنوان مثال، الف
تایمر ممکن است خود را دوباره برنامه ریزی کند تا در بازه بعدی منقضی شود).

رویدادهای اولیه معمولاً توسط هر شی ایجاد می شوند، به عنوان مثال، IPv6 روتر را برنامه ریزی می کند
تبلیغات، درخواست های همسایه، و غیره، یک برنامه برنامه اولین بسته را برنامه ریزی می کند
ارسال رویداد و غیره

هنگامی که یک رویداد پردازش می شود، ممکن است صفر، یک یا چند رویداد ایجاد کند. به عنوان شبیه سازی
اجرا می شود، رویدادها مصرف می شوند، اما رویدادهای بیشتری ممکن است (یا ممکن است) تولید شوند. در
زمانی که هیچ رویداد دیگری در صف رویداد وجود نداشته باشد، شبیه سازی به طور خودکار متوقف می شود
یک رویداد توقف ویژه یافت می شود. رویداد Stop از طریق ایجاد می شود شبیه ساز::توقف
(StopTime)؛ تابع.

یک مورد معمولی وجود دارد که در آن شبیه ساز::توقف کاملا ضروری است که متوقف شود
شبیه سازی: زمانی که یک رویداد خودپایدار وجود دارد. رویدادهای خودپایدار (یا تکرار شونده).
رویدادهایی هستند که همیشه خود را تغییر می دهند. در نتیجه، آنها همیشه رویداد را نگه می دارند
صف غیر خالی

پروتکل ها و ماژول های بسیاری حاوی رویدادهای تکرار شونده وجود دارد، به عنوان مثال:

· FlowMonitor - بررسی دوره ای برای بسته های گم شده

· RIPng - پخش دوره ای جداول مسیریابی به روز رسانی

· و غیره.

در این موارد، شبیه ساز::توقف برای توقف آرام شبیه سازی ضروری است. که در
علاوه بر این، زمانی که ns-3 در حالت شبیه سازی است Realtime Simulator برای نگهداری استفاده می شود
ساعت شبیه سازی با ساعت ماشین تراز شده و شبیه ساز::توقف لازم است متوقف شود
فرآیند.

بسیاری از برنامه های شبیه سازی در این آموزش به صراحت تماس نمی گیرند شبیه ساز::توقف,
از آنجایی که صف رویداد به طور خودکار از رویدادها تمام می شود. با این حال، این برنامه ها خواهد بود
همچنین یک تماس را بپذیرید شبیه ساز::توقف. به عنوان مثال، عبارت اضافی زیر در
برنامه نمونه اول توقف صریح را در 11 ثانیه برنامه ریزی می کند:

+ شبیه ساز::توقف (ثانیه (11.0))؛
شبیه ساز::Run ();
شبیه ساز::Destroy ();
0 بازگشت؛
}

موارد فوق در واقع رفتار این برنامه را تغییر نمی دهد، زیرا این خاص است
شبیه سازی به طور طبیعی پس از 10 ثانیه به پایان می رسد. اما اگر بخواهید زمان توقف را تغییر دهید
عبارت فوق از 11 ثانیه تا 1 ثانیه، متوجه خواهید شد که شبیه سازی
قبل از اینکه هر خروجی روی صفحه چاپ شود متوقف می شود (زیرا خروجی در حدود زمان 2 رخ می دهد
ثانیه از زمان شبیه سازی).

مهم است که تماس بگیرید شبیه ساز::توقف قبل از فراخوانی شبیه ساز::اجرا کنید؛ در غیر این صورت،
شبیه ساز::اجرا کنید ممکن است هرگز کنترل را به برنامه اصلی برای اجرای توقف برنگرداند!

بنا شما خط
ما ساختن اسکریپت های ساده شما را بی اهمیت جلوه داده ایم. تنها کاری که باید انجام دهید این است که خود را رها کنید
اسکریپت را در دایرکتوری اسکرچ بنویسید و اگر Waf را اجرا کنید به طور خودکار ساخته می شود.
بیایید آن را امتحان کنیم. کپی 🀄 examples/tutorial/first.cc به خراش دایرکتوری پس از تغییر
به دایرکتوری سطح بالا برگردید.

سی دی/ ..
$ cp examples/tutorial/first.cc scratch/myfirst.cc

اکنون اولین نمونه اسکریپت خود را با استفاده از waf بسازید:

$./waf

شما باید پیام هایی را ببینید که گزارش می دهند که شما اولین من نمونه با موفقیت ساخته شد.

Waf: ورود به فهرست "/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: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (2.357s)

اکنون می توانید مثال را اجرا کنید (توجه داشته باشید که اگر برنامه خود را در دایرکتوری اسکرچ بسازید
باید آن را از دایرکتوری اولیه اجرا کنید):

$ ./waf --run scratch/myfirst

باید مقداری خروجی ببینید:

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.418s)
1024 بایت به 10.1.1.2 ارسال شد
دریافت 1024 بایت از 10.1.1.1
دریافت 1024 بایت از 10.1.1.2

در اینجا مشاهده می کنید که سیستم ساخت بررسی می کند تا مطمئن شود که فایل ساخته شده است و
سپس آن را اجرا می کند. می بینید که مولفه ورود به سیستم در مشتری echo نشان می دهد که ارسال شده است
یک بسته 1024 بایتی به سرور اکو در 10.1.1.2. شما همچنین مؤلفه ورود به سیستم را مشاهده می کنید
در سرور اکو بگویید که 1024 بایت را از 10.1.1.1 دریافت کرده است. سرور اکو
بدون صدا بسته را بازتاب می دهد و گزارش مشتری echo را مشاهده می کنید که بسته خود را دریافت کرده است.
برگشت از سرور

Ns-3 منبع رمز
اکنون که از برخی از آنها استفاده کرده اید ns-3 ممکن است بخواهید به برخی از آنها نگاهی بیندازید
کد منبعی که آن عملکرد را پیاده سازی می کند. آخرین کد را می توان در مرور کرد
وب سرور ما در لینک زیر: http://code.nsnam.org/ns-3-dev. آنجا، خواهید دید
صفحه خلاصه Mercurial برای ما ns-3 درخت توسعه

در بالای صفحه، تعدادی لینک مشاهده خواهید کرد،

خلاصه | کوتاه | تغییرات | نمودار | برچسب ها | فایل ها

پیش بروید و آن را انتخاب کنید فایل ها ارتباط دادن. این همان چیزی است که در سطح بالای اکثر ما وجود دارد
مخازن نگاه خواهد کرد:

drwxr-xr-x [بالا]
drwxr-xr-x فایل‌های پایتون را پیوند می‌دهد
فایل های سند drwxr-xr-x
فایل های نمونه drwxr-xr-x
فایل های drwxr-xr-x ns3
فایل های اسکرچ drwxr-xr-x
فایل های drwxr-xr-x src
drwxr-xr-x فایل های کاربردی
-rw-r--r-- 2009-07-01 12:47 +0200 560 فایل hgignore | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 1886 فایل hgtags | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 1276 فایل AUTHORS | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html فایل | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 17987 فایل LICENSE | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 3742 فایل README | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 16171 فایل RELEASE_NOTES | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSION فایل | تجدید نظر | حاشیه نویسی کنید
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 فایل waf | تجدید نظر | حاشیه نویسی کنید
-rwxr-xr-x 2009-07-01 12:47 +0200 28 فایل waf.bat | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 35395 فایل wscript | تجدید نظر | حاشیه نویسی کنید
-rw-r--r-- 2009-07-01 12:47 +0200 7673 فایل wutils.py | تجدید نظر | حاشیه نویسی کنید

اسکریپت های نمونه ما در مثال ها فهرست راهنما. اگر روی مثال ها شما خواهید دید
لیستی از زیر شاخه ها یکی از فایل های موجود در آموزش زیر شاخه است first.cc. اگر شما
با کلیک بر روی first.cc کدی را که به تازگی از آن عبور کرده اید پیدا خواهید کرد.

کد منبع عمدتا در " فهرست راهنما. شما می توانید کد منبع را از طریق مشاهده کنید
با کلیک بر روی نام دایرکتوری یا با کلیک بر روی فایل ها لینک سمت راست
نام دایرکتوری اگر روی آن کلیک کنید " دایرکتوری، شما به فهرستی هدایت خواهید شد
la " دایرکتوری های فرعی اگر بر روی آن کلیک کنید هسته فهرست فرعی را خواهید دید
فایل ها. اولین فایلی که پیدا خواهید کرد (تا این لحظه) این است سقط کردن.h. اگر روی آن کلیک کنید
سقط کردن.h لینک، شما به فایل منبع ارسال می شوید سقط کردن.h که حاوی ماکروهای مفید است
برای خروج از اسکریپت در صورت شناسایی شرایط غیرعادی.

کد منبع برای کمک‌هایی که در این فصل استفاده کرده‌ایم را می‌توان در بخش پیدا کرد
src/applications/helper فهرست راهنما. برای دریافت، به راحتی در درخت دایرکتوری جستجو کنید
احساسی نسبت به آنچه وجود دارد و سبک آن ns-3 برنامه ها.

پیچاندن


با استفاده از la ورود به سیستم ماژول ها
قبلاً نگاهی کوتاه به آن انداخته ایم ns-3 ماژول ورود به سیستم در حالی که بیش از
first.cc اسکریپت اکنون نگاهی دقیق‌تر می‌اندازیم و می‌بینیم که چه نوع موارد استفاده است
زیرسیستم ورود به سیستم برای پوشش طراحی شده است.

ورود به سیستم بررسی اجمالی
بسیاری از سیستم های بزرگ از نوعی تسهیلات ثبت پیام پشتیبانی می کنند و ns-3 نیست
استثنا. در برخی موارد، فقط پیام های خطا به "کنسول اپراتور" (که
به طور معمول است استدرر در سیستم های مبتنی بر یونیکس). در سیستم های دیگر، پیام های هشدار ممکن است وجود داشته باشد
خروجی و همچنین پیام های اطلاعاتی دقیق تر. در برخی موارد، امکانات چوب بری
برای خروجی پیام های اشکال زدایی استفاده می شود که می تواند به سرعت خروجی را به تاری تبدیل کند.

ns-3 بر این عقیده است که همه این سطوح پرحرفی مفید هستند و ما الف
رویکرد چند سطحی انتخابی برای ثبت پیام. ورود به سیستم را می توان به طور کامل غیرفعال کرد،
فعال بر اساس جزء به جزء، یا فعال در سطح جهانی. و قابل انتخاب را فراهم می کند
سطوح پرحرفی در ns-3 ماژول ورود به سیستم ساده و نسبتا آسان برای استفاده فراهم می کند
راهی برای بدست آوردن اطلاعات مفید از شبیه سازی

شما باید درک کنید که ما یک مکانیسم با هدف کلی --- ردیابی --- را ارائه می دهیم
داده هایی را از مدل های خود دریافت کنید که باید برای خروجی شبیه سازی ترجیح داده شوند (به
بخش آموزش استفاده از سیستم ردیابی برای جزئیات بیشتر در مورد سیستم ردیابی ما).
ورود به سیستم باید برای اشکال زدایی اطلاعات، هشدارها، پیام های خطا یا هر موردی ترجیح داده شود
زمانی که می خواهید به راحتی پیامی سریع از اسکریپت ها یا مدل های خود دریافت کنید.

در حال حاضر هفت سطح از پیام های گزارش افزایش پرحرفی تعریف شده است
سیستم.

· LOG_ERROR --- ورود پیام های خطا (ماکرو مرتبط: NS_LOG_ERROR).

· LOG_WARN --- ورود پیام های هشدار دهنده (ماکرو مرتبط: NS_LOG_WARN).

· LOG_DEBUG --- پیام های اشکال زدایی نسبتاً نادر و موقتی را ثبت کنید (ماکرو مرتبط:
NS_LOG_DEBUG)؛

· LOG_INFO --- گزارش پیام های اطلاعاتی در مورد پیشرفت برنامه (ماکرو مرتبط:
NS_LOG_INFO)؛

· LOG_FUNCTION --- ثبت پیامی که هر تابع نامیده شده را توصیف می کند (دو ماکرو مرتبط:
NS_LOG_FUNCTION، برای توابع عضو، و NS_LOG_FUNCTION_NOARGS، برای استاتیک استفاده می شود
کارکرد)؛

· LOG_LOGIC - گزارش پیام هایی که جریان منطقی را در یک تابع توصیف می کنند (ماکرو مرتبط:
NS_LOG_LOGIC)؛

· LOG_ALL --- همه موارد ذکر شده در بالا را ثبت کنید (بدون ماکرو مرتبط).

برای هر LOG_TYPE نیز LOG_LEVEL_TYPE وجود دارد که در صورت استفاده، ثبت همه موارد را فعال می کند
سطوح بالاتر از آن علاوه بر سطح آن. (در نتیجه، LOG_ERROR و
LOG_LEVEL_ERROR و همچنین LOG_ALL و LOG_LEVEL_ALL از نظر عملکردی معادل هستند.) برای
به عنوان مثال، فعال کردن LOG_INFO فقط پیام های ارائه شده توسط ماکرو NS_LOG_INFO را فعال می کند، در حالی که
فعال کردن LOG_LEVEL_INFO پیام های ارائه شده توسط NS_LOG_DEBUG، NS_LOG_WARN را نیز فعال می کند
و ماکروهای NS_LOG_ERROR.

ما همچنین یک ماکرو ثبت نام بدون قید و شرط ارائه می کنیم که همیشه نمایش داده می شود، صرف نظر از آن
سطوح ورود به سیستم یا انتخاب جزء.

· NS_LOG_UNCOND - پیام مرتبط را بدون قید و شرط ثبت کنید (بدون سطح گزارش مرتبط).

هر سطح را می توان به تنهایی یا به صورت تجمعی درخواست کرد. و ورود به سیستم را می توان با استفاده از a راه اندازی کرد
متغیر محیط پوسته (NS_LOG) یا با ثبت فراخوانی عملکرد سیستم. همانطور که مشاهده شد
قبلاً در آموزش، سیستم لاگ دارای مستندات Doxygen است و اکنون یک خواهد بود
اگر این کار را نکرده اید، زمان خوبی برای مطالعه مستندات Logging Module است.

اکنون که مستندات را با جزئیات کامل خواندید، اجازه دهید از برخی از آن دانش استفاده کنیم
برای به دست آوردن اطلاعات جالب از scratch/myfirst.cc اسکریپت نمونه ای که دارید
قبلا ساخته شده است.

را قادر می سازد ورود به سیستم
بیایید از متغیر محیطی NS_LOG برای روشن کردن برخی گزارش‌های دیگر استفاده کنیم، اما ابتدا فقط به این کار
یاتاقان ما را دریافت کنید، ادامه دهید و آخرین اسکریپت را همانطور که قبلا انجام دادید اجرا کنید،

$ ./waf --run scratch/myfirst

شما باید خروجی آشنای اول را ببینید ns-3 برنامه نمونه

$ Waf: وارد کردن دایرکتوری «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.413s)
1024 بایت به 10.1.1.2 ارسال شد
دریافت 1024 بایت از 10.1.1.1
دریافت 1024 بایت از 10.1.1.2

به نظر می رسد که پیام های "ارسال شده" و "دریافت" که در بالا مشاهده می کنید در واقع در حال ثبت هستند
پیام هایی از UdpEchoClientApplication و UdpEchoServerApplication. می توانیم بپرسیم
برنامه مشتری، برای مثال، برای چاپ اطلاعات بیشتر با تنظیم سطح گزارش آن
از طریق متغیر محیطی NS_LOG.

از اینجا به بعد می‌خواهم فرض کنم که شما از یک پوسته sh مانند استفاده می‌کنید
نحو "VARIABLE=value". اگر از پوسته ای شبیه csh استفاده می کنید، مجبور خواهید بود
مثال های من را به نحو "setenv VARIABLE value" مورد نیاز آن پوسته ها تبدیل کنید.

در حال حاضر، برنامه UDP echo client به خط کد زیر پاسخ می دهد
scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication"، LOG_LEVEL_INFO);

این خط کد را فعال می کند LOG_LEVEL_INFO سطح ورود به سیستم وقتی از چوب درخت عبور می کنیم
پرچم سطح، ما در واقع سطح داده شده و تمام سطوح پایین تر را فعال می کنیم. در این مورد،
را فعال کرده ایم NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN و NS_LOG_ERROR. می توانیم افزایش دهیم
سطح ورود به سیستم و دریافت اطلاعات بیشتر بدون تغییر اسکریپت و کامپایل مجدد توسط
متغیر محیطی NS_LOG را به صورت زیر تنظیم کنید:

$ export NS_LOG=UdpEchoClientApplication=level_all

این متغیر محیط پوسته را تنظیم می کند NS_LOG به رشته،

UdpEchoClientApplication=level_all

سمت چپ تخصیص نام مؤلفه ورود به سیستم است که می خواهیم تنظیم کنیم،
و سمت راست پرچمی است که می خواهیم استفاده کنیم. در این مورد، ما می خواهیم روشن کنیم
تمام سطوح اشکال زدایی برنامه اگر اسکریپت را با مجموعه NS_LOG اجرا کنید
از این طریق، ns-3 سیستم ورود به سیستم تغییرات را دریافت می کند و باید موارد زیر را مشاهده کنید
خروجی:

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
1024 بایت به 10.1.1.2 ارسال شد
دریافت 1024 بایت از 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
دریافت 1024 بایت از 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

اطلاعات رفع اشکال اضافی ارائه شده توسط برنامه از NS_LOG_FUNCTION است
مرحله. این نشان می دهد هر بار که یک تابع در برنامه در طول اسکریپت فراخوانی می شود
اجرا. به طور کلی، استفاده از (حداقل) NS_LOG_FUNCTION(this) در توابع عضو
ارجح. از NS_LOG_FUNCTION_NOARGS() فقط در توابع استاتیک استفاده کنید. اما توجه داشته باشید که
هیچ الزامی در ns-3 سیستمی که مدل ها باید هر خاصی را پشتیبانی کنند
قابلیت ورود به سیستم تصمیم گیری در مورد اینکه چه مقدار اطلاعات ثبت شده است به عهده شماست
توسعه دهنده مدل فردی در مورد برنامه های اکو، مقدار زیادی گزارش
خروجی در دسترس است.

اکنون می توانید گزارشی از فراخوانی های عملکردی که با برنامه انجام شده است را مشاهده کنید. اگر شما
با دقت نگاه کنید، متوجه یک دو نقطه بین رشته خواهید شد UdpEchoClientApplication
و نام روشی که ممکن است انتظار داشته باشید که یک عملگر دامنه C++ (::). این هست
عمدی - قصدی.

نام در واقع یک نام کلاس نیست، یک نام مؤلفه ورود به سیستم است. هنگامی که وجود دارد
مکاتبات یک به یک بین یک فایل منبع و یک کلاس، این به طور کلی خواهد بود
نام کلاس اما باید بدانید که در واقع نام کلاس نیست و یک وجود دارد
تک کولون به جای دو نقطه وجود دارد تا به روشی نسبتاً ظریف به شما یادآوری کند
به طور مفهومی نام مؤلفه ورود به سیستم را از نام کلاس جدا کنید.

به نظر می رسد که در برخی موارد، تعیین اینکه کدام روش واقعاً دشوار است
یک پیام گزارش ایجاد می کند. اگر به متن بالا نگاه کنید، ممکن است تعجب کنید که رشته کجاست
"دریافتی 1024 بایت از جانب 10.1.1.2شما می توانید این مشکل را با OR حل کنید
prefix_func سطح به NS_LOG متغیر محیطی. سعی کنید موارد زیر را انجام دهید،

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

توجه داشته باشید که از نوار عمودی که برای نشان دادن یک OR استفاده می کنیم، نقل قول ها ضروری هستند
عملیات همچنین یک اتصال دهنده لوله یونیکس است.

حال، اگر اسکریپت را اجرا کنید، خواهید دید که سیستم ورود به سیستم مطمئن می شود که هر
پیامی از کامپوننت log داده شده با نام مؤلفه پیشوند است.

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): 1024 بایت به 10.1.1.2 ارسال شد
دریافت 1024 بایت از 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): دریافت 1024 بایت از 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

اکنون می‌توانید تمام پیام‌های دریافتی از برنامه UDP echo client را ببینید
به عنوان چنین شناسایی شده است. اکنون پیام "دریافت 1024 بایت از 10.1.1.2" به وضوح مشاهده می شود.
شناسایی شده است که از برنامه مشتری اکو می آید. پیام باقی مانده باید باشد
از برنامه UDP Echo Server. با وارد کردن a می توانیم آن کامپوننت را فعال کنیم
کولون لیستی از اجزای متغیر محیطی NS_LOG را جدا کرده است.

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

اخطار: پس از اتمام باید خط جدید را حذف کنید : در متن مثال بالا که
فقط برای اهداف قالب بندی سند وجود دارد.

اکنون، اگر اسکریپت را اجرا کنید، تمام پیام‌های گزارش هر دو echo client را خواهید دید
و برنامه های کاربردی سرور ممکن است ببینید که این می تواند در اشکال زدایی مشکلات بسیار مفید باشد.

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): 1024 بایت به 10.1.1.2 ارسال شد
UdpEchoServerApplication:HandleRead(): دریافت 1024 بایت از 10.1.1.1
UdpEchoServerApplication:HandleRead(): بسته پژواک
UdpEchoClientApplication:HandleRead(0x624920، 0x625160)
UdpEchoClientApplication:HandleRead(): دریافت 1024 بایت از 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

همچنین گاهی اوقات مفید است که بتوانیم زمان شبیه سازی را که در آن یک پیام گزارش ثبت می شود، ببینیم
تولید می شود. می توانید این کار را با OR کردن در بیت prefix_time انجام دهید.

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

باز هم باید خط جدید بالا را حذف کنید. اگر اکنون اسکریپت را اجرا می کنید، باید
خروجی زیر را ببینید:

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.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(): 1024 بایت به 10.1.1.2 ارسال شد
2.00369s UdpEchoServerApplication:HandleRead(): دریافت 1024 بایت از 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): بسته پژواک
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): دریافت 1024 بایت از 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

می توانید ببینید که سازنده UdpEchoServer در زمان شبیه سازی فراخوانی شده است
0 ثانیه این در واقع قبل از شروع شبیه سازی اتفاق می افتد، اما زمان آن است
به صورت صفر ثانیه نمایش داده می شود. همین امر در مورد پیام سازنده UdpEchoClient نیز صادق است.

به یاد بیاورید که خراش / first.cc اسکریپت برنامه سرور اکو را در یک ثانیه شروع کرد
به شبیه سازی اکنون می توانید ببینید که StartApplication روش سرور به این صورت است
در واقع در یک ثانیه تماس گرفت. شما همچنین می توانید ببینید که برنامه مشتری اکو است
همانطور که در اسکریپت درخواست کردیم در زمان شبیه سازی دو ثانیه شروع شد.

اکنون می توانید پیشرفت شبیه سازی را از قسمت زیر دنبال کنید ScheduleTransmit تماس بگیرید در
مشتری که تماس می گیرد ارسال به HandleRead پاسخ به تماس در برنامه سرور اکو. توجه داشته باشید
که زمان سپری شده برای ارسال بسته از طریق پیوند نقطه به نقطه 3.69 است.
میلی ثانیه سرور اکو را مشاهده می کنید که پیامی را ثبت می کند که به شما می گوید بازتاب داده است
بسته و سپس، پس از یک تاخیر دیگر کانال، می بینید که مشتری echo دریافت می کند
بسته پژواک در آن HandleRead روش.

چیزهای زیادی در این شبیه سازی در زیر پوشش ها اتفاق می افتد که شما نیستید
دیدن نیز. با روشن کردن همه موارد، می توانید به راحتی کل فرآیند را دنبال کنید
ثبت اجزای سیستم سعی کنید تنظیم کنید NS_LOG متغیر به شکل زیر

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

ستاره بالا علامت عام مؤلفه ورود به سیستم است. این همه را روشن می کند
ورود به تمام اجزای مورد استفاده در شبیه سازی. من خروجی را بازتولید نمی کنم
در اینجا (تا لحظه نگارش این مقاله، 1265 خط خروجی برای اکو یک بسته تولید می کند) اما
شما می توانید این اطلاعات را به یک فایل هدایت کنید و با موارد دلخواه خود به آن نگاه کنید
ویرایشگر اگر دوست دارید،

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

من شخصاً از این نسخه بسیار پرمخاطب از ورود به سیستم زمانی که با a ارائه می‌شوم استفاده می‌کنم
مشکل است و من هیچ ایده ای ندارم که کارها کجا پیش می رود. من می توانم پیشرفت را دنبال کنم
بدون نیاز به تعیین نقاط شکست و عبور از کد در یک اشکال‌زدا، به راحتی کد کنید.
من فقط می توانم خروجی را در ویرایشگر مورد علاقه خود ویرایش کنم و چیزهایی را که انتظار دارم جستجو کنم،
و شاهد اتفاقاتی باشم که انتظارش را ندارم. وقتی یک ایده کلی در مورد آنچه هست دارم
اشتباه می شود، برای بررسی دقیق مشکل به یک دیباگر منتقل می شوم.
این نوع خروجی می تواند به ویژه زمانی مفید باشد که اسکریپت شما کاری را به طور کامل انجام دهد
غیر منتظره. اگر از یک دیباگر استفاده می کنید، ممکن است یک سفر غیرمنتظره را از دست بدهید
به طور کامل. ثبت کردن سفر باعث می شود که به سرعت قابل مشاهده باشد.

اضافه کردن ورود به سیستم به خود را رمز
می توانید با برقراری تماس با مؤلفه گزارش از طریق، گزارش جدیدی را به شبیه سازی های خود اضافه کنید
چندین ماکرو بیایید این کار را در myfirst.cc اسکریپت ما در خراش دایرکتوری.

به یاد بیاورید که ما یک جزء لاگ را در آن اسکریپت تعریف کرده ایم:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample")؛

اکنون می‌دانید که می‌توانید همه گزارش‌های مربوط به این مؤلفه را با تنظیم کردن فعال کنید
NS_LOG متغیر محیطی در سطوح مختلف بیایید جلو برویم و مقداری ورود به سیستم را اضافه کنیم
فیلمنامه ماکرو مورد استفاده برای افزودن پیام گزارش سطح اطلاعاتی است NS_LOG_INFO. برو
جلوتر و یکی اضافه کنید (درست قبل از شروع ایجاد گره ها) که به شما می گوید که اسکریپت
"ایجاد توپولوژی" است. این کار مانند این قطعه کد انجام می شود،

باز کن scratch/myfirst.cc در ویرایشگر مورد علاقه خود و اضافه کردن خط،

NS_LOG_INFO ("ایجاد توپولوژی")؛

درست قبل از خطوط،

گره های NodeContainer.
nodes.Create (2);

اکنون اسکریپت را با استفاده از waf بسازید و آن را پاک کنید NS_LOG متغیر برای خاموش کردن تورنت
گزارشی که قبلاً فعال کرده بودیم:

$./waf
صادرات $ NS_LOG=

حالا اگر اسکریپت را اجرا کنید،

$ ./waf --run scratch/myfirst

شما خواهد شد نه پیام جدید خود را از مولفه گزارش مربوط به آن ببینید
(FirstScriptExample) فعال نشده است. برای دیدن پیام خود باید
را فعال کنید FirstScriptExample جزء ورود به سیستم با سطح بزرگتر یا مساوی
NS_LOG_INFO. اگر فقط می خواهید این سطح خاص از ورود به سیستم را ببینید، می توانید آن را فعال کنید
توسط،

$ export NS_LOG=FirstScriptExample=اطلاعات

اگر اکنون اسکریپت را اجرا کنید، پیام گزارش جدید "ایجاد توپولوژی" خود را خواهید دید،

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.404s)
ایجاد توپولوژی
1024 بایت به 10.1.1.2 ارسال شد
دریافت 1024 بایت از 10.1.1.1
دریافت 1024 بایت از 10.1.1.2

با استفاده از فرمان لاین استدلال
برجسته به طور پیش فرض خواص
راه دیگری که می توانید نحوه تغییر را تغییر دهید ns-3 اسکریپت ها بدون ویرایش رفتار می کنند و ساخت از طریق است
فرمان خط استدلال ما مکانیزمی برای تجزیه آرگومان های خط فرمان و
به طور خودکار متغیرهای محلی و سراسری را بر اساس آن آرگومان ها تنظیم می کند.

اولین قدم در استفاده از سیستم آرگومان خط فرمان، اعلام خط فرمان است
تجزیه کننده این کار به سادگی (در برنامه اصلی شما) مانند کد زیر انجام می شود.

INT
اصلی (int argc، char *argv[])
{
...

CommandLine cmd;
cmd.Parse (argc, argv);

...
}

این قطعه ساده دو خطی در واقع به خودی خود بسیار مفید است. در را به روی باز می کند
ns-3 متغیر جهانی و صفت سیستم های. ادامه دهید و آن دو خط کد را به آن اضافه کنید
la scratch/myfirst.cc اسکریپت در ابتدای اصلی. ادامه دهید و اسکریپت را بسازید و اجرا کنید
آن را، اما از اسکریپت به روش زیر کمک بخواهید،

$ ./waf -- "scratch/myfirst --PrintHelp" را اجرا کنید

با این کار از Waf می‌خواهد تا اجرا شود scratch/myfirst اسکریپت و آرگومان خط فرمان را پاس کنید
--PrintHelp به فیلمنامه برای مشخص کردن اینکه کدام برنامه کدام را دریافت می کند، به نقل قول ها نیاز است
بحث و جدل. تجزیه کننده خط فرمان اکنون می بیند --PrintHelp استدلال و پاسخ با،

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.413s)
پروتکل TcpL4:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: این پیام راهنما را چاپ کنید.
--PrintGroups: لیست گروه ها را چاپ کنید.
--PrintTypeIds: چاپ همه TypeIds.
--PrintGroup=[group]: چاپ تمام TypeId های گروه.
--PrintAttributes=[typeid]: چاپ تمام ویژگی های typeid.
--PrintGlobals: فهرست جهانی ها را چاپ کنید.

بیایید بر روی آن تمرکز کنیم --PrintAttributes گزینه. ما قبلاً به آن اشاره کرده ایم ns-3 صفت
سیستم هنگام راه رفتن از طریق first.cc اسکریپت ما به خطوط زیر نگاه کردیم
کد ،

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("تاخیر"، StringValue ("2 میلی ثانیه"));

و اشاره کرد که نرخ داده در واقع یک بود صفت از PointToPointNetDevice. اجازه دهید
از تجزیه کننده آرگومان خط فرمان استفاده کنید تا نگاهی به آن بیندازید خواص از
PointToPointNetDevice. فهرست راهنما می گوید که ما باید a TypeId. این
مربوط به نام کلاس کلاسی است که خواص تعلق داشتن. در این مورد
خواهد بود ns3::PointToPointNetDevice. بیایید جلو برویم و تایپ کنیم،

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

سیستم تمام موارد را چاپ خواهد کرد خواص از این نوع دستگاه شبکه بین
خواص خواهید دید که لیست شده است،

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
نرخ پیش‌فرض داده برای پیوندهای نقطه به نقطه

این مقدار پیش‌فرض است که وقتی a استفاده می‌شود PointToPointNetDevice در ایجاد شده است
سیستم. ما این پیش فرض را با صفت تنظیم در PointToPointHelper
در بالا. بیایید از مقادیر پیش فرض برای دستگاه ها و کانال های نقطه به نقطه استفاده کنیم
حذف کردن SetDeviceAttribute تماس بگیرید و SetChannelAttribute تماس از myfirst.cc
ما در دایرکتوری scratch داریم.

اسکریپت شما اکنون باید فقط آن را اعلام کند PointToPointHelper و هیچ کاری انجام نده تنظیم عملیات
مانند مثال زیر،

...

گره های NodeContainer.
nodes.Create (2);

PointToPointHelper pointToPoint;

دستگاه های NetDeviceContainer؛
دستگاه ها = pointToPoint.Install (گره ها);

...

ادامه دهید و اسکریپت جدید را با Waf بسازید (./ واف) و اجازه دهید به عقب برگردیم و برخی را فعال کنیم
از برنامه UDP Echo Server وارد شوید و پیشوند زمان را روشن کنید.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

اگر اسکریپت را اجرا کنید، اکنون باید خروجی زیر را ببینید:

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
1024 بایت به 10.1.1.2 ارسال شد
2.25732s دریافت 1024 بایت از 10.1.1.1
2.25732s بسته پژواک
دریافت 1024 بایت از 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

به یاد بیاورید که آخرین باری که به زمان شبیه سازی بسته نگاه کردیم
دریافت شده توسط سرور اکو، در 2.00369 ثانیه بود.

2.00369s UdpEchoServerApplication:HandleRead(): دریافت 1024 بایت از 10.1.1.1

اکنون بسته را در 2.25732 ثانیه دریافت می کند. این به این دلیل است که ما فقط آن را رها کردیم
نرخ داده از PointToPointNetDevice به طور پیش فرض 32768 بیت در ثانیه از
پنج مگابیت در ثانیه

اگر قرار بود جدید ارائه کنیم نرخ داده با استفاده از خط فرمان، می‌توانیم شبیه‌سازی خود را سرعت دهیم
دوباره بالا ما این کار را به روش زیر انجام می دهیم، با توجه به فرمول ذکر شده توسط کمک
آیتم:

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

این مقدار پیش فرض را تنظیم می کند نرخ داده صفت به پنج مگابیت در هر
دومین. آیا از نتیجه شگفت زده شده اید؟ معلوم می شود که برای به دست آوردن اصل
رفتار اسکریپت به عقب، ما باید تاخیر سرعت نور کانال را تنظیم کنیم
همچنین. می‌توانیم از سیستم خط فرمان بخواهیم که آن را چاپ کند خواص از کانال
درست مانند کاری که برای دستگاه نت انجام دادیم:

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

ما کشف می کنیم تاخیر انداختن صفت کانال به صورت زیر تنظیم شده است:

--ns3::PointToPointChannel::Delay=[0ns]:
تاخیر ارسال از طریق کانال

سپس می توانیم هر دوی این مقادیر پیش فرض را از طریق سیستم خط فرمان تنظیم کنیم،

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

در این صورت، زمانی را که به صراحت تنظیم کردیم، بازیابی می کنیم نرخ داده و تاخیر انداختن
در فیلمنامه:

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
1024 بایت به 10.1.1.2 ارسال شد
2.00369s دریافت 1024 بایت از 10.1.1.1
2.00369s بسته پژواک
دریافت 1024 بایت از 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

توجه داشته باشید که بسته مجدداً در 2.00369 ثانیه توسط سرور دریافت می شود. ما توانستیم
در واقع تنظیم هر یک از خواص به این ترتیب در فیلمنامه استفاده شده است. به طور خاص ما می توانستیم
مجموعه ای از UdpEchoClient صفت MaxPackets به ارزش دیگری غیر از یک

چگونه در مورد آن اقدام می کنید؟ آن را امتحان کنید. به یاد داشته باشید که باید در مورد مکان نظر بدهید
پیش فرض را لغو می کنیم صفت و به صراحت تنظیم شده است MaxPackets در فیلمنامه سپس شما
باید اسکریپت را از نو بسازند. شما همچنین باید نحوی را برای تنظیم واقعی پیدا کنید
مقدار مشخصه پیش فرض جدید با استفاده از تسهیلات خط فرمان کمکی. وقتی اینو داشتی
متوجه شدم که باید بتوانید تعداد بسته هایی که از دستور بازتاب می شود را کنترل کنید
خط از آنجایی که ما افراد خوبی هستیم، به شما می گوییم که خط فرمان شما باید در نهایت به نظر برسد
چیزی مثل،

$ ./waf -- run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::تاخیر = 2 میلی ثانیه
--ns3::UdpEchoClient::MaxPackets=2"

قلاب زدن شما خود ارزش‌ها
شما همچنین می توانید قلاب های خود را به سیستم خط فرمان اضافه کنید. این کار به سادگی توسط
با استفاده از AddValue روش به تجزیه کننده خط فرمان.

بیایید از این امکان برای تعیین تعداد بسته هایی که باید به صورت کاملاً متفاوت بازتاب می کنند استفاده کنیم
مسیر. بیایید یک متغیر محلی به نام اضافه کنیم nPackets به اصلی عملکرد. مقداردهی اولیه می کنیم
آن را به یک برای مطابقت با رفتار پیش فرض قبلی ما. تا به تجزیه کننده خط فرمان اجازه دهید
این مقدار را تغییر دهید، باید مقدار را به تجزیه کننده متصل کنیم. ما این کار را با افزودن یک تماس انجام می دهیم
به AddValue. برو جلو و تغییرش بده scratch/myfirst.cc اسکریپت برای شروع با
کد زیر،

INT
اصلی (int argc، char *argv[])
{
uint32_t nPackets = 1;

CommandLine cmd;
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);
cmd.Parse (argc, argv);

...

به پایین اسکرول کنید تا به نقطه ای از اسکریپت بروید که در آن تنظیم کردیم MaxPackets صفت و آن را تغییر دهید
به طوری که روی متغیر تنظیم می شود nPackets به جای ثابت 1 همانطور که در زیر نشان داده شده است.

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

حالا اگر اسکریپت را اجرا کنید و ارائه دهید --PrintHelp استدلال، شما باید جدید خود را ببینید
کاربر استدلال در صفحه راهنما فهرست شده است.

تلاش كردن،

$ ./waf -- "scratch/myfirst --PrintHelp" را اجرا کنید

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.403s)
--PrintHelp: این پیام راهنما را چاپ کنید.
--PrintGroups: لیست گروه ها را چاپ کنید.
--PrintTypeIds: چاپ همه TypeIds.
--PrintGroup=[group]: چاپ تمام TypeId های گروه.
--PrintAttributes=[typeid]: چاپ تمام ویژگی های typeid.
--PrintGlobals: فهرست جهانی ها را چاپ کنید.
آرگومان های کاربر:
--nPackets: تعداد بسته هایی که باید پژواک شوند

اگر می‌خواهید تعداد بسته‌ها را برای اکو مشخص کنید، اکنون می‌توانید با تنظیم کردن این کار را انجام دهید
--nبسته ها آرگومان در خط فرمان،

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

حالا باید ببینمت

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
1024 بایت به 10.1.1.2 ارسال شد
2.25732s دریافت 1024 بایت از 10.1.1.1
2.25732s بسته پژواک
دریافت 1024 بایت از 10.1.1.2
1024 بایت به 10.1.1.2 ارسال شد
3.25732s دریافت 1024 بایت از 10.1.1.1
3.25732s بسته پژواک
دریافت 1024 بایت از 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

شما اکنون دو بسته را تکرار کرده اید. خیلی آسان است، اینطور نیست؟

شما می توانید ببینید که اگر شما یک ns-3 کاربر، می توانید از سیستم آرگومان خط فرمان استفاده کنید
کنترل ارزش های جهانی و خواص. اگر نویسنده مدل هستید، می توانید جدید اضافه کنید
خواص خود را به اشیاء و آنها به طور خودکار برای تنظیم توسط شما در دسترس خواهند بود
کاربران از طریق سیستم خط فرمان اگر نویسنده اسکریپت هستید، می توانید جدید اضافه کنید
متغیرها را به اسکریپت های خود اضافه کنید و آنها را بدون دردسر به سیستم خط فرمان متصل کنید.

با استفاده از la ردیابی سیستم
کل هدف شبیه سازی تولید خروجی برای مطالعه بیشتر است ns-3
سیستم ردیابی یک مکانیسم اولیه برای این است. از آنجا که ns-3 یک برنامه C++، استاندارد است
می توان از امکانات تولید خروجی از برنامه های C++ استفاده کرد:

#عبارتند از
...
intmain()
{
...
std::cout << "مقدار x " << x << std::endl;
...
}

حتی می توانید از ماژول ورود به سیستم برای اضافه کردن ساختار کمی به راه حل خود استفاده کنید. آنجا
بسیاری از مشکلات شناخته شده ای هستند که توسط چنین رویکردهایی ایجاد می شوند و بنابراین ما یک ارائه کرده ایم
زیرسیستم ردیابی رویداد عمومی برای رسیدگی به مسائلی که فکر می کردیم مهم هستند.

اهداف اساسی از ns-3 سیستم ردیابی عبارتند از:

· برای کارهای اساسی، سیستم ردیابی باید به کاربر اجازه دهد تا ردیابی استاندارد را ایجاد کند
برای منابع ردیابی محبوب، و برای سفارشی کردن اشیاء ایجاد ردیابی.

· کاربران متوسط ​​باید بتوانند سیستم ردیابی را برای اصلاح فرمت خروجی گسترش دهند
تولید شده، یا برای درج منابع ردیابی جدید، بدون تغییر هسته
شبیه ساز؛

· کاربران پیشرفته می توانند هسته شبیه ساز را برای اضافه کردن منابع ردیابی جدید و سینک ها تغییر دهند.

La ns-3 سیستم ردیابی بر اساس مفاهیم منابع ردیابی مستقل و
ردیابی سینک ها و مکانیزم یکنواخت برای اتصال منابع به سینک ها. منابع ردیابی هستند
موجودیت هایی که می توانند رویدادهایی را که در یک شبیه سازی اتفاق می افتد سیگنال دهند و دسترسی به آنها را فراهم کنند
داده های اساسی جالب به عنوان مثال، یک منبع ردیابی می تواند زمان بودن یک بسته را نشان دهد
دریافت شده توسط یک دستگاه شبکه و امکان دسترسی به محتویات بسته برای ردیابی علاقه مند
غرق می شود

منابع ردیابی به خودی خود مفید نیستند، آنها باید به قطعات دیگر "متصل" شوند
کدهایی که در واقع با اطلاعات ارائه شده توسط سینک کار مفیدی انجام می دهند. پی گیری
سینک ها مصرف کنندگان رویدادها و داده های ارائه شده توسط منابع ردیابی هستند. مثلا،
می توان یک سینک ردیابی ایجاد کرد که (در صورت اتصال به منبع ردیابی
مثال قبلی) بخش های جالب بسته دریافتی را چاپ کنید.

منطق این تقسیم بندی صریح این است که به کاربران اجازه می دهد انواع جدیدی از سینک ها را به آن وصل کنند
منابع ردیابی موجود، بدون نیاز به ویرایش و کامپایل مجدد هسته اصلی
شبیه ساز بنابراین، در مثال بالا، یک کاربر می تواند یک سینک ردیابی جدید را در خود تعریف کند
اسکریپت و آن را به یک منبع ردیابی موجود که در هسته شبیه سازی توسط تعریف شده است وصل کنید
ویرایش فقط اسکریپت کاربر

در این آموزش، چند منبع و سینک از پیش تعریف شده را مرور خواهیم کرد و نحوه انجام آن را نشان خواهیم داد
آنها ممکن است با کمی تلاش کاربر سفارشی شوند. به بخش راهنمای ns-3 یا نحوه انجام آن مراجعه کنید
برای اطلاعات در مورد پیکربندی ردیابی پیشرفته از جمله گسترش ردیابی
فضای نام و ایجاد منابع ردیابی جدید.

ASCII ردیابی
ns-3 عملکرد کمکی را ارائه می دهد که سیستم ردیابی سطح پایین را به شما کمک می کند
با جزئیات مربوط به پیکربندی برخی از ردیابی های بسته به راحتی قابل درک است. اگر شما
این قابلیت را فعال کنید، خروجی را در یک فایل ASCII خواهید دید --- بنابراین نام. برای
کسانی که با ns-2 خروجی، این نوع ردیابی مشابه است out.tr تولید
توسط بسیاری از اسکریپت ها

بیایید درست وارد شویم و مقداری خروجی ردیابی ASCII را به ما اضافه کنیم scratch/myfirst.cc
اسکریپت درست قبل از تماس به شبیه ساز::اجرا کنید ()، خطوط کد زیر را اضافه کنید:

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

مانند بسیاری دیگر ns-3 اصطلاحات، این کد از یک شی کمکی برای کمک به ایجاد ASCII استفاده می کند
آثار خط دوم شامل دو فراخوانی متد تو در تو است. روش "درون"،
CreateFileStream() از یک اصطلاح شی بی نام برای ایجاد یک شی جریان فایل روی آن استفاده می کند
پشته (بدون نام شی) و آن را به متد فراخوانی شده منتقل کنید. ما وارد این می شویم
بیشتر در آینده، اما تنها چیزی که در این مرحله باید بدانید این است که در حال ایجاد یک
شی نشان دهنده فایلی به نام "myfirst.tr" و ارسال آن به آن است ns-3. شما دارید می گویید
ns-3 برای رسیدگی به مسائل طول عمر شی ایجاد شده و همچنین مقابله با مشکلات
ناشی از محدودیت کمتر شناخته شده (عمدی) C++ ofstream اشیاء مربوط به کپی است
سازندگان

تماس بیرونی، به EnableAsciiAll()، به کمک کننده می گوید که می خواهید ASCII را فعال کنید
ردیابی در تمام دستگاه های نقطه به نقطه در شبیه سازی شما. و شما می خواهید (ارائه شده)
trace sinks برای نوشتن اطلاعات در مورد حرکت بسته در قالب ASCII.

برای آشنایان ns-2، رویدادهای ردیابی شده معادل نقاط ردیابی محبوب هستند
که رویدادهای "+"، "-"، "d" و "r" را ثبت می کند.

اکنون می توانید اسکریپت را بسازید و آن را از خط فرمان اجرا کنید:

$ ./waf --run scratch/myfirst

همانطور که قبلاً بارها دیده اید، پیام هایی از Waf و سپس مشاهده خواهید کرد
"ساخت" با موفقیت به پایان رسید" با تعدادی پیام از برنامه در حال اجرا.

وقتی اجرا شد، برنامه فایلی به نام ایجاد می کند myfirst.tr. به خاطر راه
که Waf کار می کند، فایل در دایرکتوری محلی ایجاد نمی شود، در آن ایجاد می شود
دایرکتوری سطح بالای مخزن به طور پیش فرض. اگر می خواهید برای کنترل جایی که آثار
ذخیره می شوند شما می توانید استفاده کنید --cwd گزینه Waf برای مشخص کردن این. بنابراین ما این کار را نکرده ایم
ما باید به دایرکتوری سطح بالای مخزن خود برویم و نگاهی به ASCII بیندازیم
فایل ردیابی myfirst.tr در ویرایشگر مورد علاقه شما

تجزیه آسچی ردیابی ها
اطلاعات زیادی در آنجا به شکل بسیار متراکم وجود دارد، اما اولین چیزی که باید به آن توجه کرد
این است که تعدادی از خطوط مجزا در این فایل وجود دارد. شاید دیدن آن سخت باشد
این واضح است مگر اینکه پنجره خود را به میزان قابل توجهی باز کنید.

هر خط در فایل مربوط به a است رد واقعه. در این مورد ما در حال ردیابی رویدادها هستیم
la انتقال صف موجود در هر دستگاه شبکه نقطه به نقطه در شبیه سازی. در
صف انتقال یک صف است که از طریق آن هر بسته برای یک کانال نقطه به نقطه تعیین می شود
باید قبول شود. توجه داشته باشید که هر خط در فایل ردیابی با یک کاراکتر تنها شروع می شود (دارای یک
فاصله بعد از آن). این کاراکتر معنی زیر را خواهد داشت:

· +: یک عملیات صف در صف دستگاه رخ داد.

· -: یک عملیات Dequeue در صف دستگاه رخ داد.

· d: یک بسته حذف شد، معمولاً به دلیل پر بودن صف.

· r: یک بسته توسط دستگاه نت دریافت شد.

بیایید نمای دقیق تری از خط اول در فایل ردیابی داشته باشیم. من آن را خراب می کنم
به بخش هایی (برای وضوح تورفتگی) با شماره مرجع در سمت چپ:

+
2
/NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
ns3::PppHeader (
پروتکل نقطه به نقطه: IP (0x0021))
ns3::Ipv4Header (
tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [هیچکدام]
طول: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
طول: 1032 49153 > 9)
بار (اندازه = 1024)

بخش اول این رویداد ردیابی گسترش یافته (شماره مرجع 0) عملیات است. ما
دارای یک + شخصیت، بنابراین این مربوط به یک در نوبت قراردادن عملیات در صف انتقال
بخش دوم (مرجع 1) زمان شبیه سازی است که بر حسب ثانیه بیان می شود. شما ممکن است
به یاد بیاورید که ما از UdpEchoClientApplication برای شروع ارسال بسته ها در دو ثانیه.
در اینجا ما تأیید می کنیم که این واقعاً اتفاق می افتد.

بخش بعدی ردیابی مثال (مرجع 2) به ما می گوید که منبع ردیابی از کدام منبع نشات گرفته است
این رویداد (بیان شده در فضای نام ردیابی). می توانید به فضای نام ردیابی فکر کنید
تا حدودی مانند فضای نام فایل سیستم. ریشه فضای نام است
NodeList. این مربوط به یک ظرف مدیریت شده در ns-3 کد اصلی که شامل همه است
از گره هایی که در یک اسکریپت ایجاد می شوند. همانطور که یک فایل سیستم ممکن است دایرکتوری داشته باشد
در زیر ریشه، ممکن است اعداد گره در قسمت داشته باشیم NodeList. رشته /NodeList/0
بنابراین به گره صفر در NodeList که ما معمولاً آن را به عنوان "گره" در نظر می گیریم
0". در هر گره لیستی از دستگاه های نصب شده وجود دارد. این لیست ظاهر می شود
بعدی در فضای نام می توانید ببینید که این رویداد ردیابی از آن ناشی می شود DeviceList/0 و باور نکردنی
دستگاه صفر نصب شده در گره.

رشته بعدی، $ns3::PointToPointNetDevice به شما می گوید که چه نوع دستگاهی در آن قرار دارد
موقعیت صفر لیست دستگاه برای گره صفر. به یاد بیاورید که عملیات + یافت شده در
مرجع 00 به این معنی است که یک عملیات صف در صف ارسال دستگاه اتفاق افتاده است.
این در بخش های پایانی "مسیر ردیابی" که هستند منعکس می شود TxQueue/Enqueue.

بخش‌های باقی‌مانده در ردیابی باید نسبتاً شهودی باشند. مراجع 3-4 نشان می دهد
که بسته در پروتکل نقطه به نقطه کپسوله شده است. منابع 5-7 نشان می دهد که
بسته دارای سرآیند IP نسخه چهار است و از آدرس IP 10.1.1.1 منشاء گرفته است و
برای 10.1.1.2 مقصد است. مراجع 8-9 نشان می دهد که این بسته دارای یک سربرگ UDP است و
در نهایت، مرجع 10 نشان می دهد که بار بار 1024 بایت مورد انتظار است.

خط بعدی در فایل ردیابی همان بسته را نشان می دهد که از فرستنده خارج شده است
صف در همان گره

خط سوم در فایل ردیابی بسته دریافتی توسط دستگاه شبکه را نشان می دهد
گره با سرور اکو. من آن رویداد را در زیر بازتولید کرده ام.

r
2.25732
/NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
ns3::Ipv4Header (
tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [هیچکدام]
طول: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
طول: 1032 49153 > 9)
بار (اندازه = 1024)

توجه داشته باشید که عملیات ردیابی اکنون است r و زمان شبیه سازی به 2.25732 افزایش یافته است
ثانیه اگر مراحل آموزش را به دقت دنبال کرده اید، به این معنی است که شما این کار را انجام داده اید
ترک کرد نرخ داده از دستگاه های شبکه و کانال تاخیر انداختن روی مقادیر پیش فرض خود تنظیم کنید.
این زمان باید همانطور که قبلاً در بخش قبلی دیده اید آشنا باشد.

ورودی فضای نام منبع ردیابی (مرجع 02) تغییر کرده است تا نشان دهد که این رویداد وجود دارد
از گره 1 (/NodeList/1) و منبع ردیابی دریافت بسته (/MacRx) آی تی
باید برای شما بسیار آسان باشد که پیشرفت بسته را از طریق توپولوژی توسط شما دنبال کنید
نگاهی به بقیه ردیابی ها در فایل.

PCAP ردیابی
La ns-3 کمک کننده های دستگاه همچنین می توانند برای ایجاد فایل های ردیابی در pcap قالب در
مخفف pcap (معمولا با حروف کوچک نوشته می شود) مخفف packet capture است و در واقع یک
API که شامل تعریف a pcap فرمت فایل. محبوب ترین برنامه ای که
می تواند این فرمت را بخواند و نمایش دهد Wireshark (که قبلا Ethereal نامیده می شد). با این حال، وجود دارد
بسیاری از تحلیلگرهای ردیابی ترافیک هستند که از این قالب بسته استفاده می کنند. ما کاربران را تشویق می کنیم
از بسیاری از ابزارهای موجود برای تجزیه و تحلیل ردپای pcap استفاده کنید. در این آموزش ما
روی مشاهده ردپای pcap با tcpdump تمرکز کنید.

کد مورد استفاده برای فعال کردن ردیابی pcap یک خطی است.

pointToPoint.EnablePcapAll ("myfirst");

ادامه دهید و این خط کد را بعد از کد ردیابی ASCII که به تازگی به آن اضافه کرده ایم وارد کنید
scratch/myfirst.cc. توجه داشته باشید که ما فقط رشته "myfirst" را پاس کردیم و نه
"myfirst.pcap" یا چیزی مشابه. این به این دلیل است که پارامتر یک پیشوند است نه a
نام کامل فایل کمک کننده در واقع یک فایل ردیابی برای هر نقطه به نقطه ایجاد می کند
دستگاه در شبیه سازی نام فایل ها با استفاده از پیشوند، شماره گره ساخته می شود.
شماره دستگاه و پسوند ".pcap".

در اسکریپت مثال ما، در نهایت فایل هایی با نام "myfirst-0-0.pcap" و
"myfirst-1-0.pcap" که ردیابی های pcap برای نود 0-دستگاه 0 و گره 1-دستگاه 0 هستند،
بود.

هنگامی که خط کد را برای فعال کردن ردیابی pcap اضافه کردید، می توانید اسکریپت را در آن اجرا کنید
روش معمول:

$ ./waf --run scratch/myfirst

اگر به دایرکتوری سطح بالای توزیع خود نگاه کنید، اکنون باید سه گزارش را مشاهده کنید
فایل ها: myfirst.tr فایل ردیابی ASCII است که قبلا بررسی کردیم. myfirst-0-0.pcap
و myfirst-1-0.pcap فایل های pcap جدیدی هستند که ما به تازگی تولید کرده ایم.

مطالعه تولید با tcpdump
ساده ترین کار در این مرحله استفاده از آن خواهد بود tcpdump برای نگاه کردن به pcap فایل های.

$ tcpdump -nn -tt -r myfirst-0-0.pcap
خواندن از فایل myfirst-0-0.pcap، نوع پیوند PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP، طول 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP، طول 1024

tcpdump -nn -tt -r myfirst-1-0.pcap
خواندن از فایل myfirst-1-0.pcap، نوع پیوند PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP، طول 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP، طول 1024

می توانید در زباله دانی ببینید myfirst-0-0.pcap (دستگاه مشتری) که بسته اکو است
در 2 ثانیه به شبیه سازی ارسال شد. اگر به روگرفت دوم نگاه کنید (myfirst-1-0.pcap)
می توانید آن بسته را در 2.257324 ثانیه دریافت کنید. وجود بسته را می بینید
بازتابی در 2.257324 ثانیه در Dump دوم داشت و در نهایت، بسته بودن را مشاهده می کنید
در اولین تخلیه در 2.514648 ثانیه در مشتری دریافت شد.

مطالعه تولید با Wireshark
اگر با Wireshark آشنا نیستید، یک وب سایت در دسترس است که می توانید از آن استفاده کنید
دانلود برنامه ها و مستندات: http://www.wireshark.org/.

Wireshark یک رابط کاربری گرافیکی است که می تواند برای نمایش این ردیابی ها استفاده شود
فایل ها. اگر Wireshark را در دسترس دارید، می توانید هر یک از فایل های ردیابی را باز کرده و نمایش دهید
محتویات به گونه ای است که گویی بسته ها را با استفاده از a ضبط کرده اید بسته معتاد به انفیه.

BUILDING توپولوژی ها


بنا a اتوبوس شبکه ارتباطی توپولوژی
در این بخش قصد داریم تسلط خود را در این زمینه گسترش دهیم ns-3 دستگاه ها و کانال های شبکه به
نمونه ای از شبکه اتوبوس را پوشش دهد. ns-3 یک دستگاه و کانال شبکه ای را ارائه می دهد که ما آن را CSMA می نامیم
(دسترسی چندگانه Carrier Sense).

La ns-3 دستگاه CSMA یک شبکه ساده را با روح اترنت مدل می کند. یک اترنت واقعی
از طرح CSMA/CD (Carrier Sense Multiple Access with Collision Detection) با
به طور تصاعدی افزایش عقب نشینی برای رقابت برای رسانه انتقال مشترک. را ns-3
مدل های دستگاه و کانال CSMA فقط زیر مجموعه ای از این است.

همانطور که در هنگام ساخت، اشیاء کمکی توپولوژی نقطه به نقطه را دیدیم
توپولوژی های نقطه به نقطه، کمک کننده های توپولوژی CSMA معادل را در این بخش خواهیم دید.
ظاهر و عملکرد این کمک ها باید برای شما کاملا آشنا به نظر برسد.

ما یک نمونه اسکریپت را در پوشه examples/tutorial} خود ارائه می دهیم. این اسکریپت ساخته شده است
la first.cc اسکریپت و یک شبکه CSMA را به شبیه سازی نقطه به نقطه که قبلا انجام داده ایم اضافه می کند
در نظر گرفته شده. برو جلو و باز کن examples/tutorial/second.cc در ویرایشگر مورد علاقه شما شما
قبلاً به اندازه کافی دیده شده است ns-3 کد برای درک بیشتر آنچه در این اتفاق می افتد
به عنوان مثال، اما ما کل اسکریپت را مرور می کنیم و برخی از خروجی ها را بررسی می کنیم.

درست همانطور که در first.cc به عنوان مثال (و در تمام نمونه های ns-3) فایل با emacs شروع می شود
خط حالت و مقداری دیگ بخار GPL.

کد واقعی با بارگیری ماژول شامل فایل‌ها همانطور که در آن انجام شد شروع می‌شود first.cc
مثال.

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"

یکی از چیزهایی که می تواند به طرز شگفت انگیزی مفید باشد، کمی هنر ASCII است که یک کارتون را نشان می دهد
از توپولوژی شبکه ساخته شده در مثال. شما یک "نقاشی" مشابه را در آن خواهید یافت
بیشتر نمونه های ما

در این مورد، می بینید که ما قصد داریم مثال نقطه به نقطه خود را گسترش دهیم (لینک
بین گره های n0 و n1 زیر) با آویزان کردن یک شبکه اتوبوس از سمت راست. اطلاع
که این توپولوژی شبکه پیش‌فرض است زیرا می‌توانید تعداد گره‌ها را تغییر دهید
در LAN ایجاد شده است. اگر nCsma را روی یک تنظیم کنید، در مجموع دو گره روی آن وجود خواهد داشت
LAN (کانال CSMA) --- یک گره مورد نیاز و یک گره "اضافی". به طور پیش فرض سه وجود دارد
گره های "اضافی" همانطور که در زیر مشاهده می شود:

// توپولوژی شبکه پیش فرض
//
// 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// نقطه به نقطه | | | |
// =================
// LAN 10.1.2.0

سپس فضای نام ns-3 است استفاده و یک جزء لاگ تعریف شده است. این همه همینطور است
در آن بود first.cc، بنابراین هنوز چیز جدیدی وجود ندارد.

با استفاده از فضای نام ns3;

NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");

برنامه اصلی با تغییر کمی متفاوت شروع می شود. ما از یک پرچم پرمخاطب برای
تعیین کنید که آیا UdpEchoClientApplication و UdpEchoServerApplication ورود به سیستم
اجزا فعال هستند این پرچم به طور پیش‌فرض روی true است (اجزای گزارش فعال هستند)
اما به ما این امکان را می دهد که در طول آزمایش رگرسیون این مثال، ورود به سیستم را خاموش کنیم.

تعدادی کد آشنا خواهید دید که به شما امکان می دهد تعداد دستگاه های موجود در آن را تغییر دهید
شبکه CSMA از طریق آرگومان خط فرمان. وقتی اجازه دادیم کاری مشابه انجام دادیم
تعداد بسته های ارسال شده برای تغییر در بخش آرگومان های خط فرمان. آخرین
خط مطمئن می شود که حداقل یک گره "اضافی" دارید.

کد شامل تغییرات API قبلاً پوشش داده شده است، بنابراین شما باید کاملاً باشید
با کد زیر در این مرحله از آموزش راحت باشید.

bool verbose = درست;
uint32_t nCsma = 3;

CommandLine cmd;
cmd.AddValue ("nCsma"، "تعداد گره ها/دستگاه های \"اضافی" CSMA، nCsma);
cmd.AddValue ("مطمئن"، "به برنامه های کاربردی پژواک برای ورود به سیستم اگر درست است"، پرمخاطب);

cmd.Parse (argc, argv);

اگر (پرمخاطب)
{
LogComponentEnable("UdpEchoClientApplication"، LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication"، LOG_LEVEL_INFO);
}

nCsma = nCsma == 0 ? 1: nCsma;

مرحله بعدی ایجاد دو گره است که از طریق پیوند نقطه به نقطه به یکدیگر متصل می شویم.
La NodeContainer برای انجام این کار درست همانطور که در انجام شد استفاده می شود first.cc.

NodeContainer p2pNodes;
p2pNodes.Create (2);

بعد، دیگری را اعلام می کنیم NodeContainer برای نگه داشتن گره هایی که بخشی از گذرگاه خواهند بود
شبکه (CSMA) ابتدا، ما فقط خود شی ظرف را نمونه سازی می کنیم.

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

خط بعدی کد می شود اولین گره (مانند داشتن شاخص یک) از
ظرف گره نقطه به نقطه و آن را به ظرف گره هایی که CSMA دریافت می کنند اضافه می کند
دستگاه ها گره مورد بحث قرار است به یک دستگاه نقطه به نقطه ختم شود و یک CSMA
دستگاه سپس تعدادی گره "اضافی" ایجاد می کنیم که بقیه CSMA را تشکیل می دهند
شبکه. از آنجایی که ما قبلاً یک گره در شبکه CSMA داریم -- گرهی که خواهد داشت
هر دو دستگاه نقطه به نقطه و CSMA خالص، تعداد گره های "اضافی" به معنای تعداد است
گره های مورد نظر شما در بخش CSMA منهای یک.

بیت بعدی کد باید تا به حال کاملاً آشنا باشد. الف را نمونه می کنیم PointToPointHelper
و پیش فرض مرتبط را تنظیم کنید خواص به طوری که پنج مگابیت در ثانیه ایجاد می کنیم
فرستنده در دستگاه های ایجاد شده با استفاده از کمک کننده و تاخیر دو میلی ثانیه در کانال ها
ایجاد شده توسط کمک کننده

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("تاخیر"، StringValue ("2 میلی ثانیه"));

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

سپس a را نمونه می کنیم NetDeviceContainer برای پیگیری دستگاه های شبکه نقطه به نقطه
و ما نصب دستگاه های روی گره های نقطه به نقطه

ما در بالا ذکر کردیم که قرار است یک کمک کننده برای دستگاه ها و کانال های CSMA ببینید و
خطوط بعدی آنها را معرفی می کند. در CsmaHelper درست مانند یک کار می کند PointToPointHelper، اما
دستگاه ها و کانال های CSMA را ایجاد و متصل می کند. در مورد دستگاه CSMA و
جفت کانال، توجه کنید که نرخ داده با a مشخص شده است کانال صفت به جای یک
دستگاه صفت. این به این دلیل است که یک شبکه CSMA واقعی اجازه نمی‌دهد که ترکیب شود
به عنوان مثال، دستگاه های 10Base-T و 100Base-T در یک کانال مشخص. ابتدا نرخ داده را روی آن تنظیم می کنیم
100 مگابیت در ثانیه و سپس تاخیر سرعت نور کانال را روی 6560 تنظیم کنید.
نانو ثانیه (به طور خودسرانه به عنوان 1 نانوثانیه در هر فوت در یک بخش 100 متری انتخاب می شود).
توجه داشته باشید که می توانید یک را تنظیم کنید صفت با استفاده از نوع داده بومی خود

CsmaHelper csma;
csma.SetChannelAttribute ("DataRate"، StringValue ("100Mbps"));
csma.SetChannelAttribute ("تاخیر"، TimeValue (NanoSeconds (6560)));

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

همانطور که ما یک را ایجاد کردیم NetDeviceContainer برای نگه داشتن دستگاه های ایجاد شده توسط
PointToPointHelper ما ایجاد می کنیم NetDeviceContainer برای نگه داشتن دستگاه های ایجاد شده توسط ما
CsmaHelper. ما به نصب روش CsmaHelper برای نصب دستگاه ها در
گره های csmaNodes NodeContainer.

ما اکنون گره ها، دستگاه ها و کانال های خود را ایجاد کرده ایم، اما هیچ پشته پروتکل نداریم
حاضر. درست همانطور که در first.cc اسکریپت، ما از InternetStackHelper برای نصب
این پشته ها

پشته InternetStackHelper;
stack.Install (p2pNodes.Get (0));
stack.install (csmanodes) ؛

به یاد بیاورید که ما یکی از گره ها را از p2pNodes ظرف و آن را به
csmaNodes ظرف بنابراین ما فقط باید پشته ها را روی بقیه نصب کنیم p2pNodes
گره و تمام گره های موجود در csmaNodes ظرفی برای پوشش تمام گره های موجود در
شبیه سازی.

درست همانطور که در first.cc اسکریپت مثال، ما قصد داریم از IPv4AddressHelper به
آدرس های IP را به رابط های دستگاه خود اختصاص دهید. ابتدا از شبکه 10.1.1.0 برای ایجاد استفاده می کنیم
دو آدرس مورد نیاز برای دو دستگاه نقطه به نقطه ما.

آدرس Ipv4AddressHelper;
address.SetBase ("10.1.1.0"، "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces.
p2pInterfaces = address.Assign (p2pDevices);

به یاد داشته باشید که ما رابط های ایجاد شده را در یک ظرف ذخیره می کنیم تا بیرون کشیدن آن آسان شود
آدرس دهی اطلاعات بعدا برای استفاده در راه اندازی برنامه ها.

اکنون باید آدرس های IP را به رابط های دستگاه CSMA خود اختصاص دهیم. عملیات کار می کند
درست همانطور که برای مورد نقطه به نقطه انجام داد، با این تفاوت که اکنون در حال انجام این عملیات هستیم
ظرفی که دارای تعداد متغیری از دستگاه های CSMA است --- به یاد داشته باشید که تعداد آنها را ساخته ایم
دستگاه های CSMA با آرگومان خط فرمان قابل تغییر هستند. دستگاه های CSMA مرتبط خواهند شد
با آدرس های IP از شماره شبکه 10.1.2.0 در این مورد، همانطور که در زیر مشاهده می کنید.

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

اکنون یک توپولوژی ساخته شده است، اما به برنامه های کاربردی نیاز داریم. این بخش قرار است باشد
اساسا شبیه به بخش برنامه های کاربردی از first.cc اما ما قصد داریم
سرور را روی یکی از گره هایی که دارای دستگاه CSMA است و کلاینت را روی آن قرار دهید
گره ای که فقط یک دستگاه نقطه به نقطه دارد.

ابتدا سرور اکو را راه اندازی می کنیم. ما ایجاد می کنیم UdpEchoServerHelper و مورد نیاز را ارائه دهد
صفت مقدار سازنده ای که شماره پورت سرور است. به یاد بیاورید که این پورت
را می توان بعدا با استفاده از SetAttribute روش در صورت تمایل، اما ما به آن نیاز داریم
به سازنده ارائه شده است.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (ثانیه (1.0))؛
serverApps.Stop (ثانیه (10.0))؛

به یاد بیاورید که csmaNodes NodeContainer شامل یکی از گره های ایجاد شده برای
شبکه نقطه به نقطه و nCsma گره های "اضافی". چیزی که می خواهیم به آن برسیم آخرین مورد است
گره های "اضافی". ورودی صفر از csmaNodes ظرف نقطه به نقطه خواهد بود
گره بنابراین، راه آسان برای فکر کردن به این موضوع این است که اگر یک گره CSMA "اضافی" ایجاد کنیم، سپس آن را ایجاد کنیم
در شاخص یکی از csmaNodes ظرف با استقرا اگر ایجاد کنیم nCsma "اضافی"
گره های آخر در ایندکس خواهند بود nCsma. شما این را در نمایشگاه می بینید گرفتن از اول
خط کد

برنامه کلاینت دقیقاً همانطور که در برنامه انجام دادیم تنظیم شده است first.cc اسکریپت نمونه از نو،
مورد نیاز را فراهم می کنیم خواص به UdpEchoClientHelper در سازنده (در این مورد
آدرس و پورت راه دور). ما به مشتری می گوییم که بسته ها را به سروری که ما فقط داریم ارسال کند
بر روی آخرین گره CSMA "اضافی" نصب شده است. ما کلاینت را در سمت چپ نصب می کنیم
گره نقطه به نقطه که در تصویر توپولوژی دیده می شود.

UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma)، 9);
echoClient.SetAttribute ("MaxPackets"، UintegerValue (1));
echoClient.SetAttribute ("Interval"، TimeValue (ثانیه (1.0)));
echoClient.SetAttribute ("PacketSize"، UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
clientApps.Start (ثانیه (2.0));
clientApps.Stop (ثانیه (10.0));

از آنجایی که ما واقعاً در اینجا یک کار اینترنتی ایجاد کرده‌ایم، به نوعی از کار اینترنتی نیاز داریم
مسیریابی ns-3 چیزی را که ما مسیریابی جهانی می نامیم برای کمک به شما ارائه می دهد. مسیریابی جهانی طول می کشد
مزیت این واقعیت است که کل اینترنت در شبیه سازی قابل دسترسی است
از طریق تمام گره های ایجاد شده برای شبیه سازی اجرا می شود --- کار سخت را انجام می دهد
راه اندازی مسیریابی برای شما بدون نیاز به پیکربندی روترها.

اساساً آنچه اتفاق می افتد این است که هر گره طوری رفتار می کند که انگار یک روتر OSPF است
فورا و به طور جادویی با همه روترهای دیگر در پشت صحنه ارتباط برقرار می کند. هر گره
تبلیغات لینک تولید می کند و آنها را مستقیماً به یک مدیر مسیر جهانی ارسال می کند
که از این اطلاعات سراسری برای ساخت جداول مسیریابی برای هر گره استفاده می کند. تنظیمات
این شکل از مسیریابی یک خطی است:

Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

بعد pcap tracing را فعال می کنیم. اولین خط کد برای فعال کردن ردیابی pcap در
راهنمای نقطه به نقطه باید تا به حال برای شما آشنا باشد. خط دوم pcap را فعال می کند
ردیابی در کمک کننده CSMA و یک پارامتر اضافی وجود دارد که هنوز با آن مواجه نشده اید.

pointToPoint.EnablePcapAll ("دوم");
csma.EnablePcap ("دوم"، csmaDevices.Get (1)، true);

شبکه CSMA یک شبکه چند نقطه به نقطه است. این بدان معنی است که می توانند (و هستند در
در این مورد) چندین نقطه پایانی در یک رسانه مشترک. هر یک از این نقاط پایانی دارای یک شبکه هستند
دستگاه مرتبط با آن دو گزینه اساسی برای جمع آوری ردیابی وجود دارد
اطلاعات از چنین شبکه ای یکی از راه ها ایجاد یک فایل ردیابی برای هر دستگاه نت است
و فقط بسته هایی را که توسط آن دستگاه شبکه منتشر یا مصرف می شود ذخیره کنید. یک راه دیگر
این است که یکی از دستگاه ها را انتخاب کنید و آن را در حالت بی بند و بار قرار دهید. آن دستگاه واحد پس از آن
شبکه را برای همه بسته ها "خرد می کند" و آنها را در یک فایل pcap ذخیره می کند. اینگونه است
tcpdumpبه عنوان مثال، کار می کند. این پارامتر نهایی به کمک کننده CSMA می گوید که آیا این کار را انجام دهد یا خیر
ترتیبی دهید که بسته‌ها را در حالت بی‌وقفه ضبط کنید.

در این مثال قصد داریم یکی از دستگاه های موجود در شبکه CSMA را انتخاب کرده و از آن بپرسیم
برای انجام یک sniff بی رویه از شبکه، در نتیجه شبیه سازی چه چیزی tcpdump انجام می داد
اگر از یک دستگاه لینوکس استفاده می‌کردید، ممکن است کاری مشابه انجام دهید tcpdump -i eth0 برای دریافت
پی گیری. در این حالت دستگاه را با استفاده مشخص می کنیم csmaDevices.Get(1)، که انتخاب می کند
اولین دستگاه در ظرف تنظیم پارامتر نهایی روی true، promiscuous را فعال می کند
تصرف می کند.

آخرین بخش کد فقط اجرا می‌شود و شبیه‌سازی را درست مانند آن پاک می‌کند first.cc
مثال.

شبیه ساز::Run ();
شبیه ساز::Destroy ();
0 بازگشت؛
}

برای اجرای این مثال، آن را کپی کنید second.cc اسکریپت مثال در دایرکتوری scratch
و از waf برای ساخت استفاده کنید همانطور که با آن انجام دادید first.cc مثال. اگر شما در
دایرکتوری سطح بالای مخزنی که فقط تایپ می کنید،

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

هشدار: ما از فایل استفاده می کنیم second.cc به عنوان یکی از تست های رگرسیون ما برای تأیید اینکه کار می کند
دقیقاً همانطور که ما فکر می کنیم برای اینکه تجربه آموزشی شما را به یک تجربه مثبت تبدیل کنیم.
این بدان معنی است که یک فایل اجرایی به نام دوم در حال حاضر در پروژه وجود دارد. برای جلوگیری از هر
سردرگمی در مورد آنچه اجرا می کنید، لطفاً تغییر نام را انجام دهید mysecond.cc پیشنهاد
در بالا.

اگر از نظر مذهبی آموزش را دنبال می کنید (هستید، نیستید) باز هم خواهید داشت
مجموعه متغیر NS_LOG، بنابراین ادامه دهید و آن متغیر را پاک کنید و برنامه را اجرا کنید.

صادرات $ NS_LOG=
$ ./waf -خراش/mysecond

از آنجایی که ما برنامه های UDP echo را برای ورود به سیستم درست همانطور که انجام دادیم تنظیم کرده ایم first.cc، شما خواهد شد
هنگام اجرای اسکریپت خروجی مشابهی را مشاهده کنید.

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.415s)
1024 بایت به 10.1.2.4 ارسال شد
دریافت 1024 بایت از 10.1.1.1
دریافت 1024 بایت از 10.1.2.4

به یاد بیاورید که اولین پیام، "ارسال شد 1024 بایت به 10.1.2.4"، سرویس گیرنده اکو UDP است
ارسال یک بسته به سرور در این حالت سرور در شبکه دیگری قرار دارد
(10.1.2.0). پیام دوم، "دریافتی 1024 بایت از جانب 10.1.1.1"از پژواک UDP است
سرور، زمانی که بسته اکو را دریافت می کند، ایجاد می شود. پیام پایانی، "دریافتی 1024
بایت از جانب 10.1.2.4" از مشتری echo است، که نشان می دهد اکو خود را دریافت کرده است
برگشت از سرور

اگر اکنون به فهرست راهنمای سطح بالا بروید، سه فایل ردیابی را پیدا خواهید کرد:

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

بیایید لحظه ای به نام گذاری این فایل ها نگاهی بیندازیم. همه آنها یک شکل دارند،
- - pcap. به عنوان مثال، اولین فایل در لیست است
دوم-0-0.pcap که ردیابی pcap از گره صفر، دستگاه صفر است. این است
دستگاه شبکه نقطه به نقطه روی گره صفر. پرونده دوم-1-0.pcap ردیابی pcap برای است
دستگاه صفر در گره یک، همچنین یک دستگاه شبکه نقطه به نقطه. و فایل دوم-2-0.pcap is
ردیابی pcap برای دستگاه صفر در گره دو.

اگر به تصویر توپولوژی در ابتدای بخش مراجعه کنید، خواهید دید
که گره صفر سمت چپ ترین گره پیوند نقطه به نقطه و گره یک گره است
که هم یک دستگاه نقطه به نقطه و هم یک دستگاه CSMA دارد. خواهید دید که گره دو است
اولین گره "اضافی" در شبکه CSMA و دستگاه صفر آن به عنوان دستگاه انتخاب شد
برای گرفتن ردی از حالت بیجا.

اکنون، بیایید بسته اکو را از طریق اینترنت دنبال کنیم. ابتدا یک tcpdump از the را انجام دهید
فایل ردیابی برای سمت چپ ترین گره نقطه به نقطه --- گره صفر.

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

شما باید محتویات فایل pcap را مشاهده کنید:

خواندن از فایل second-0-0.pcap، نوع پیوند PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، طول 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، طول 1024

خط اول dump نشان می دهد که نوع پیوند PPP (نقطه به نقطه) است که ما
انتظار. سپس بسته اکو را می بینید که گره صفر را از طریق دستگاه مرتبط با IP خارج می کند
آدرس 10.1.1.1 به آدرس IP 10.1.2.4 (راست ترین گره CSMA) هدایت شد. این بسته
روی پیوند نقطه به نقطه حرکت می کند و توسط دستگاه شبکه نقطه به نقطه دریافت می شود
گره یک بیا یک نگاهی بیندازیم:

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

اکنون باید خروجی pcap trace را در سمت دیگر پیوند نقطه به نقطه مشاهده کنید:

خواندن از فایل second-1-0.pcap، نوع پیوند PPP (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، طول 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، طول 1024

در اینجا می بینیم که نوع پیوند نیز همانطور که انتظار داریم PPP است. شما بسته را از IP مشاهده می کنید
آدرس 10.1.1.1 (که در 2.000000 ثانیه ارسال شد) به آدرس IP 10.1.2.4 هدایت شد.
در این رابط ظاهر می شود. اکنون، به صورت داخلی به این گره، بسته به آن ارسال می شود
رابط CSMA و ما باید ببینیم که در آن دستگاه به سمت نهایی خود می رود
مقصد

به یاد داشته باشید که ما گره 2 را به عنوان گره sniffer promiscuous برای شبکه CSMA انتخاب کردیم
اجازه دهید سپس به second-2-0.pcap نگاه کنیم و ببینیم آیا وجود دارد یا خیر.

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

اکنون باید تخلیه ناخواسته گره دو، دستگاه صفر را ببینید:

خواندن از فایل second-2-0.pcap، نوع پیوند EN10MB (اترنت)
2.007698 ARP، درخواست who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) به 10.1.2.1، طول 50 بگویید
2.007710 ARP، پاسخ 10.1.2.4 is-at 00:00:00:00:00:06، طول 50
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، طول 1024
2.013815 ARP، درخواست who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) به 10.1.2.4، طول 50 بگویید
2.013828 ARP، پاسخ 10.1.2.1 is-at 00:00:00:00:00:03، طول 50
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، طول 1024

همانطور که می بینید، نوع پیوند اکنون "Ethernet" است. هر چند چیز جدیدی ظاهر شده است. در
نیازهای شبکه اتوبوس ARP، پروتکل حل آدرس. Node one می داند که باید ارسال کند
بسته به آدرس IP 10.1.2.4، اما آدرس MAC آن را نمی داند.
گره مربوطه در شبکه CSMA (ff:ff:ff:ff:ff:ff) پخش می شود و درخواست می کند
دستگاهی که دارای آدرس IP 10.1.2.4 است. در این مورد، سمت راست ترین گره پاسخ می دهد که آن را می گوید
در آدرس MAC 00:00:00:00:00:06 است. توجه داشته باشید که گره دو به طور مستقیم درگیر این موضوع نیست
تبادل، اما شبکه را استشمام می کند و تمام ترافیکی را که می بیند گزارش می دهد.

این مبادله در خطوط زیر مشاهده می شود

2.007698 ARP، درخواست who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) به 10.1.2.1، طول 50 بگویید
2.007710 ARP، پاسخ 10.1.2.4 is-at 00:00:00:00:00:06، طول 50

سپس گره یک، دستگاه یک جلو می رود و بسته اکو را به سرور اکو UDP در ارسال می کند
آدرس IP 10.1.2.4.

2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، طول 1024

سرور درخواست اکو را دریافت می کند و بسته را در تلاش برای ارسال مجدد به آن می چرخاند
منبع. سرور می داند که این آدرس در شبکه دیگری است که از طریق آن به آن می رسد
آدرس IP 10.1.2.1. این به این دلیل است که ما مسیریابی جهانی را راه اندازی کردیم و همه چیز را مشخص کرده است
از این برای ما. اما، گره سرور اکو آدرس MAC اولی را نمی‌داند
گره CSMA، بنابراین باید مانند اولین گره CSMA برای آن ARP انجام دهد.

2.013815 ARP، درخواست who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) به 10.1.2.4، طول 50 بگویید
2.013828 ARP، پاسخ 10.1.2.1 is-at 00:00:00:00:00:03، طول 50

سپس سرور پژواک را به گره فورواردینگ باز می‌فرستد.

2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، طول 1024

با نگاه کردن به سمت راست ترین گره پیوند نقطه به نقطه،

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

اکنون می‌توانید بسته بازتاب داده شده را ببینید که به عنوان آخرین بسته به پیوند نقطه به نقطه باز می‌گردد
خط تخلیه ردیابی

خواندن از فایل second-1-0.pcap، نوع پیوند PPP (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، طول 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، طول 1024

در نهایت، می‌توانید به گره‌ای که اکو را ایجاد کرده است نگاه کنید

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

و ببینید که بسته پژواک شده در 2.007602 ثانیه به منبع باز می گردد،

خواندن از فایل second-0-0.pcap، نوع پیوند PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، طول 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، طول 1024

در نهایت، به یاد بیاورید که ما توانایی کنترل تعداد دستگاه های CSMA را در آن اضافه کردیم
شبیه سازی با آرگومان خط فرمان شما می توانید این آرگومان را به همان روشی که چه زمانی تغییر دهید
ما به تغییر تعداد بسته های بازتاب داده شده در آن نگاه کردیم first.cc مثال. دویدن را امتحان کنید
برنامه با تعداد دستگاه های "اضافی" روی چهار تنظیم شده است:

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

اکنون باید ببینید،

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.405s)
در زمان 2s کلاینت 1024 بایت به پورت 10.1.2.5 9 ارسال کرد
در زمان 2.0118s سرور 1024 بایت از پورت 10.1.1.1 49153 دریافت کرد.
در زمان 2.0118s سرور 1024 بایت را به پورت 10.1.1.1 49153 ارسال کرد.
در زمان 2.02461s کلاینت 1024 بایت از پورت 10.1.2.5 9 دریافت کرد.

توجه داشته باشید که سرور اکو اکنون به آخرین گره CSMA منتقل شده است
10.1.2.5 به جای حالت پیش فرض، 10.1.2.4.

این امکان وجود دارد که شما از فایل ردیابی تولید شده توسط یک تماشاگر راضی نباشید
شبکه CSMA ممکن است واقعاً بخواهید از یک دستگاه ردیابی کنید و ممکن است نخواهید
به هر ترافیک دیگری در شبکه علاقه مند باشید. شما می توانید این کار را نسبتاً آسان انجام دهید.

بیایید نگاهی بیندازیم scratch/mysecond.cc و آن کد را اضافه کنید که ما را قادر می سازد بیشتر باشیم
خاص ns-3 کمک‌کنندگان روش‌هایی را ارائه می‌کنند که شماره گره و شماره دستگاه را به‌عنوان در نظر می‌گیرند
مولفه های. برو و جایگزین کن EnablePcap با تماس های زیر تماس بگیرید.

pointToPoint.EnablePcap ("دوم"، p2pNodes.Get (0)->GetId ()، 0);
csma.EnablePcap ("دوم"، csmaNodes.Get (nCsma)->GetId ()، 0، false);
csma.EnablePcap ("دوم"، csmaNodes.Get (nCsma-1)->GetId ()، 0، false);

ما می دانیم که می خواهیم یک فایل pcap با نام پایه "second" ایجاد کنیم و همچنین می دانیم
که دستگاه مورد نظر در هر دو مورد صفر خواهد بود، بنابراین آن پارامترها نیستند
واقعا جالب

برای به دست آوردن شماره گره، دو انتخاب دارید: اول، گره ها با a شماره گذاری می شوند
افزایش یکنواخت مد با شروع از صفر به ترتیبی که ایجاد کردید
آنها یکی از راه های بدست آوردن شماره گره این است که این عدد را به صورت دستی بدست آوریم
در نظر گرفتن ترتیب ایجاد گره اگر نگاهی به توپولوژی شبکه بیندازید
تصویر در ابتدای فایل، ما این کار را برای شما انجام دادیم و می بینید که
آخرین گره CSMA شماره گره خواهد بود nCsma + 1. این رویکرد می تواند آزار دهنده باشد
در شبیه سازی های بزرگتر مشکل است.

یک راه جایگزین، که ما در اینجا استفاده می کنیم، این است که متوجه شویم NodeContainers شامل
اشاره گر به ns-3 گره اشیاء. را گره شی دارای متدی به نام است GetId که خواهد شد
شناسه آن گره را که همان شماره گره ای است که به دنبال آن هستیم، برگردانید. بیا برویم نگاهی به
داکسیژن برای گره و آن روش را پیدا کنید، که در پایین تر است ns-3 کد اصلی
از آنچه تاکنون دیده ایم؛ اما گاهی اوقات باید به دنبال چیزهای مفید باشید.

برای انتشار خود به مستندات Doxygen بروید (به یاد داشته باشید که می توانید آن را در آن پیدا کنید
وب سایت پروژه). می توانید به گره مستندات با نگاه کردن به
برگه «Classes» را بزنید و «فهرست کلاس‌ها» را به پایین اسکرول کنید تا پیدا کنید ns3:: گره. انتخاب
ns3:: گره و شما را به اسناد مربوط به گره کلاس اگر شما در حال حاضر
به پایین اسکرول کنید GetId روش و انتخاب آن، به جزئیات هدایت خواهید شد
مستندسازی برای روش با استفاده از GetId روش می تواند تعداد گره ها را تعیین کند
در توپولوژی های پیچیده بسیار آسان تر است.

برای جلوگیری از سردرگمی، بیایید فایل‌های ردیابی قدیمی را از دایرکتوری سطح بالا پاک کنیم
چه خبره،

$ rm *.pcap
$ rm *.tr

اگر اسکریپت جدید را بسازید و تنظیمات شبیه سازی را اجرا کنید nCsma به 100،

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

خروجی زیر را خواهید دید:

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.407s)
در زمان 2s کلاینت 1024 بایت به پورت 10.1.2.101 9 ارسال کرد
در زمان 2.0068s سرور 1024 بایت از پورت 10.1.1.1 49153 دریافت کرد.
در زمان 2.0068s سرور 1024 بایت را به پورت 10.1.1.1 49153 ارسال کرد.
در زمان 2.01761s کلاینت 1024 بایت از پورت 10.1.2.101 9 دریافت کرد.

توجه داشته باشید که سرور اکو اکنون در 10.1.2.101 قرار دارد که مربوط به داشتن 100 است.
گره های "اضافی" CSMA با سرور اکو در آخرین مورد. اگر فایل های pcap را در لیست قرار دهید
دایرکتوری سطح بالایی که خواهید دید،

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

فایل ردیابی دوم-0-0.pcap "سمت چپ ترین" دستگاه نقطه به نقطه است که اکو است
منبع بسته پرونده دوم-101-0.pcap مربوط به سمت راست ترین دستگاه CSMA است که
جایی است که سرور اکو در آن قرار دارد. ممکن است متوجه شده باشید که پارامتر نهایی در
تماس برای فعال کردن ردیابی pcap در گره سرور اکو نادرست بود. این به این معنی است که اثر
جمع آوری شده در آن گره در حالت غیر بی بند و باری بود.

برای نشان دادن تفاوت بین ردپای محجوب و غیر محجور، ما نیز
درخواست یک ردیابی غیرمجاز برای گره بعدی تا آخر کرد. برو جلو و نگاهی به
la tcpdump برای دوم-100-0.pcap.

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

اکنون می توانید ببینید که گره 100 واقعاً یک تماشاگر در تبادل اکو است. تنها
بسته هایی که دریافت می کند درخواست های ARP هستند که به کل CSMA پخش می شوند
شبکه می باشد.

خواندن از فایل second-100-0.pcap، نوع پیوند EN10MB (اترنت)
2.006698 ARP، درخواست who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) به 10.1.2.1، طول 50 بگویید
2.013815 ARP، درخواست who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) به 10.1.2.101، طول 50 بگویید

حالا نگاهی به tcpdump برای دوم-101-0.pcap.

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

اکنون می توانید ببینید که گره 101 واقعاً در تبادل اکو شرکت می کند.

خواندن از فایل second-101-0.pcap، نوع پیوند EN10MB (اترنت)
2.006698 ARP، درخواست who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) به 10.1.2.1، طول 50 بگویید
2.006698 ARP، پاسخ 10.1.2.101 is-at 00:00:00:00:00:67، طول 50
2.006803 IP 10.1.1.1.49153 > 10.1.2.101.9: UDP، طول 1024
2.013803 ARP، درخواست who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) به 10.1.2.101، طول 50 بگویید
2.013828 ARP، پاسخ 10.1.2.1 is-at 00:00:00:00:00:03، طول 50
2.013828 IP 10.1.2.101.9 > 10.1.1.1.49153: UDP، طول 1024

مدل ها، خواص و واقعیت
این یک مکان مناسب برای یک گشت و گذار کوچک و بیان یک نکته مهم است. ممکن است
یا ممکن است برای شما واضح نباشد، اما هر زمان که از شبیه سازی استفاده می کنید، مهم است
دقیقاً بفهمید چه چیزی در حال مدل سازی است و چه چیزی نیست. برای مثال وسوسه انگیز است
به دستگاه‌ها و کانال‌های CSMA که در بخش قبل استفاده شده‌اند، طوری فکر کنید که گویی واقعی هستند
دستگاه های اترنت؛ و انتظار داشته باشیم که یک نتیجه شبیه سازی مستقیماً منعکس کننده آنچه اتفاق خواهد افتاد باشد
در یک اترنت واقعی این مورد نیست.

مدل طبق تعریف، انتزاعی از واقعیت است. در نهایت این مسئولیت است
نویسنده اسکریپت شبیه سازی برای تعیین به اصطلاح "محدوده دقت" و "دامنه"
قابل اجرا بودن شبیه سازی به عنوان یک کل، و در نتیجه اجزای تشکیل دهنده آن.

در برخی موارد، مانند Csma، تعیین اینکه چیست می تواند نسبتاً آسان باشد نه مدل سازی شده توسط
خواندن توضیحات مدل (csma.h) می توانید متوجه شوید که تشخیص برخورد وجود ندارد
در مدل CSMA و تصمیم بگیرید که استفاده از آن در شبیه سازی شما چقدر کاربرد دارد یا چه چیزی
هشدارهایی که ممکن است بخواهید در نتایج خود لحاظ کنید. در موارد دیگر، می تواند بسیار آسان باشد
برای پیکربندی رفتارهایی که ممکن است با هیچ واقعیتی مطابقت نداشته باشند، می توانید بیرون بروید و بخرید. آی تی
صرف زمان برای بررسی چند مورد از این قبیل و چگونگی آن، ارزش دارد
به راحتی می توانید در شبیه سازی های خود به خارج از محدوده واقعیت منحرف شوید.

همانطور که دیدید ns-3 فراهم می کند خواص که کاربر به راحتی می تواند آن را برای تغییر مدل تنظیم کند
رفتار - اخلاق. دو مورد را در نظر بگیرید خواص از CsmaNetDevice: متو و
حالت Encapsulation. متو ویژگی حداکثر واحد انتقال را نشان می دهد
دستگاه این اندازه بزرگترین واحد داده پروتکل (PDU) است که دستگاه می تواند
ارسال.

پیش‌فرض MTU 1500 بایت است CsmaNetDevice. این پیش فرض مربوط به یک عدد است
در RFC 894، «استانداردی برای انتقال داده‌های IP از طریق اترنت» یافت می‌شود
شبکه ها." این عدد در واقع از حداکثر اندازه بسته برای 10Base5 به دست می آید
شبکه های اترنت (تمام مشخصات) -- 1518 بایت. اگر کپسولاسیون DIX را کم کنید
سربار بسته های اترنت (18 بایت) در نهایت به حداکثر اندازه ممکن داده خواهید رسید
(MTU) 1500 بایت. همچنین می توان یافت که MTU برای شبکه های IEEE 802.3 1492 است
بایت ها این به این دلیل است که کپسوله سازی LLC/SNAP هشت بایت اضافی به سربار اضافه می کند
بسته در هر دو مورد، سخت‌افزار زیربنایی فقط می‌تواند 1518 بایت، اما داده‌ها را ارسال کند
اندازه متفاوت است

به منظور تنظیم حالت کپسوله سازی، CsmaNetDevice فراهم می کند صفت نام
حالت Encapsulation که می تواند ارزش ها را به خود بگیرد دیکس or LLC. اینها با اترنت مطابقت دارند
و قاب بندی LLC/SNAP به ترتیب.

اگر یکی را ترک کند متو در 1500 بایت و تغییر حالت کپسوله سازی به LLC، نتیجه
شبکه ای خواهد بود که PDU های 1500 بایتی را با قاب بندی LLC/SNAP کپسوله می کند که منجر به
بسته های 1526 بایتی، که در بسیاری از شبکه ها غیرقانونی است، زیرا آنها می توانند a را انتقال دهند
حداکثر 1518 بایت در هر بسته. این به احتمال زیاد منجر به شبیه سازی می شود که
کاملاً نامحسوس واقعیتی را که ممکن است انتظارش را دارید منعکس کند.

فقط برای پیچیده تر کردن تصویر، فریم های جامبو وجود دارد (1500 < MTU <= 9000 بایت) و
فریم های فوق جامبو (MTU > 9000 بایت) که به طور رسمی توسط IEEE تایید نشده اند اما
در برخی از شبکه های پرسرعت (گیگابیت) و NIC موجود است. یکی می تواند ترک کند
حالت کپسوله سازی روی دیکس، و تنظیم کنید متو صفت در CsmaNetDevice تا 64000 بایت
-- حتی اگر مرتبط CsmaChannel نرخ داده بر روی 10 مگابیت بر ثانیه تنظیم شد. این
اساسا یک سوئیچ اترنت ساخته شده از 1980Base10 به سبک دهه 5 توسط خون آشام ها را مدل می کند.
شبکه هایی که از دیتاگرام های فوق العاده جامبو پشتیبانی می کنند. این قطعا چیزی نیست که بود
تا به حال ساخته شده است، و احتمالا هرگز ساخته نخواهد شد، اما پیکربندی آن برای شما بسیار آسان است.

در مثال قبلی، شما از خط فرمان برای ایجاد یک شبیه سازی که دارای 100 بود استفاده کردید
Csma گره ها شما می توانستید به همین راحتی یک شبیه سازی با 500 گره ایجاد کنید. اگر شما
در واقع آن شبکه 10Base5 vampire-tap را مدلسازی می کردند، حداکثر طول یک مشخصات کامل
کابل اترنت 500 متر با حداقل فاصله شیر 2.5 متر است. یعنی اونجا
فقط می تواند 200 ضربه در یک شبکه واقعی باشد. شما می توانستید به راحتی یک غیرقانونی بسازید
از این طریق نیز شبکه کنید. این ممکن است به یک شبیه سازی معنادار منجر شود یا نه
بسته به آنچه می خواهید مدل سازی کنید.

موقعیت های مشابه می تواند در بسیاری از مکان ها رخ دهد ns-3 و در هر شبیه ساز. مثلا،
ممکن است بتوانید گره ها را به گونه ای قرار دهید که فضای یکسانی را در آن اشغال کنند
در همان زمان، یا ممکن است بتوانید تقویت کننده ها یا سطوح نویز را پیکربندی کنید که این موارد را نقض می کند
قوانین اساسی فیزیک

ns-3 به طور کلی از انعطاف پذیری حمایت می کند و بسیاری از مدل ها اجازه تنظیم آزادانه را می دهند خواص
بدون تلاش برای اعمال هرگونه سازگاری دلخواه یا مشخصات زیربنایی خاص.

چیزی که باید از این به خانه برد این است که ns-3 قرار است یک پایگاه فوق العاده انعطاف پذیر ارائه دهد
برای شما برای آزمایش این به شما بستگی دارد که بفهمید از سیستم چه می‌خواهید
انجام دهید و مطمئن شوید که شبیه‌سازی‌هایی که ایجاد می‌کنید دارای معنی و مقداری هستند
ارتباط با واقعیتی که توسط شما تعریف شده است.

بنا a بي سيم شبکه ارتباطی توپولوژی
در این بخش می‌خواهیم دانش خود را بیشتر گسترش دهیم ns-3 دستگاه های شبکه و
کانال هایی برای پوشش نمونه ای از شبکه های بی سیم. ns-3 مجموعه ای از مدل های 802.11 را ارائه می دهد
که سعی در ارائه یک پیاده سازی دقیق در سطح MAC از مشخصات 802.11 دارند
و یک مدل "نه چندان کند" در سطح PHY با مشخصات 802.11a.

همانطور که ما اشیاء کمکی توپولوژی نقطه به نقطه و CSMA را دیدیم
با ساخت توپولوژی های نقطه به نقطه، معادل آن را خواهیم دید فای کمک های توپولوژی در
این بخش. ظاهر و عملکرد این کمک کننده ها باید کاملا آشنا به نظر برسد
شما خواهد شد.

ما یک نمونه اسکریپت را در خود ارائه می دهیم نمونه ها/آموزش فهرست راهنما. این اسکریپت ساخته شده است
la second.cc اسکریپت و یک شبکه Wifi اضافه می کند. برو جلو و باز کن
examples/tutorial/third.cc در ویرایشگر مورد علاقه شما شما قبلاً به اندازه کافی دیده اید
ns-3 کد برای درک بیشتر آنچه در این مثال می گذرد، اما چند مورد جدید وجود دارد
چیزها، بنابراین ما کل اسکریپت را مرور می کنیم و برخی از خروجی ها را بررسی می کنیم.

درست همانطور که در second.cc مثال (و در کل ns-3 مثال) فایل با emacs شروع می شود
خط حالت و مقداری دیگ بخار GPL.

به هنر ASCII (که در زیر بازتولید شده است) که توپولوژی شبکه پیش فرض را نشان می دهد، نگاهی بیندازید
در مثال ساخته شده است. می بینید که ما قصد داریم مثال خود را بیشتر گسترش دهیم
با آویزان کردن یک شبکه بی سیم از سمت چپ. توجه داشته باشید که این یک شبکه پیش فرض است
توپولوژی از آنجایی که در واقع می توانید تعداد گره های ایجاد شده روی سیم و بی سیم را تغییر دهید
شبکه های. درست همانطور که در second.cc مورد اسکریپت، اگر تغییر دهید nCsma، آن را به شما می دهد
تعداد گره های "اضافی" CSMA. به طور مشابه، می توانید تنظیم کنید nWifi برای کنترل چند S
(ایستگاه) گره ها در شبیه سازی ایجاد می شوند. همیشه یکی وجود خواهد داشت AP (نقطه دسترسی)
گره در شبکه بی سیم به طور پیش فرض سه گره CSMA "اضافی" و سه گره وجود دارد
بي سيم S گره ها

کد با بارگیری ماژول شامل فایل‌ها همانطور که در آن انجام شد شروع می‌شود second.cc مثال.
چند مورد جدید مربوط به ماژول Wifi و قابلیت حرکت وجود دارد
ماژول که در ادامه به آن خواهیم پرداخت.

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

تصویر توپولوژی شبکه به شرح زیر است:

// توپولوژی شبکه پیش فرض
//
// Wifi 10.1.3.0
// AP
// * * * *
// | | | | 10.1.1.0
// n5 n6 n7 n0 -------------- n1 n2 n3 n4
// نقطه به نقطه | | | |
// =================
// LAN 10.1.2.0

می بینید که ما یک دستگاه شبکه جدید را به گره سمت چپ اضافه می کنیم
پیوند نقطه به نقطه که به نقطه دسترسی شبکه بی سیم تبدیل می شود. تعدادی از
گره های STA بی سیم برای پر کردن شبکه جدید 10.1.3.0 همانطور که در سمت چپ نشان داده شده است ایجاد می شوند
سمت تصویر

بعد از تصویر، ns-3 فضای نام است استفاده و یک جزء لاگ تعریف شده است.
همه اینها تا به حال کاملاً آشنا هستند.

با استفاده از فضای نام ns3;

NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample")؛

برنامه اصلی درست مثل شروع می شود second.cc با افزودن برخی از پارامترهای خط فرمان برای
فعال یا غیرفعال کردن اجزای گزارش و تغییر تعداد دستگاه های ایجاد شده.

bool verbose = درست;
uint32_t nCsma = 3;
uint32_t nWifi = 3;

CommandLine cmd;
cmd.AddValue ("nCsma"، "تعداد گره ها/دستگاه های \"اضافی" CSMA، nCsma);
cmd.AddValue ("nWifi"، "تعداد دستگاه های wifi STA"، nWifi)؛
cmd.AddValue ("مطمئن"، "به برنامه های کاربردی پژواک برای ورود به سیستم اگر درست است"، پرمخاطب);

cmd.Parse (argc,argv);

اگر (پرمخاطب)
{
LogComponentEnable("UdpEchoClientApplication"، LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication"، LOG_LEVEL_INFO);
}

درست مانند تمام مثال های قبلی، مرحله بعدی ایجاد دو گره است که می خواهیم
از طریق پیوند نقطه به نقطه متصل شوید.

NodeContainer p2pNodes;
p2pNodes.Create (2);

بعد، یک دوست قدیمی را می بینیم. الف را نمونه می کنیم PointToPointHelper و مربوط را تنظیم کنید
به طور پیش فرض خواص به طوری که یک فرستنده پنج مگابیت در ثانیه بر روی دستگاه ها ایجاد می کنیم
ایجاد شده با استفاده از کمک کننده و تاخیر دو میلی ثانیه ای در کانال های ایجاد شده توسط کمک کننده.
ما پس از آن نصبی دستگاه های روی گره ها و کانال بین آنها.

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("تاخیر"، StringValue ("2 میلی ثانیه"));

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

بعد، دیگری را اعلام می کنیم NodeContainer برای نگه داشتن گره هایی که بخشی از گذرگاه خواهند بود
شبکه (CSMA)

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

خط بعدی کد می شود اولین گره (مانند داشتن شاخص یک) از
ظرف گره نقطه به نقطه و آن را به ظرف گره هایی که CSMA دریافت می کنند اضافه می کند
دستگاه ها گره مورد نظر به یک دستگاه نقطه به نقطه و یک CSMA ختم می شود
دستگاه سپس تعدادی گره "اضافی" ایجاد می کنیم که بقیه CSMA را تشکیل می دهند
شبکه می باشد.

سپس a را نمونه می کنیم CsmaHelper و آن را تنظیم کنید خواص همانطور که در مثال قبلی انجام دادیم.
ما ایجاد می کنیم NetDeviceContainer برای پیگیری دستگاه های شبکه CSMA ایجاد شده و سپس ما
نصب دستگاه های CSMA در گره های انتخاب شده.

CsmaHelper csma;
csma.SetChannelAttribute ("DataRate"، StringValue ("100Mbps"));
csma.SetChannelAttribute ("تاخیر"، TimeValue (NanoSeconds (6560)));

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

در مرحله بعد، ما می خواهیم گره هایی را ایجاد کنیم که بخشی از شبکه Wifi خواهند بود. ما هستیم
قصد داریم تعدادی گره "ایستگاه" را همانطور که توسط آرگومان خط فرمان مشخص شده است ایجاد کنیم، و
ما قصد داریم از "سمت چپ ترین" گره پیوند نقطه به نقطه به عنوان گره برای آن استفاده کنیم
نقطه دسترسی.

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

بیت بعدی کد دستگاه های وای فای و کانال ارتباطی بین آن ها را می سازد
این گره های فای ابتدا PHY و کمک کننده های کانال را پیکربندی می کنیم:

YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::پیش فرض ();

برای سادگی، این کد از پیکربندی لایه پیش فرض PHY و مدل های کانال استفاده می کند
که در مستندات API doxygen برای
YansWifiChannelHelper::پیش فرض و YansWifiPhyHelper::پیش فرض مواد و روش ها. یک بار این اشیاء
ایجاد می شود، یک شی کانال ایجاد می کنیم و آن را به مدیر شی لایه PHY خود مرتبط می کنیم
برای اطمینان از اینکه تمام اشیاء لایه PHY ایجاد شده توسط YansWifiPhyHelper به اشتراک گذاری
همان کانال زیربنایی، یعنی آنها از یک رسانه بی سیم و می توانند استفاده می کنند
ارتباط و دخالت:

phy.SetChannel (channel.Create ());

هنگامی که PHY helper پیکربندی شد، می‌توانیم روی لایه MAC تمرکز کنیم. در اینجا ما کار را انتخاب می کنیم
با MAC های غیرQos، بنابراین از یک شی NqosWifiMacHelper برای تنظیم پارامترهای MAC استفاده می کنیم.

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

NqosWifiMacHelper mac = NqosWifiMacHelper::پیش فرض ();

La SetRemoteStationManager روش به کمک کننده نوع الگوریتم کنترل نرخ را می گوید
استفاده کنید. در اینجا، از کمک کننده می خواهد که از الگوریتم AARF استفاده کند --- البته جزئیات عبارتند از:
موجود در داکسیژن

سپس، نوع MAC، SSID شبکه زیرساختی را که می‌خواهیم پیکربندی کنیم
راه اندازی کنید و مطمئن شوید که ایستگاه های ما کاوش فعال را انجام نمی دهند:

Ssid ssid = Ssid ("ns-3-ssid");
mac.SetType ("ns3::StaWifiMac"،
"Ssid"، SsidValue (ssid)،
"ActiveProbing"، BooleanValue (نادرست));

این کد ابتدا یک شیء شناسه مجموعه سرویس (SSID) 802.11 ایجاد می کند که مورد استفاده قرار خواهد گرفت.
برای تنظیم مقدار "Ssid" صفت اجرای لایه MAC خاص
نوع لایه MAC که توسط کمک کننده ایجاد می شود توسط مشخص می شود صفت به عنوان بودن از
نوع "ns3::StaWifiMac". استفاده از NqosWifiMacHelper اطمینان حاصل خواهد کرد که
"QosSupported" صفت برای اشیاء MAC ایجاد شده false تنظیم شده است. ترکیب اینها
دو پیکربندی به این معنی است که نمونه MAC ایجاد شده بعدی یک غیر QoS غیر AP خواهد بود
ایستگاه (STA) در یک زیرساخت BSS (یعنی یک BSS با یک AP). در نهایت،
"ActiveProbing" صفت روی false تنظیم شده است. این به این معنی است که درخواست های کاوشگر وجود نخواهد داشت
ارسال شده توسط MAC های ایجاد شده توسط این کمک کننده.

هنگامی که تمام پارامترهای خاص ایستگاه به طور کامل پیکربندی شدند، هم در MAC و هم در PHY
لایه‌ها، می‌توانیم اکنون آشنای خود را فراخوانی کنیم نصب روشی برای ایجاد دستگاه های فای اینها
ایستگاه ها:

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

ما Wifi را برای تمام گره های STA خود پیکربندی کرده ایم و اکنون باید AP را پیکربندی کنیم.
(نقطه دسترسی) گره. ما این فرآیند را با تغییر پیش فرض آغاز می کنیم خواص از
NqosWifiMacHelper برای منعکس کردن الزامات AP.

mac.SetType ("ns3::ApWifiMac"،
"Ssid"، SsidValue (ssid))؛

در این مورد، NqosWifiMacHelper قرار است لایه های MAC "ns3::ApWifiMac" را ایجاد کند،
دومی مشخص می کند که یک نمونه MAC پیکربندی شده به عنوان یک AP باید ایجاد شود، با
نوع کمکی که به این معنی است که "QosSupported" صفت باید روی false تنظیم شود - غیرفعال کردن
پشتیبانی QoS به سبک 802.11e/WMM در APهای ایجاد شده.

خطوط بعدی یک AP منفرد را ایجاد می کند که مجموعه ای از سطح PHY را به اشتراک می گذارد خواص
کانال) به عنوان ایستگاه های:

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

اکنون، ما می خواهیم مدل های تحرک را اضافه کنیم. ما می خواهیم گره های STA متحرک و سرگردان باشند
در داخل یک جعبه مرزی، و ما می خواهیم گره AP را ثابت کنیم. ما استفاده می کنیم
MobilityHelper تا این کار را برای ما آسان کند. ابتدا a را نمونه می کنیم MobilityHelper هدف
و مقداری تنظیم کنید خواص کنترل عملکرد "تخصیص دهنده موقعیت".

MobilityHelper mobility;

mobility.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"))؛

این کد به کمک کننده تحرک می گوید که از یک شبکه دو بعدی برای قرار دادن در ابتدا استفاده کند
گره های STA به راحتی می توانید Doxygen را برای کلاس کشف کنید ns3::GridPositionAllocator برای دیدن
دقیقاً آنچه در حال انجام است

ما گره های خود را روی یک شبکه اولیه مرتب کرده ایم، اما اکنون باید به آنها بگوییم که چگونه حرکت کنند.
ما انتخاب می کنیم RandomWalk2dMobilityModel که گره ها در جهت تصادفی حرکت می کنند
سرعت تصادفی در داخل یک جعبه مرزی.

mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel"،
"Bounds"، RectangleValue (Rectangle (-50، 50، -50، 50)));

ما اکنون به آن می گوییم MobilityHelper برای نصب مدل های تحرک روی گره های STA.

mobility.Install (wifiStaNodes)؛

ما می خواهیم نقطه دسترسی در طول شبیه سازی در یک موقعیت ثابت باقی بماند. ما
این کار را با تنظیم مدل تحرک برای این گره انجام دهید
ns3::ConstantPositionMobilityModel:

mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode)؛

ما اکنون گره‌ها، دستگاه‌ها و کانال‌های خود را ایجاد کرده‌ایم و مدل‌های تحرک را برای آن انتخاب کرده‌ایم
گره های فای، اما ما هیچ پشته پروتکلی نداریم. همانطور که قبلاً بسیاری از آنها را انجام داده ایم
بارها، از آن استفاده خواهیم کرد InternetStackHelper برای نصب این پشته ها

پشته InternetStackHelper;
stack.install (csmanodes) ؛
stack.Install (wifiApNode);
stack.Install (wifiStaNodes);

درست همانطور که در second.cc اسکریپت مثال، ما قصد داریم از IPv4AddressHelper به
آدرس های IP را به رابط های دستگاه خود اختصاص دهید. ابتدا از شبکه 10.1.1.0 برای ایجاد استفاده می کنیم
دو آدرس مورد نیاز برای دو دستگاه نقطه به نقطه ما. سپس از شبکه 10.1.2.0 استفاده می کنیم
برای تخصیص آدرس ها به شبکه CSMA و سپس آدرس هایی را از شبکه 10.1.3.0 اختصاص می دهیم.
به هر دو دستگاه STA و AP در شبکه بی سیم.

آدرس Ipv4AddressHelper;

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

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

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

ما سرور اکو را روی "راست ترین" گره در تصویر در ابتدای شروع قرار دادیم
فایل. ما قبلا این کار را انجام داده ایم.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (ثانیه (1.0))؛
serverApps.Stop (ثانیه (10.0))؛

و ما echo client را روی آخرین گره STA که ایجاد کردیم قرار می دهیم و آن را به سروری که در آن قرار دارد اشاره می کنیم
شبکه CSMA ما قبلاً نیز شاهد عملیات مشابه بودیم.

UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma)، 9);
echoClient.SetAttribute ("MaxPackets"، UintegerValue (1));
echoClient.SetAttribute ("Interval"، TimeValue (ثانیه (1.0)));
echoClient.SetAttribute ("PacketSize"، UintegerValue (1024));

ApplicationContainer clientApps =
echoClient.Install (wifiStaNodes.Get (nWifi - 1));
clientApps.Start (ثانیه (2.0));
clientApps.Stop (ثانیه (10.0));

از آنجایی که ما در اینجا یک اینترنت ورک ساخته‌ایم، باید مسیریابی اینترنت را نیز به همان اندازه فعال کنیم
ما در second.cc اسکریپت نمونه

Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

یکی از چیزهایی که می تواند برخی از کاربران را شگفت زده کند این واقعیت است که شبیه سازی ما به تازگی ایجاد کرده ایم
هرگز "طبیعی" متوقف نخواهد شد. این به این دلیل است که ما از نقطه دسترسی بی سیم خواسته ایم
تولید فانوس دریایی این چراغ‌ها را برای همیشه تولید می‌کند، و این منجر به شبیه‌ساز می‌شود
رویدادهایی که در آینده به طور نامحدود برنامه ریزی می شوند، بنابراین باید به شبیه ساز بگوییم که متوقف شود
حتی اگر ممکن است رویدادهای نسل فانوس دریایی برنامه ریزی شده باشد. خط کد زیر
به شبیه ساز می گوید که متوقف شود تا برای همیشه بیکن ها را شبیه سازی نکنیم و وارد آنچه هست شویم
در اصل یک حلقه بی پایان

شبیه ساز::توقف (ثانیه (10.0))؛

ما ردیابی کافی برای پوشش هر سه شبکه ایجاد می کنیم:

pointToPoint.EnablePcapAll ("سوم");
phy.EnablePcap ("سوم"، apDevices.Get (0));
csma.EnablePcap ("سوم"، csmaDevices.Get (0)، true);

این سه خط کد ردیابی pcap را در هر دو گره نقطه به نقطه شروع می کند
به عنوان ستون فقرات ما عمل می کند، یک ردیابی حالت بی رویه (مانیتور) را در شبکه Wifi شروع می کند،
و یک ردیابی بی‌وقفه در شبکه CSMA آغاز می‌کند. این به ما امکان می دهد همه موارد را ببینیم
ترافیک با حداقل تعداد فایل های ردیابی

در نهایت، ما در واقع شبیه سازی را اجرا می کنیم، پاک می کنیم و سپس از برنامه خارج می شویم.

شبیه ساز::Run ();
شبیه ساز::Destroy ();
0 بازگشت؛
}

برای اجرای این مثال، باید آن را کپی کنید سوم.سی سی نمونه اسکریپت در
دایرکتوری را خراش دهید و از Waf برای ساختن همان کاری که با آن انجام دادید استفاده کنید second.cc مثال. اگر شما
در دایرکتوری سطح بالای مخزنی هستند که باید تایپ کنید،

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

باز هم، از آنجایی که ما برنامه های UDP echo را درست همانطور که در آن انجام دادیم، راه اندازی کرده ایم second.cc
اسکریپت، خروجی مشابهی خواهید دید.

Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.407s)
در زمان 2s کلاینت 1024 بایت به پورت 10.1.2.4 9 ارسال کرد
در زمان 2.01796s سرور 1024 بایت از پورت 10.1.3.3 49153 دریافت کرد.
در زمان 2.01796s سرور 1024 بایت را به پورت 10.1.3.3 49153 ارسال کرد.
در زمان 2.03364s کلاینت 1024 بایت از پورت 10.1.2.4 9 دریافت کرد.

به یاد بیاورید که اولین پیام، ارسال شد 1024 بایت به 10.1.2.4"، سرویس گیرنده اکو UDP است
ارسال یک بسته به سرور در این حالت کلاینت در شبکه بی سیم است
(10.1.3.0). پیام دوم، "دریافتی 1024 بایت از جانب 10.1.3.3"از پژواک UDP است
سرور، زمانی که بسته اکو را دریافت می کند، ایجاد می شود. پیام پایانی، "دریافتی 1024
بایت از جانب 10.1.2.4" از مشتری echo است، که نشان می دهد اکو خود را دریافت کرده است
برگشت از سرور

اگر اکنون بروید و به فهرست راهنمای سطح بالا نگاه کنید، چهار فایل ردیابی از آنها را پیدا خواهید کرد
این شبیه سازی، دو از گره صفر و دو از گره یک:

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

فایل "third-0-0.pcap" مربوط به دستگاه نقطه به نقطه در گره صفر است --
سمت چپ "ستون فقرات". فایل "third-1-0.pcap" مربوط به نقطه به نقطه است
دستگاه در گره یک -- سمت راست "ستون فقرات". فایل "third-0-1.pcap" خواهد بود
ردیابی نامناسب (حالت مانیتور) از شبکه Wifi و فایل "third-1-1.pcap"
ردیابی بی‌وقفه از شبکه CSMA خواهد بود. آیا می توانید با بررسی این موضوع را تأیید کنید
کد؟

از آنجایی که مشتری echo در شبکه Wifi است، بیایید از آنجا شروع کنیم. بیایید نگاهی به
ردی بی‌وقفه (حالت مانیتور) که ما در آن شبکه گرفتیم.

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

باید برخی از محتویات وای فای را ببینید که قبلاً در اینجا ندیده اید:

خواندن از فایل third-0-1.pcap، نوع پیوند 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 مگابیت] IBSS
0.000308 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 مگابیت]
0.000324 Acknowledgment RA:00:00:00:00:00:08
0.000402 Assoc Response کمک(0) :: موفق
0.000546 Acknowledgment RA:00:00:00:00:00:0a
0.000721 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 مگابیت]
0.000737 Acknowledgment RA:00:00:00:00:00:07
0.000824 Assoc Response کمک(0) :: موفق
0.000968 Acknowledgment RA:00:00:00:00:00:0a
0.001134 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 مگابیت]
0.001150 Acknowledgment RA:00:00:00:00:00:09
0.001273 Assoc Response کمک(0) :: موفق
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 مگابیت] IBSS
0.204800 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 مگابیت] IBSS
0.307200 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 مگابیت] IBSS

می توانید ببینید که نوع پیوند اکنون همانطور که انتظار دارید 802.11 است. شما احتمالا می توانید
درک کنید که چه اتفاقی می افتد و بسته های درخواست اکو و پاسخ IP را در این مورد بیابید
پی گیری. ما آن را به عنوان تمرینی برای تجزیه کامل ردپایی رها می کنیم.

اکنون به فایل pcap سمت راست پیوند نقطه به نقطه نگاه کنید.

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

باز هم، باید برخی از مطالب آشنا را ببینید:

خواندن از فایل III-0-0.pcap، نوع پیوند PPP (PPP)
2.008151 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP، طول 1024
2.026758 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP، طول 1024

این بسته پژواک است که از چپ به راست (از Wifi به CSMA) می رود و دوباره به سمت راست برمی گردد
لینک نقطه به نقطه

اکنون به فایل pcap سمت راست پیوند نقطه به نقطه نگاه کنید.

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

باز هم، باید برخی از مطالب آشنا را ببینید:

خواندن از فایل III-1-0.pcap، نوع پیوند PPP (PPP)
2.011837 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP، طول 1024
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP، طول 1024

این نیز بسته اکو است که از چپ به راست (از Wifi به CSMA) و دوباره برمی گردد
در سراسر پیوند نقطه به نقطه با زمان بندی کمی متفاوت همانطور که ممکن است انتظار داشته باشید.

سرور اکو در شبکه CSMA است، بیایید به ردیابی بی‌وقفه در آنجا نگاه کنیم:

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

شما باید برخی از مطالب آشنا را ببینید:

خواندن از فایل III-1-1.pcap، نوع پیوند EN10MB (اترنت)
2.017837 ARP، درخواست who-has 10.1.2.4 (ff:ff:ff:ff:ff:ff) به 10.1.2.1، طول 50 بگویید
2.017861 ARP، پاسخ 10.1.2.4 is-at 00:00:00:00:00:06، طول 50
2.017861 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP، طول 1024
2.022966 ARP، درخواست who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) به 10.1.2.4، طول 50 بگویید
2.022966 ARP، پاسخ 10.1.2.1 is-at 00:00:00:00:00:03، طول 50
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP، طول 1024

این را باید به راحتی درک کرد. اگر فراموش کرده اید، برگردید و به بحث نگاه کنید
in second.cc. این همان دنباله است.

اکنون، ما زمان زیادی را صرف تنظیم مدل‌های متحرک برای شبکه‌های بی‌سیم و غیره کردیم
خجالت آور است که کار را بدون حتی نشان دادن اینکه گره های STA واقعاً در حال حرکت هستند به پایان برسانیم
در حین شبیه سازی بیایید این کار را با اتصال به آن انجام دهیم MobilityModel دوره
تغییر منبع ردیابی این فقط نگاهی گذرا به بخش ردیابی دقیق است که در آن وجود دارد
در راه است، اما این مکان بسیار خوبی برای مثال زدن به نظر می رسد.

همانطور که در بخش "Tweaking ns-3" ذکر شد، ns-3 سیستم ردیابی به ردیابی تقسیم می شود
منابع و ردیابی سینک ها، و ما توابعی را برای اتصال این دو ارائه می دهیم. ما استفاده خواهیم کرد
مدل تحرک از پیش تعریف شده منبع ردیابی تغییر مسیر برای منشأ رویدادهای ردیابی. ما
برای اتصال به آن منبع باید یک سینک ردیابی بنویسید تا کمی زیبا نمایش داده شود
اطلاعات برای ما علیرغم شهرت آن به عنوان دشوار بودن، واقعاً بسیار ساده است.
درست قبل از برنامه اصلی از scratch/mythird.cc اسکریپت (یعنی درست بعد از
NS_LOG_COMPONENT_DEFINE بیانیه)، تابع زیر را اضافه کنید:

از درجه اعتبار ساقط
CourseChange (std::string context، Ptr مدل)
{
موقعیت برداری = model->GetPosition ();
NS_LOG_UNCOND (زمینه <
" x = " << position.x << ", y = " << position.y);
}

این کد فقط اطلاعات موقعیت را از مدل تحرک و بدون قید و شرط بیرون می کشد
موقعیت x و y گره را ثبت می کند. ما می خواهیم ترتیبی دهیم که این تابع باشد
هر بار که گره بی سیم با کلاینت اکو موقعیت خود را تغییر می دهد، فراخوانی می شود. ما این کار را انجام می دهیم
با استفاده از پیکربندی::اتصال عملکرد. فقط خطوط کد زیر را به اسکریپت اضافه کنید
قبل از شبیه ساز::اجرا کنید زنگ زدن.

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

پیکربندی::اتصال (oss.str ()، MakeCallback (&CourseChange));

کاری که ما در اینجا انجام می دهیم این است که یک رشته حاوی مسیر فضای نام ردیابی رویداد ایجاد کنیم
که می خواهیم به آن وصل شویم. ابتدا باید بفهمیم که از کدام گره می خواهیم استفاده کنیم
la GetId روش همانطور که قبلا توضیح داده شد. در مورد شماره پیش فرض CSMA و
گره های بی سیم، مشخص می شود که این گره هفت و مسیر فضای نام ردیابی به سمت است
مدل تحرک به نظر می رسد،

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

بر اساس بحث در بخش ردیابی، ممکن است استنباط کنید که این مسیر ردیابی است
به هفتمین گره در NodeList جهانی اشاره می کند. مشخص می کند که چه چیزی را an نامیده می شود
شیء تجمیع شده از نوع ns3::MobilityModel. پیشوند علامت دلار نشان می دهد که
MobilityModel به گره هفت تجمیع می شود. آخرین جزء مسیر یعنی ما
به رویداد "CourseChange" آن مدل متصل می شوند.

ما با فراخوانی بین منبع ردیابی در گره هفت با trace sink خود ارتباط برقرار می کنیم
پیکربندی::اتصال و عبور از این مسیر فضای نام. پس از انجام این کار، هر دوره تغییر می کند
رویداد در گره هفت به سینک ردیابی ما قلاب می‌شود، که به نوبه خود آن را چاپ می‌کند
موقعیت جدید

اگر اکنون شبیه سازی را اجرا کنید، تغییرات دوره را به محض وقوع مشاهده خواهید کرد.

"ساخت" با موفقیت به پایان رسید (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
در زمان 2s کلاینت 1024 بایت به پورت 10.1.2.4 9 ارسال کرد
در زمان 2.01796s سرور 1024 بایت از پورت 10.1.3.3 49153 دریافت کرد.
در زمان 2.01796s سرور 1024 بایت را به پورت 10.1.3.3 49153 ارسال کرد.
در زمان 2.03364s کلاینت 1024 بایت از پورت 10.1.2.4 9 دریافت کرد.
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.3273، y = 4.04175
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.013، y = 4.76955
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.4317، y = 5.67771
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.4607، y = 5.91681
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.0155، y = 6.74878
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.0076، y = 6.62336
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.6285، y = 5.698
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.32، y = 4.97559
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.1134، y = 3.99715
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.8359، y = 4.68851
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.5953، y = 3.71789
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.7595، y = 4.26688
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.7629، y = 4.34913
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.2292، y = 5.19485
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2344، y = 5.09394
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.3601، y = 4.60846
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.40025، y = 4.32795
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.14292، y = 4.99761
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.08299، y = 5.99581
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.26068، y = 5.42677
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.35917، y = 6.42191
/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.66805، y = 7.14466
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.71414، y = 6.84456
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.42489، y = 7.80181

ردیابی


زمینه
همانطور که در UsingTracingSystem ذکر شد، کل نکته اجرای an ns-3 شبیه سازی به است
تولید خروجی برای مطالعه شما دو استراتژی اساسی برای به دست آوردن خروجی دارید ns-3:
با استفاده از مکانیزم های عمومی از پیش تعریف شده خروجی فله و تجزیه محتوای آنها برای استخراج
اطلاعات جالب؛ یا به نوعی در حال توسعه مکانیزم خروجی است که دقیقاً انتقال می دهد
(و شاید فقط) اطلاعات مورد نظر.

استفاده از مکانیزم های از پیش تعریف شده خروجی حجیم این مزیت را دارد که نیازی به تغییر ندارد
ns-3، اما ممکن است نیاز به نوشتن اسکریپت برای تجزیه و فیلتر کردن داده های مورد علاقه داشته باشد. غالبا،
PCAP یا NS_LOG پیام های خروجی در طول اجرای شبیه سازی جمع آوری شده و به طور جداگانه اجرا می شوند
از طریق اسکریپت هایی که استفاده می کنند grep استفاده, SED or بیدار برای تجزیه پیام ها و کاهش و تبدیل
داده ها به یک فرم قابل مدیریت برنامه ها باید نوشته شوند تا تحول انجام شود، بنابراین این
رایگان نمی آید NS_LOG خروجی بخشی از در نظر گرفته نمی شود ns-3 API و can
بدون اخطار بین نسخه ها تغییر دهید. علاوه بر این، NS_LOG خروجی فقط در دسترس است
اشکال زدایی ایجاد می شود، بنابراین تکیه بر آن جریمه عملکردی را اعمال می کند. البته اگر
اطلاعات مورد علاقه در هیچ یک از مکانیسم های خروجی از پیش تعریف شده وجود ندارد
رویکرد شکست می خورد

اگر شما نیاز به اضافه کردن مقداری اطلاعات به مکانیسم‌های از پیش تعریف‌شده انبوه دارید، می‌توانید
قطعا انجام شود؛ و در صورت استفاده از یکی از ns-3 مکانیزم، ممکن است کد خود را اضافه کنید
به عنوان کمک

ns-3 مکانیسم دیگری به نام Tracing را ارائه می دهد که از برخی مشکلات ذاتی جلوگیری می کند
در مکانیزم های خروجی عمده چندین مزیت مهم دارد. اول، شما می توانید
تنها با ردیابی رویدادهای مورد علاقه خود، حجم داده هایی را که باید مدیریت کنید کاهش دهید
(برای شبیه سازی های بزرگ، ریختن همه چیز به دیسک برای پردازش پس از پردازش می تواند I/O ایجاد کند
تنگناها). دوم اینکه در صورت استفاده از این روش می توانید فرمت خروجی را کنترل کنید
به طور مستقیم، بنابراین شما از مرحله پس پردازش با SED, بیدار, پرل or پایتون اسکریپت ها اگر
می‌خواهید، خروجی شما می‌تواند مستقیماً به شکلی که توسط gnuplot قابل قبول است، فرمت شود
مثال (همچنین به GnuplotHelper مراجعه کنید). شما می توانید قلاب هایی را در هسته اضافه کنید که پس از آن می توانید
توسط سایر کاربران قابل دسترسی است، اما هیچ اطلاعاتی تولید نمی کند مگر اینکه صریحاً از آن خواسته شود
انجام دهید. به این دلایل، ما معتقدیم که ns-3 سیستم ردیابی بهترین راه برای به دست آوردن است
اطلاعات خارج از یک شبیه سازی و همچنین یکی از مکانیسم های مهم است
برای درک در ns-3.

بی پرده ابزار
راه های زیادی برای دریافت اطلاعات از یک برنامه وجود دارد. سرراست ترین راه این است
برای چاپ مستقیم اطلاعات در خروجی استاندارد، مانند:

#عبارتند از
...
از درجه اعتبار ساقط
SomeFunction (باطل)
{
uint32_t x = SOME_INTERESTING_VALUE؛
...
std::cout << "مقدار x " << x << std::endl;
...
}

هیچ کس نمی تواند شما را از رفتن به هسته اصلی باز دارد ns-3 و اضافه کردن چاپ
بیانیه. انجام این کار بسیار آسان است و بعد از همه، شما کنترل کامل خود را دارید
خود ns-3 شاخه. این احتمالاً در دراز مدت چندان رضایت بخش نخواهد بود
هر چند مدت

با افزایش تعداد بیانیه های چاپی در برنامه های شما، وظیفه مقابله با
تعداد زیادی از خروجی ها پیچیده تر و پیچیده تر خواهند شد. در نهایت، ممکن است احساس کنید
نیاز به کنترل اطلاعاتی که به نوعی چاپ می شود، شاید با روشن کردن
و دسته‌های خاصی از چاپ‌ها را کاهش دهید یا مقدار آن را افزایش یا کاهش دهید
اطلاعاتی که می خواهید اگر این مسیر را ادامه دهید، ممکن است متوجه شوید که دارید
را دوباره اجرا کرد NS_LOG مکانیسم (به استفاده از ورود به سیستم مراجعه کنید). به منظور اجتناب از آن، یکی از
اولین چیزی که ممکن است در نظر بگیرید استفاده از آن است NS_LOG خود.

در بالا اشاره کردیم که یکی از راه های بدست آوردن اطلاعات از آن است ns-3 تجزیه موجود است NS_LOG
خروجی برای اطلاعات جالب اگر متوجه شوید که برخی از اطلاعات شما
نیاز در خروجی لاگ موجود وجود ندارد، می توانید هسته آن را ویرایش کنید ns-3 و به سادگی اضافه کنید
اطلاعات جالب شما به جریان خروجی. در حال حاضر، این قطعا بهتر از
از آنجایی که در ادامه آمده است، اظهارات چاپی خود را اضافه کنید ns-3 قراردادهای کدگذاری و می تواند
به طور بالقوه برای افراد دیگر به عنوان یک وصله به هسته موجود مفید باشد.

بیایید یک مثال تصادفی انتخاب کنیم. اگر می‌خواهید ورود به سیستم را اضافه کنید ns-3 سوکت TCP
(tcp-socket-base.cc) فقط می توانید یک پیام جدید در پیاده سازی اضافه کنید. اطلاع
که در TcpSocketBase::ReceivedAck() هیچ پیام گزارشی برای مورد no ACK وجود ندارد. شما
به سادگی می توان یکی را اضافه کرد و کد را تغییر داد. اینم اصلش:

/** پردازش ACK تازه دریافت شده */
از درجه اعتبار ساقط
TcpSocketBase::ReceivedAck (Ptr بسته، const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION (این << tcpHeader)؛

// ACK دریافت کرد. عدد ACK را با بالاترین seqno تایید نشده مقایسه کنید
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // در صورت عدم وجود پرچم ACK نادیده بگیرید
}
...

برای ورود به پرونده no ACK، می توانید یک مورد جدید اضافه کنید NS_LOG_LOGIC در if بدنه بیانیه:

/** پردازش ACK تازه دریافت شده */
از درجه اعتبار ساقط
TcpSocketBase::ReceivedAck (Ptr بسته، const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION (این << tcpHeader)؛

// ACK دریافت کرد. عدد ACK را با بالاترین seqno تایید نشده مقایسه کنید
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // در صورت عدم وجود پرچم ACK نادیده بگیرید
NS_LOG_LOGIC ("TcpSocketBase" << این << "بدون پرچم ACK");
}
...

این ممکن است در نگاه اول نسبتاً ساده و رضایت بخش به نظر برسد، اما چیزی که باید در نظر گرفت این است
که برای اضافه کردن کد می نویسید NS_LOG بیانیه ها و شما همچنین باید بنویسید
کد (مانند grep استفاده, SED or بیدار اسکریپت ها) برای تجزیه خروجی ورود به سیستم به منظور جداسازی شما
اطلاعات این به این دلیل است که حتی اگر شما کنترلی بر آنچه که توسط خروجی می‌دهد دارید
سیستم ورود به سیستم، شما فقط تا سطح مؤلفه ورود به سیستم کنترل دارید، که معمولاً همینطور است
یک فایل کد منبع کامل

اگر در حال اضافه کردن کد به یک ماژول موجود هستید، باید با خروجی نیز زندگی کنید
که هر توسعه دهنده دیگری آن را جالب می داند. شما ممکن است آن را برای به دست آوردن آن پیدا کنید
مقدار کمی از اطلاعاتی که نیاز دارید، ممکن است مجبور شوید مقدار زیادی از آن را رد کنید
پیام های خارجی که هیچ علاقه ای به شما ندارند. ممکن است مجبور شوید سیاهه های بزرگ را ذخیره کنید
فایل ها را روی دیسک قرار دهید و هر زمان که می خواهید کاری انجام دهید آنها را تا چند خط پردازش کنید.

از آنجایی که هیچ تضمینی وجود ندارد ns-3 در مورد ثبات NS_LOG خروجی، شما نیز ممکن است
کشف کنید که قطعات خروجی ورود به سیستم که به آنها وابسته هستید ناپدید می شوند یا بین آنها تغییر می کنید
منتشر شده. اگر به ساختار خروجی بستگی دارید، ممکن است پیام های دیگری را پیدا کنید
اضافه یا حذف شده است که ممکن است بر کد تجزیه شما تأثیر بگذارد.

در نهایت، NS_LOG خروجی فقط در ساخت‌های اشکال‌زدایی موجود است، شما نمی‌توانید خروجی ورود را از آن دریافت کنید
ساخت‌های بهینه‌شده، که تقریباً دو برابر سریع‌تر اجرا می‌شوند. با تکیه بر NS_LOG عملکردی را تحمیل می کند
پنالتی

به این دلایل، ما چاپ را در نظر می گیریم std::out و NS_LOG پیام ها سریع و
راه های کثیف برای به دست آوردن اطلاعات بیشتر ns-3، اما برای کار جدی مناسب نیست.

داشتن یک تسهیلات پایدار با استفاده از APIهای پایدار که به فرد اجازه دسترسی به آن را می دهد، مطلوب است
سیستم اصلی و فقط اطلاعات مورد نیاز را دریافت کنید. مطلوب است که بتوانید انجام دهید
این بدون نیاز به تغییر و کامپایل مجدد سیستم اصلی. حتی بهتر از این خواهد بود
سیستمی که هنگام تغییر یک مورد مورد علاقه یا یک رویداد جالب، کد کاربر را مطلع می کند
این اتفاق افتاده است بنابراین کاربر مجبور نیست به طور فعال در سیستم جستجو کند
همه چیز.

La ns-3 سیستم ردیابی برای کار در این خطوط طراحی شده است و به خوبی با آن یکپارچه شده است
صفت و پیکربندی زیرسیستم هایی که امکان سناریوهای استفاده نسبتاً ساده را فراهم می کنند.

بررسی اجمالی
La ns-3 سیستم ردیابی بر اساس مفاهیم منابع ردیابی مستقل و
ردیابی سینک، همراه با مکانیزم یکنواخت برای اتصال منابع به سینک.

منابع ردیابی موجودیت هایی هستند که می توانند رویدادهایی را که در یک شبیه سازی اتفاق می افتد سیگنال دهند و ارائه دهند
دسترسی به داده های اساسی جالب به عنوان مثال، یک منبع ردیابی می تواند زمانی را نشان دهد که a
بسته توسط یک دستگاه شبکه دریافت می شود و امکان دسترسی به محتویات بسته را فراهم می کند
غرق ردیابی علاقه مند یک منبع ردیابی نیز ممکن است نشان دهد که چه زمانی یک حالت جالب است
تغییر در یک مدل اتفاق می افتد به عنوان مثال، پنجره تراکم یک مدل TCP یک عدد اول است
نامزد منبع ردیابی هر بار که پنجره تراکم تغییر می کند، ردیابی متصل است
سینک ها با ارزش قدیم و جدید مطلع می شوند.

منابع ردیابی به خودی خود مفید نیستند. آنها باید به کدهای دیگر متصل شوند
که در واقع با اطلاعات ارائه شده توسط منبع کار مفیدی انجام می دهند. در
موجودیت هایی که اطلاعات ردیابی را مصرف می کنند، ردیابی نامیده می شوند. منابع ردیابی هستند
مولدهای داده و ردیابی سینک مصرف کنندگان هستند. این تقسیم صریح به بزرگ اجازه می دهد
تعدادی از منابع ردیابی که در سراسر سیستم در مکان هایی که نویسندگان مدل هستند پراکنده شوند
باور کنید ممکن است مفید باشد درج منابع ردیابی یک اجرای بسیار کوچک را معرفی می کند
در بالای سر.

ممکن است صفر یا بیشتر مصرف کننده رویدادهای ردیابی تولید شده توسط یک منبع ردیابی وجود داشته باشد. یکنفر میتواند
منبع ردیابی را به عنوان نوعی پیوند اطلاعاتی نقطه به چند نقطه در نظر بگیرید. کد شما
به دنبال رویدادهای ردیابی از یک قطعه خاص از کد اصلی می‌توان با خوشحالی همزیستی کرد
کد دیگری که کاری کاملاً متفاوت از همان اطلاعات انجام می دهد.

تا زمانی که کاربر یک trace sink را به یکی از این منابع متصل نکند، هیچ چیزی خروجی نخواهد داشت. با استفاده از
سیستم ردیابی، هم شما و هم سایر افرادی که به یک منبع ردیابی متصل هستند، در حال دریافت هستید
دقیقاً همان چیزی را که آنها می خواهند و فقط آنچه را که از سیستم می خواهند. هیچ کدام از شما نیستید
با تغییر اطلاعات خروجی از سیستم، هر کاربر دیگری را تحت تأثیر قرار می دهد. اگر شما
اگر یک منبع ردیابی اضافه کنید، کار شما به عنوان یک شهروند منبع باز خوب ممکن است به دیگران اجازه دهد
کاربران ابزارهای جدیدی را ارائه دهند که شاید در مجموع بسیار مفید باشند، بدون اینکه هیچ کاری انجام دهند
تغییر در ns-3 هسته.

ساده مثال
اجازه دهید چند دقیقه وقت بگذاریم و یک مثال ساده ردیابی را مرور کنیم. ما نیاز داریم
پس زمینه کمی در مورد Callbacks برای درک آنچه در مثال اتفاق می افتد، بنابراین ما
باید فوراً یک مسیر انحرافی کوچک طی کنید.

پاسخگویی
هدف سیستم Callback در ns-3 اجازه دادن به یک کد برای فراخوانی یک تابع است
(یا روش در C++) بدون وابستگی بین ماژول خاصی. این در نهایت به این معنی است
شما به نوعی غیرمستقیم نیاز دارید -- شما آدرس تابع فراخوانده شده را به عنوان a در نظر می گیرید
متغیر. این متغیر را متغیر اشاره گر به تابع می نامند. رابطه
بین تابع و اشاره گر به تابع واقعاً با شیء و تابع تفاوتی ندارد
اشاره گر به شی

در C مثال متعارف یک اشاره گر به تابع a است
اشاره گر به تابع - عدد صحیح بازگشتی (PFI). برای PFI مصرف یکی INT پارامتر، این
می تواند اینگونه اعلام شود،

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

(اما بخوانید C++-سوالات متداول بخش 33 قبل از نوشتن کدی مانند این!) آنچه از این به دست می آورید
متغیری است با نام ساده pfi که به مقدار 0 مقدار دهی اولیه می شود. اگر می خواهید
این اشاره گر را به چیزی معنادار اولیه کنید، باید تابعی با a داشته باشید
امضای منطبق در این مورد، شما می توانید تابعی به شکل زیر ارائه دهید:

int MyFunction (int arg) {}

اگر این هدف را دارید، می توانید متغیر را برای اشاره به تابع خود مقداردهی اولیه کنید:

pfi = MyFunction;

سپس می‌توانید با استفاده از فرم پیشنهادی تماس، به‌طور غیرمستقیم با MyFunction تماس بگیرید:

int result = (*pfi) (1234);

این موضوع پیشنهادی است زیرا به نظر می رسد که شما فقط اشاره گر تابع را حذف می کنید
مثل اینکه شما هر اشاره گر را حذف می کنید. با این حال، به طور معمول، مردم از مزایای آن استفاده می کنند
این واقعیت که کامپایلر می‌داند چه اتفاقی می‌افتد و فقط از یک فرم کوتاه‌تر استفاده می‌کند:

int result = pfi (1234);

به نظر می رسد شما در حال فراخوانی تابعی به نام هستید pfi، اما کامپایلر به اندازه کافی هوشمند است
بدانید که از طریق متغیر فراخوانی کنید pfi به طور غیر مستقیم به تابع MyFunction.

از نظر مفهومی، این تقریباً دقیقاً نحوه عملکرد سیستم ردیابی است. در اصل، یک اثر
فرو رفتن is یک تماس برگشتی هنگامی که یک ردیابی به دریافت رویدادهای ردیابی ابراز علاقه می کند، آن را نشان می دهد
خود را به عنوان یک Callback به لیستی از Callbacks که به صورت داخلی توسط منبع ردیابی نگهداری می شود اضافه می کند.
هنگامی که یک رویداد جالب اتفاق می افتد، منبع ردیابی آن را فراخوانی می کند اپراتور(...) ارائه
آرگومان صفر یا بیشتر را اپراتور(...) در نهایت به سیستم سرگردان می شود و
کاری را به طرز قابل توجهی انجام می دهد مانند تماس غیرمستقیم که شما هم اکنون دیدید، صفر یا بیشتر را ارائه می دهد
پارامترها، درست به عنوان فراخوانی به pfi بالاتر یک پارامتر را به تابع هدف ارسال کرد
MyFunction.

تفاوت مهمی که سیستم ردیابی اضافه می کند این است که برای هر منبع ردیابی وجود دارد
یک لیست داخلی از Callbacks است. به جای اینکه فقط یک تماس غیرمستقیم ایجاد کنید، یک ردیابی
منبع ممکن است چندین تماس را فراخوانی کند. هنگامی که یک سینک ردیابی ابراز علاقه می کند
اعلان‌ها از یک منبع ردیابی، اساساً فقط ترتیب می‌دهد تا عملکرد خود را به آن اضافه کند
لیست پاسخ به تماس

اگر علاقه مند به جزئیات بیشتر در مورد نحوه چیدمان این هستید ns-3، احساس کن
رایگان برای مطالعه بخش Callback of the ns-3 دستی.

پیاده روی: سی سی چهارم
ما تعدادی کد برای پیاده سازی ساده ترین نمونه ردیابی ارائه کرده ایم
که قابل مونتاژ است شما می توانید این کد را در دایرکتوری آموزش به عنوان پیدا کنید سی سی چهارم.
بیایید از آن عبور کنیم:

/* -*- حالت:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* این برنامه نرم افزار رایگان است. شما می توانید آن را دوباره توزیع کنید و/یا تغییر دهید
* آن را تحت شرایط مجوز عمومی عمومی گنو نسخه 2 به عنوان
* منتشر شده توسط بنیاد نرم افزار آزاد؛
*
* این برنامه به امید اینکه مفید واقع شود توزیع شده است
* اما بدون ضمانت؛ حتی بدون ضمانت ضمنی
* قابلیت خرید و فروش یا تناسب اندام برای یک هدف خاص. را ببینید
* مجوز عمومی عمومی گنو برای جزئیات بیشتر.
*
* شما باید یک کپی از مجوز عمومی عمومی گنو دریافت کرده باشید
* همراه با این برنامه؛ اگر نه، به نرم افزار آزاد بنویسید
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

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

#عبارتند از

با استفاده از فضای نام ns3;

بیشتر این کد باید برای شما کاملا آشنا باشد. همانطور که در بالا ذکر شد، سیستم ردیابی
به شدت از سیستم های Object و Attribute استفاده می کند، بنابراین شما باید آنها را درج کنید.
دو مورد اول شامل اعلان‌های آن سیستم‌ها است. شما
می‌توانیم از هدر ماژول اصلی برای دریافت همه چیز به یکباره استفاده کنیم، اما ما شامل آن‌ها هستیم
به صراحت در اینجا برای نشان دادن اینکه این همه واقعا چقدر ساده است.

پرونده، traced-value.h اعلان های مورد نیاز را برای ردیابی داده هایی که
از معناشناسی ارزشی تبعیت می کند. به طور کلی، معناشناسی ارزش فقط به این معنی است که شما می توانید آن را پاس کنید
به جای ارسال آدرس شیء، خود را در اطراف خود قرار دهید. واقعا این همه چی
به این معنی است که شما قادر خواهید بود تمام تغییرات ایجاد شده در TracedValue را در یک واقعاً ردیابی کنید
راه ساده.

از آنجایی که سیستم ردیابی با ویژگی ها یکپارچه شده است و ویژگی ها با اشیاء کار می کنند،
باید وجود داشته باشد ns-3 شیء برای منبع ردیابی که در آن زندگی می کند. قطعه کد بعدی
یک شی ساده را که می توانیم با آن کار کنیم، اعلام و تعریف می کند.

کلاس MyObject: عمومی Object
{
عمومی:
استاتیک TypeId GetTypeId (باطل)
{
static TypeId tid = TypeId ("MyObject")
SetParent (Object::GetTypeId ())
.AddConstructor ()
.AddTraceSource ("MyInteger"،
"یک مقدار صحیح برای ردیابی."،
MakeTraceSourceAccessor (&MyObject::m_myInt)،
"ns3:: Traced::Value::Int32Callback")
;
برگرد
}

MyObject () {}
TracedValue m_myInt;
};

دو خط مهم کد، در بالا، با توجه به ردیابی عبارتند از .AddTraceSource
و TracedValue اعلامیه از m_myInt.

La .AddTraceSource "قلاب‌های" مورد استفاده برای اتصال منبع ردیابی به
دنیای خارج از طریق سیستم Config. اولین آرگومان نامی برای این ردیابی است
منبع، که آن را در سیستم پیکربندی قابل مشاهده می کند. آرگومان دوم یک رشته کمکی است.
اکنون به استدلال سوم نگاه کنید، در واقع بر روی آن تمرکز کنید استدلال از استدلال سوم:
&MyObject::m_myInt. این TracedValue است که به کلاس اضافه می شود. این است
همیشه یک عضو داده کلاس (استدلال نهایی نام a است typedef برای
نوع TracedValue، به عنوان یک رشته. این برای ایجاد مستندات درست استفاده می شود
امضای تابع پاسخ به تماس، که به ویژه برای انواع عمومی تر مفید است
تماس های تلفنی.)

La TracedValue<> Declaration زیرساختی را فراهم می کند که پاسخ تماس را هدایت می کند
روند. هر زمان که مقدار اساسی تغییر کند، مکانیسم TracedValue ارائه خواهد شد
هم مقدار قدیمی و هم مقدار جدید آن متغیر، در این مورد an int32_t ارزش. ردیابی
تابع سینک برای این TracedValue به امضا نیاز دارد

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

همه ردیاب‌هایی که این منبع ردیابی را قلاب می‌کنند باید این امضا را داشته باشند. در زیر بحث خواهیم کرد
چگونه می توانید امضای تماس مورد نیاز را در موارد دیگر تعیین کنید.

مطمئنا به اندازه کافی، ادامه دارد سی سی چهارم می بینیم:

از درجه اعتبار ساقط
IntTrace (int32_t oldValue، int32_t newValue)
{
std::cout << "ردیابی" << oldValue << " به " << newValue << std::endl;
}

این تعریف یک سینک ردیابی منطبق است. این به طور مستقیم با پاسخ تماس مطابقت دارد
امضای تابع پس از اتصال، این تابع در هر زمان فراخوانی می شود
TracedValue تغییرات.

ما اکنون منبع ردیابی و غرق ردیابی را دیده ایم. آنچه باقی می ماند کدی برای اتصال است
منبع به سینک، که در اصلی:

INT
اصلی (int argc، char *argv[])
{
Ptr myObject = CreateObject ()
myObject->TraceConnectWithoutContext ("MyInteger"، MakeCallback(&IntTrace));

myObject->m_myInt = 1234;
}

در اینجا ابتدا نمونه MyObject را ایجاد می کنیم که منبع ردیابی در آن زندگی می کند.

مرحله بعدی، TraceConnectWithoutContext، ارتباط بین ردیابی را تشکیل می دهد
منبع و سینک ردیابی اولین آرگومان فقط نام منبع ردیابی "MyInteger" است
در بالا دیدیم توجه کنید MakeCallback تابع قالب این تابع جادو را انجام می دهد
برای ایجاد زمینه مورد نیاز است ns-3 شیء Callback و مرتبط کردن آن با تابع
IntTrace. TraceConnect ارتباط بین عملکرد ارائه شده شما و
اضافه بار اپراتور() در متغیر traced که توسط ویژگی "MyInteger" ارجاع شده است.
پس از انجام این ارتباط، منبع ردیابی پاسخ تماس ارائه شده شما را "آتش" می کند
تابع.

رمز تحقق همه اینها، البته، بی اهمیت است، اما ماهیت این است
شما در حال ترتیب دادن چیزی هستید که دقیقاً شبیه به آن است pfi() مثال بالا به نام
توسط منبع ردیابی اعلامیه TracedValue m_myInt; در شیء
خود جادوی مورد نیاز برای ارائه اپراتورهای تخصیص بارگذاری شده را انجام می دهد
با استفاده از اپراتور() تا در واقع Callback را با پارامترهای مورد نظر فراخوانی کند. در
.AddTraceSource ماژیک را برای اتصال Callback به سیستم Config انجام می دهد و
TraceConnectWithoutContext جادو را برای اتصال عملکرد شما به ردیابی انجام می دهد
منبع، که با نام ویژگی مشخص شده است.

بیایید در حال حاضر کمی در مورد زمینه را نادیده بگیریم.

در نهایت، خطی که یک مقدار را به m_myInt:

myObject->m_myInt = 1234;

باید به عنوان فراخوانی تفسیر شود اپراتور= روی متغیر عضو m_myInt با
عدد صحیح 1234 به عنوان یک پارامتر ارسال می شود.

پس از m_myInt هست یک TracedValue، این عملگر برای اجرای یک کال بک تعریف شده است که
void را برمی گرداند و دو مقدار صحیح را به عنوان پارامتر --- یک مقدار قدیمی و یک مقدار جدید می گیرد
برای عدد صحیح مورد نظر این دقیقاً امضای تابع برای پاسخ به تماس است
عملکردی که ما ارائه کردیم --- IntTrace.

به طور خلاصه، منبع ردیابی، در اصل، متغیری است که فهرستی از تماس‌های برگشتی را در خود نگه می‌دارد. آ
ردیابی سینک تابعی است که به عنوان هدف تماس برگشتی استفاده می شود. ویژگی و نوع شی
سیستم های اطلاعاتی برای ارائه راهی برای اتصال منابع ردیابی به ردیابی سینک ها استفاده می شوند.
عمل "ضربه زدن" یک منبع ردیابی، اجرای یک عملگر بر روی منبع ردیابی است که
پاسخ تماس ها را شلیک می کند. این منجر به ردیابی تماس های سینک می شود که علاقه مند به ثبت نام هستند
منبع با پارامترهای ارائه شده توسط منبع فراخوانی می شود.

اگر اکنون این مثال را بسازید و اجرا کنید،

$ ./waf -- چهارم را اجرا کنید

خروجی را خواهید دید IntTrace تابع به محض اینکه منبع ردیابی باشد اجرا می شود
اصابت:

ردیابی 0 تا 1234

وقتی کد را اجرا کردیم، myObject->m_myInt = 1234.، منبع ردیابی شلیک و
به طور خودکار مقادیر قبل و بعد را به trace sink ارائه می کند. کارکرد
IntTrace سپس این را در خروجی استاندارد چاپ کرد.

اتصال با پیکربندی
La TraceConnectWithoutContext تماس نشان داده شده در بالا در مثال ساده در واقع بسیار است
به ندرت در سیستم استفاده می شود. به طور معمول، پیکربندی زیر سیستم برای انتخاب یک ردیابی استفاده می شود
منبع در سیستم با استفاده از چیزی که a نامیده می شود پیکربندی مسیر. نمونه ای از آن را در
بخش قبلی که در آن رویداد "CourseChange" را زمانی که در حال آزمایش بودیم قلاب کردیم
سوم.سی سی.

به یاد بیاورید که ما یک سینک ردیابی برای چاپ اطلاعات تغییر دوره از تحرک تعریف کردیم
مدل های شبیه سازی ما اکنون باید برای شما خیلی واضح تر باشد که این عملکرد چیست
در حال انجام:

از درجه اعتبار ساقط
CourseChange (std::string context، Ptr مدل)
{
موقعیت برداری = model->GetPosition ();
NS_LOG_UNCOND (زمینه <
" x = " << position.x << ", y = " << position.y);
}

هنگامی که منبع ردیابی "CourseChange" را به سینک ردیابی بالا وصل کردیم، از a استفاده کردیم
مسیر پیکربندی برای تعیین منبع زمانی که ما یک اتصال بین از پیش تعریف شده ترتیب دادیم
منبع ردیابی و سینک جدید ردیابی:

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

پیکربندی::اتصال (oss.str ()، MakeCallback (&CourseChange));

بیایید سعی کنیم چیزی را که گاهی اوقات کد نسبتاً مرموز تلقی می شود، درک کنیم.
برای اهداف بحث، فرض کنید که شماره Node که توسط the برگردانده شده است GetId() is
"7". در این صورت، مسیر بالا معلوم می شود

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

آخرین بخش مسیر پیکربندی باید یک باشد صفت از شیء. در واقع اگر داشتید
اشاره گر به شیء که دارای "تغییر دوره" است صفت مفید است، شما می توانید این را بنویسید
درست همانطور که در مثال قبلی انجام دادیم. شما تا به حال می دانید که ما معمولاً ذخیره می کنیم
اشاره گر به ما گره ها در یک NodeContainer. در سوم.سی سی به عنوان مثال، گره های مورد علاقه
در انبارها ذخیره می شوند wifiStaNodes NodeContainer. در واقع، در حالی که مسیر را کنار هم قرار می دهیم،
ما از این ظرف برای به دست آوردن یک Ptr که قبلا صداش میکردیم GetId(). ما می توانیم داشته باشیم
از این استفاده کرد Ptr برای فراخوانی مستقیم یک متد Connect:

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

در سوم.سی سی به عنوان مثال، ما در واقع می خواستیم یک "زمینه" اضافی در کنار آن ارائه شود
با پارامترهای Callback (که در زیر توضیح داده خواهد شد) بنابراین ما در واقع می توانیم از آن استفاده کنیم
کد معادل زیر:

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

به نظر می رسد که کد داخلی برای پیکربندی::ConnectWithoutContext و پیکربندی::اتصال
در واقع a Ptr و مناسب تماس بگیرید TraceConnect روش در کمترین مقدار
سطح.

La پیکربندی توابع مسیری را طی می کنند که نشان دهنده زنجیره ای از شیء اشاره گرها هر بخش
یک مسیر با یک ویژگی شی مطابقت دارد. آخرین بخش ویژگی Attribute of است
علاقه، و بخش های قبلی باید تایپ شوند تا اشیاء را در بر گیرند یا پیدا کنند. را پیکربندی رمز
این مسیر را تا زمانی که به بخش نهایی مسیر برسد، تجزیه کرده و «پیاده می‌کند». سپس آن را
آخرین بخش را به عنوان یک تعبیر می کند صفت در آخرین جسمی که در حین راه رفتن پیدا کرد
مسیر. پیکربندی سپس توابع مربوطه را فراخوانی کنید TraceConnect or
TraceConnectWithoutContext متد روی شی نهایی بیایید ببینیم بعد از مدتی چه اتفاقی می افتد
جزئیات بیشتر زمانی که مسیر فوق طی می شود.

کاراکتر "/" پیشرو در مسیر به فضای نامی اشاره دارد. یکی از
فضاهای نام از پیش تعریف شده در سیستم پیکربندی "NodeList" است که لیستی از همه موارد است.
گره ها در شبیه سازی آیتم های موجود در لیست با شاخص هایی در لیست ارجاع داده می شوند، بنابراین
"/NodeList/7" به گره هشتم در لیست گره های ایجاد شده در طول شبیه سازی اشاره دارد.
(شاخص های فراخوان از 0'). این مرجع is واقعا a ``Ptr ` و همینطور a
زیر کلاس an ns3:: شی.

همانطور که در بخش Object Model توضیح داده شده است ns-3 دستی، ما به طور گسترده از آن استفاده می کنیم
تجمع شی این به ما اجازه می دهد تا ارتباطی بین اشیاء مختلف ایجاد کنیم
بدون ساختن یک درخت ارثی پیچیده یا از قبل تعیین اینکه چه اشیایی بخشی خواهند بود
از یک گره هر شیء در یک تجمیع می تواند از اشیاء دیگر قابل دسترسی باشد.

در مثال ما، بخش بعدی مسیر با کاراکتر "$" شروع می شود. این
به سیستم پیکربندی نشان می دهد که قطعه نام یک نوع شی است، بنابراین a
GetObject باید به دنبال آن نوع تماس بگیرید. معلوم می شود که MobilityHelper
مورد استفاده در سوم.سی سی ترتیب می دهد تا یک مدل تحرک را برای هر یک از آنها جمع کند یا مرتبط کند
بي سيم گره ها. وقتی "$" را اضافه می کنید، شی دیگری را می خواهید که داشته باشد
احتمالاً قبلاً تجمیع شده است. شما می توانید این را به عنوان تغییر نشانگرها در نظر بگیرید
Ptr اصلی همانطور که توسط "/NodeList/7" به مدل تحرک مرتبط آن مشخص شده است ---
که از نوع است ns3::MobilityModel. اگر آشنایی دارید GetObject، پرسیده ایم
سیستم موارد زیر را انجام دهد:

Ptr mobilityModel = node->GetObject ()

ما اکنون در آخرین Object در مسیر هستیم، بنابراین توجه خود را به ویژگی های مربوط می کنیم
آن شی را MobilityModel کلاس یک ویژگی به نام "CourseChange" را تعریف می کند. تو می توانی
این را با نگاه کردن به کد منبع در آن ببینید src/mobility/model/mobility-model.cc و
جستجوی "CourseChange" در ویرایشگر مورد علاقه خود. باید پیدا کنی

.AddTraceSource ("CurseChange"،
"مقدار بردار موقعیت و/یا سرعت تغییر کرد"
MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace)،
"ns3::MobilityModel::CourseChangeCallback")

که در این مرحله باید بسیار آشنا به نظر برسد.

اگر به دنبال اعلان متناظر متغیر traced زیربنایی باشید
mobility-model.h شما را پیدا خواهد کرد

TracedCallback > m_courseChangeTrace؛

اعلامیه نوع TracedCallback شناسایی می کند m_courseChangeTrace به عنوان یک لیست ویژه از
تماس‌هایی که می‌توانند با استفاده از توابع پیکربندی که در بالا توضیح داده شد متصل شوند. را typedef برای
امضای تابع callback نیز در فایل هدر تعریف شده است:

typedef void (* CourseChangeCallback)(Ptr * مدل)؛

La MobilityModel کلاس طوری طراحی شده است که یک کلاس پایه باشد که یک رابط مشترک برای آن ارائه می کند
همه زیر کلاس های خاص اگر تا انتهای فایل را جستجو کنید، a
متد تعریف شده نامیده می شود NotifyCourseChange():

از درجه اعتبار ساقط
MobilityModel::NotifyCourseChange (void) const
{
m_courseChangeTrace(this);
}

کلاس های مشتق شده هر زمان که یک دوره برای پشتیبانی انجام دهند به این روش فراخوانی می شوند
ردیابی این روش فراخوانی می کند اپراتور() در زمینه m_courseChangeTrace، که
به نوبه خود، همه Callback های ثبت شده را فراخوانی می کند و همه ردیابی ها را فراخوانی می کند
با فراخوانی یک تابع Config علاقه خود را به منبع ردیابی ثبت کرده اند.

بنابراین ، در سوم.سی سی به عنوان مثالی که ما به آن نگاه کردیم، هر زمان که تغییر رشته در یکی از موارد ایجاد شود
RandomWalk2dMobilityModel موارد نصب شده، وجود خواهد داشت NotifyCourseChange() صدا
که به MobilityModel کلاس پایه همانطور که در بالا مشاهده شد، این فراخوانی می کند اپراتور()
on m_courseChangeTrace، که به نوبه خود، هر اثر ثبت شده را سینک می نامد. در مثال،
تنها کدی که علاقه را ثبت می کرد، کدی بود که مسیر پیکربندی را ارائه می کرد.
بنابراین، تغییر دوره تابعی که از گره شماره هفت قلاب شده است، خواهد بود
فقط تماس تلفنی تماس گرفت.

آخرین قطعه پازل «زمینه» است. به یاد بیاورید که ما یک خروجی به دنبال دیدیم
چیزی شبیه به زیر از سوم.سی سی:

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

بخش اول خروجی زمینه است. این به سادگی راهی است که از طریق آن
کد پیکربندی منبع ردیابی را قرار داده است. در موردی که ما به آن نگاه کرده ایم، ممکن است وجود داشته باشد
هر تعداد منبع ردیابی در سیستم مربوط به هر تعداد گره با
مدل های تحرک باید راهی برای شناسایی منبع ردیابی وجود داشته باشد
یکی که Callback را شلیک کرد. راه آسان این است که با آن ارتباط برقرار کنید پیکربندی::اتصال، بجای
of پیکربندی::ConnectWithoutContext.

کشف منابع
اولین سوالی که ناگزیر برای کاربران جدید سیستم Tracing مطرح می شود این است که "باشه،
I دانستن که آنجا باید be رد منابع in la شبیه سازی هسته، اما چگونه do I پیدا کردن خارج چی
رد منابع هستند در دسترس به من؟ "

سوال دوم این است که "باشه، I یافت a رد منبع ، چگونه do I شکل خارج la پیکربندی مسیر
به استفاده کنید چه زمانی I اتصال به آی تی؟"

سوال سوم این است که "باشه، I یافت a رد منبع و la پیکربندی مسیر، چگونه do I شکل
خارج چی la برگشت نوع و رسمی استدلال of my فراخوان تابع نیاز به بودن؟"

سوال چهارم این است که "باشه، I تایپ شده که تمام in و کردم این بطور باور نکردنی غریب و عجیب خطا
پیام ، چی in la جهان میکند it منظور داشتن؟"

ما به نوبه خود به هر یک از این موارد خواهیم پرداخت.

در دسترس منابع
باشه، I دانستن که آنجا باید be رد منابع in la شبیه سازی هسته، اما چگونه do I پیدا کردن
خارج چی رد منابع هستند در دسترس به من؟

پاسخ به سوال اول در یافت می شود ns-3 اسناد API اگر به
وب سایت پروژه، ns-3 پروژه، پیوندی به "اسناد" در پیمایش پیدا خواهید کرد
بار. اگر این پیوند را انتخاب کنید، به صفحه مستندات ما هدایت خواهید شد. وجود دارد
پیوند به "آخرین نسخه" که شما را به مستندات آخرین استبل می برد
رها کردن ns-3. اگر پیوند "API Documentation" را انتخاب کنید، به این آدرس هدایت خواهید شد
ns-3 صفحه اسناد API.

در نوار کناری باید سلسله مراتبی را ببینید که شروع می شود

· ns-3

· مستندات ns-3

· همه TraceSources

· همه صفات

· همه ارزش های جهانی

لیست مورد علاقه ما در اینجا "همه منابع ردیابی" است. برو و اون لینک رو انتخاب کن
شما، شاید خیلی تعجب آور نباشد، فهرستی از تمام منابع ردیابی موجود را خواهید دید
in ns-3.

به عنوان مثال، به پایین بروید ns3::MobilityModel. یک ورودی برای پیدا خواهید کرد

CourseChange: مقدار بردار موقعیت و/یا سرعت تغییر کرد

شما باید این را به عنوان منبع ردیابی که ما در آن استفاده کرده‌ایم بشناسید سوم.سی سی مثال. مطالعه کردن
این لیست مفید خواهد بود.

پیکربندی راه ها
باشه، I یافت a رد منبع ، چگونه do I شکل خارج la پیکربندی مسیر به استفاده کنید چه زمانی I اتصال به
آن؟

اگر می‌دانید به کدام شی علاقه دارید، بخش "شرح تفصیلی" را برای
کلاس تمام منابع ردیابی موجود را فهرست می کند. به عنوان مثال، شروع از لیست "همه
TraceSources" روی آن کلیک کنید ns3::MobilityModel لینک، که شما را به
اسناد و مدارک برای MobilityModel کلاس تقریباً در بالای صفحه یک خط است
شرح مختصری از کلاس، که به لینک "بیشتر..." ختم می شود. برای پرش روی این لینک کلیک کنید
خلاصه API و به «شرح تفصیلی» کلاس بروید. در پایان از
توضیحات (تا) سه لیست خواهد بود:

· پیکربندی راه ها: لیستی از مسیرهای پیکربندی معمولی برای این کلاس.

· خواص: لیستی از تمام ویژگی های ارائه شده توسط این کلاس.

· TraceSources: لیستی از همه TraceSources موجود از این کلاس.

ابتدا در مورد مسیرهای Config بحث می کنیم.

بیایید فرض کنیم که شما به تازگی منبع ردیابی "CourseChange" را در "همه" پیدا کرده اید.
TraceSources" لیست می شود و می خواهید نحوه اتصال به آن را بیابید. می دانید که هستید
با استفاده از (دوباره، از سوم.سی سی مثال) an ns3::RandomWalk2dMobilityModel. پس یا
روی نام کلاس در لیست "همه منابع ردیابی" کلیک کنید یا پیدا کنید
ns3::RandomWalk2dMobilityModel در "فهرست کلاس". در هر صورت اکنون باید به دنبال آن باشید
در صفحه "ns3::RandomWalk2dMobilityModel Class Reference".

اگر اکنون به قسمت «توضیحات تفصیلی» بروید، پس از فهرست خلاصه
متدها و ویژگی های کلاس (یا فقط روی پیوند "بیشتر..." در انتهای کلاس کلیک کنید
توضیحات مختصر در بالای صفحه) مستندات کلی را مشاهده خواهید کرد
کلاس در ادامه پیمایش به پایین، لیست "Config Paths" را پیدا کنید:
پیکربندی راه ها

ns3::RandomWalk2dMobilityModel از طریق مسیرهای زیر قابل دسترسی است با
پیکربندی:: تنظیم و پیکربندی::اتصال:

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

مستندات به شما می گوید که چگونه به آن برسید RandomWalk2dMobilityModel هدف - شی. مقایسه کنید
رشته بالا با رشته ای که در کد مثال استفاده کردیم:

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

تفاوت به این دلیل است که دو GetObject فراخوانی ها در رشته یافت شده ذکر می شوند
در مستندات اولی، برای $ns3::MobilityModel جمع آوری را برای
کلاس پایه دومی اشاره کرد GetObject تماس برای $ ns3 :: randomwalk2dmobilitymodel,
برای ریختن کلاس پایه به کلاس اجرای بتن استفاده می شود. مستندات
هر دوی این عملیات را برای شما نشان می دهد. معلوم می شود که منبع ردیابی واقعی شما هستید
جستجو در کلاس پایه یافت می شود.

برای یافتن فهرست منابع ردیابی، به بخش «توضیحات تفصیلی» نگاه کنید.
شما را پیدا خواهد
هیچ TraceSource برای این نوع تعریف نشده است.

TraceSources مشخص in پدر یا مادر کلاس ``ns3::MobilityModel``

· تغییر دوره: مقدار بردار موقعیت و/یا سرعت تغییر کرد.

امضای پاسخ به تماس: ns3::MobilityModel::CourseChangeCallback

این دقیقا همان چیزی است که شما باید بدانید. منبع ردیابی علاقه در یافت می شود
ns3::MobilityModel (که به هر حال می دانستید). نکته جالب این بیت API است
مستندات به شما می گوید که در مسیر پیکربندی بالا نیازی به بازیگر اضافی ندارید
به کلاس بتن برسید، زیرا منبع ردیابی در واقع در کلاس پایه است.
بنابراین اضافی GetObject مورد نیاز نیست و شما به سادگی از مسیر زیر استفاده می کنید:

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

که کاملاً با مسیر مثال مطابقت دارد:

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

به عنوان کنار، راه دیگری برای یافتن مسیر Config این است که grep استفاده اطراف در ns-3 پایه کد
برای کسی که قبلا آن را فهمیده است همیشه باید سعی کنید از دیگران کپی کنید
قبل از شروع به نوشتن کد کار خود. چیزی شبیه این را امتحان کنید:

$ پیدا کنید. -name '*.cc' | xargs grep تغییر دوره | grep اتصال

و ممکن است پاسخ خود را به همراه کد کار پیدا کنید. به عنوان مثال، در این مورد،
src/mobility/examples/main-random-topology.cc چیزی دارد که فقط در انتظار شما برای استفاده است:

پیکربندی:: اتصال ("/NodeList/*/$ns3::MobilityModel/CourseChange"،
MakeCallback (&CourseChange))؛

ما در یک لحظه به این مثال باز خواهیم گشت.

تماس لطفا امضا
باشه، I یافت a رد منبع و la پیکربندی مسیر، چگونه do I شکل خارج چی la برگشت نوع
و رسمی استدلال of my فراخوان تابع نیاز به بودن؟

ساده ترین راه این است که امضای تماس را بررسی کنید typedef، که در داده شده است
"امضای پاسخ به تماس" منبع ردیابی در "شرح تفصیلی" برای کلاس، به عنوان
در بالا نشان داده شده است

تکرار ورودی منبع ردیابی "CourseChange" از ns3::RandomWalk2dMobilityModel we
دارند:

· تغییر دوره: مقدار بردار موقعیت و/یا سرعت تغییر کرد.

امضای پاسخ به تماس: ns3::MobilityModel::CourseChangeCallback

امضای تماس به عنوان پیوندی به مربوطه داده می شود typedef، جایی که پیدا می کنیم
typedef از درجه اعتبار ساقط (* CourseChangeCallback) (تداوم std::string متن نوشته، Ptr
MobilityModel> * مدل)؛

TracedCallback امضا برای اطلاعیه های تغییر دوره

اگر پاسخ تماس با استفاده از ConnectWithoutContext حذف کردن زمینه استدلال از
امضا

پارامترهای:
[in] context رشته زمینه ارائه شده توسط منبع Trace.
مدل [in] MobilityModel که در حال تغییر مسیر است.

همانطور که در بالا، برای دیدن این در حال استفاده است grep استفاده اطراف در ns-3 به عنوان مثال، پایگاه کد مثال
بالا، از src/mobility/examples/main-random-topology.cc، "CourseChange" را متصل می کند
منبع ردیابی به تغییر دوره عملکرد در همان فایل:

باطل استاتیک
CourseChange (std::string context، Ptr مدل)
{
...
}

توجه داشته باشید که این تابع:

· یک آرگومان رشته "context" را می گیرد که در عرض یک دقیقه توضیح خواهیم داد. (اگر پاسخ به تماس
با استفاده از ConnectWithoutContext تابع زمینه استدلال خواهد بود
حذف شده است.)

· دارد MobilityModel به عنوان آخرین آرگومان (یا فقط آرگومان اگر
ConnectWithoutContext استفاده می شود).

· برمی گردد از درجه اعتبار ساقط.

اگر به طور تصادفی، امضای تماس مجدد مستند نشده باشد و هیچ نمونه ای برای آن وجود نداشته باشد
بنابراین، تعیین امضای تابع پاسخ به تماس مناسب می‌تواند چالش‌برانگیز باشد
در واقع از کد منبع پیدا کنید.

قبل از شروع به بررسی کد، مهربان خواهم بود و فقط یک راه ساده را به شما می گویم
برای فهمیدن این موضوع: مقدار برگشتی بازگشت تماس شما همیشه خواهد بود از درجه اعتبار ساقطبه رسمی
لیست پارامتر برای a TracedCallback را می توان از لیست پارامترهای الگو در قسمت پیدا کرد
اعلام. به یاد بیاورید که برای مثال فعلی ما، این در است mobility-model.h، جایی که ما
قبلا پیدا کرده اند:

TracedCallback > m_courseChangeTrace؛

یک تناظر یک به یک بین لیست پارامترهای الگو در وجود دارد
اعلان و آرگومان های رسمی تابع callback. اینجا یکی هست
پارامتر قالب که عبارت است از a Ptr MobilityModel>. این به شما می گوید که شما نیاز به یک
تابعی که void را برمی گرداند و a را می گیرد Ptr MobilityModel>. مثلا:

از درجه اعتبار ساقط
تغییر دوره (Ptr مدل)
{
...
}

اگر بخواهید این تمام چیزی است که نیاز دارید پیکربندی::ConnectWithoutContext. اگر زمینه می خواهید،
شما نیاز به پیکربندی::اتصال و از یک تابع Callback که یک زمینه رشته را می گیرد، استفاده کنید
آرگومان های قالب:

از درجه اعتبار ساقط
CourseChange (const std::string context، Ptr مدل)
{
...
}

اگر می خواهید اطمینان حاصل کنید که شما CourseChangeCallback تابع فقط در شما قابل مشاهده است
فایل محلی، می توانید کلمه کلیدی را اضافه کنید ایستا و به این نتیجه برسیم:

باطل استاتیک
CourseChange (const std:: مسیر رشته، Ptr مدل)
{
...
}

که دقیقا همان چیزی است که ما در آن استفاده کردیم سوم.سی سی مثال.

پیاده سازی
این بخش کاملا اختیاری است. این یک سواری پر دست انداز خواهد بود، به خصوص برای آن ها
با جزئیات قالب ها آشنا نیستم. با این حال، اگر از این طریق عبور کنید، خواهید داشت
یک دسته بسیار خوب در بسیاری از ns-3 اصطلاحات سطح پایین

بنابراین، دوباره، بیایید بفهمیم که چه امضای تابع callback مورد نیاز است
منبع ردیابی "CourseChange". این دردناک خواهد بود، اما شما فقط باید این کار را انجام دهید
یک بار. پس از عبور از این، می توانید فقط به یک نگاه کنید TracedCallback و
متوجه شدم.

اولین چیزی که باید به آن نگاه کنیم، اعلام منبع ردیابی است. به یاد بیاورید که
این در mobility-model.h، جایی که قبلاً یافتیم:

TracedCallback > m_courseChangeTrace؛

این اعلامیه برای یک الگو است. پارامتر الگو در داخل براکت های زاویه قرار دارد،
بنابراین ما واقعاً علاقه مندیم که بدانیم این چیست TracedCallback<> است. اگر تو داری
مطلقاً هیچ ایده ای در این مورد وجود ندارد، grep استفاده دوست تو هست

ما احتمالاً به نوعی اعلامیه در این زمینه علاقه مند خواهیم بود ns-3 منبع، بنابراین
ابتدا به " فهرست راهنما. سپس، ما می دانیم که این اعلامیه باید انجام شود
در نوعی از فایل هدر باشد، بنابراین فقط grep استفاده برای آن با استفاده از:

$ پیدا کنید. -name '*.h' | xargs grep TracedCallback

303 خط را خواهید دید که در حال پرواز هستند (من این را لوله کردم wc ببینم چقدر بد بود). با اينكه
ممکن است زیاد به نظر برسد، واقعاً زیاد نیست. فقط خروجی را لوله کنید بیش و
شروع به اسکن از طریق آن کنید. در صفحه اول، شما برخی از موارد بسیار مشکوک را مشاهده خواهید کرد
چیزهایی شبیه به قالب

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 ...

معلوم می شود که همه اینها از فایل هدر می آید traced-callback.h که صدا می کند
بسیار امیدوار کننده. سپس می توانید نگاهی به آن بیندازید mobility-model.h و ببینید که یک خط وجود دارد
که این تصور را تایید می کند:

#include "ns3/traced-callback.h"

البته، می‌توانستید از جهت دیگر به این موضوع بروید و با نگاه کردن شروع کنید
شامل در mobility-model.h و توجه به شامل traced-callback.h و
استنباط می کند که این باید فایل مورد نظر شما باشد.

در هر صورت، قدم بعدی این است که نگاهی به آن بیندازید src/core/model/traced-callback.h in
ویرایشگر مورد علاقه خود را برای دیدن آنچه اتفاق می افتد.

نظری را در بالای فایل خواهید دید که باید آرامش بخش باشد:
یک ns3::TracedCallback تقریباً دقیقاً همان API یک ns3::Callback معمولی دارد اما
به جای انتقال تماس ها به یک تابع (همانطور که معمولاً یک ns3::Callback انجام می دهد)،
تماس ها را به زنجیره ای از ns3::Callback ارسال می کند.

این باید بسیار آشنا به نظر برسد و به شما اطلاع دهد که در مسیر درستی هستید.

فقط بعد از این نظر، خواهید دید

قالب
نوع نام T3 = خالی، نام نوع T4 = خالی،
نوع نام T5 = خالی، نام نوع T6 = خالی،
typename T7 = خالی، typename T8 = خالی>
کلاس TracedCallback
{
...

این به شما می گوید که TracedCallback یک کلاس قالب است. دارای هشت نوع ممکن است
پارامترها با مقادیر پیش فرض برگردید و این را با اعلامیه ای که هستید مقایسه کنید
تلاش برای درک:

TracedCallback > m_courseChangeTrace؛

La اسم را تایپ کن T1 در اعلان کلاس الگو مطابق با Ptr
MobilityModel> در اعلامیه بالا تمام پارامترهای نوع دیگر به عنوان باقی مانده است
پیش فرض ها نگاه کردن به سازنده واقعا چیز زیادی به شما نمی گوید. همان جایی که
مشاهده کرده اید که بین عملکرد Callback شما و سیستم ردیابی ارتباط برقرار شده است
در اتصال و ConnectWithoutContext کارکرد. اگر به پایین اسکرول کنید، یک را خواهید دید
ConnectWithoutContext روش در اینجا:

قالب
تایپ نام T3، نام نوع T4،
تایپ نام T5، نام نوع T6،
typename T7، typename T8>
از درجه اعتبار ساقط
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext ...
{
Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> cb;
cb.Assign (بازخوانی)؛
m_callbackList.push_back (cb);
}

شما اکنون در شکم وحش هستید. هنگامی که الگو برای
بیانیه بالا، کامپایلر جایگزین خواهد شد T1 با Ptr MobilityModel>.

از درجه اعتبار ساقط
TracedCallback ::ConnectWithoutContext ... cb
{
پاسخ به تماس > cb;
cb.Assign (بازخوانی)؛
m_callbackList.push_back (cb);
}

اکنون می توانید اجرای همه چیزهایی را که در مورد آن صحبت کردیم مشاهده کنید. کد
یک Callback از نوع مناسب ایجاد می کند و عملکرد شما را به آن اختصاص می دهد. این است
معادل pfi = MyFunction در ابتدای این بخش بحث کردیم. کد
سپس Callback را به لیست Callbacks برای این منبع اضافه می کند. تنها چیزی که باقی مانده است
برای نگاهی به تعریف Callback. با استفاده از همین grep استفاده ترفندی که قبلا پیدا می کردیم
TracedCallback، می توانید آن فایل را پیدا کنید ./core/callback.h همان ماست
نیاز به نگاه کردن

اگر از طریق فایل به پایین نگاه کنید، احتمالاً بسیاری از موارد تقریباً نامفهوم را خواهید دید
کد قالب در نهایت به برخی از اسناد API برای پاسخ به تماس خواهید رسید
هر چند کلاس قالب خوشبختانه مقداری انگلیسی وجود دارد:
تماس لطفا کلاس قالب

این الگوی کلاس الگوی طراحی Functor را پیاده سازی می کند. برای اعلام استفاده می شود
نوع a تماس لطفا:

· اولین آرگومان الگوی غیراختیاری نشان دهنده نوع برگشتی تماس برگشتی است.

· آرگومان های قالب باقی مانده (اختیاری) نشان دهنده نوع بعدی است
آرگومان هایی برای پاسخ به تماس

· تا نه آرگومان پشتیبانی می شود.

ما در تلاشیم تا بفهمیم که چیست

پاسخ به تماس > cb;

اعلام یعنی اکنون در موقعیتی هستیم که درک کنیم که اولین (غیر اختیاری)
استدلال الگو، از درجه اعتبار ساقط، نشان دهنده نوع برگشتی Callback است. دومین
آرگومان الگو (اختیاری)، Ptr MobilityModel> نشان دهنده نوع اولی است
استدلال برای پاسخ به تماس

Callback مورد نظر عملکرد شما برای دریافت ردیابی رویدادها است. از این شما می توانید
استنباط کنید که به تابعی نیاز دارید که برگرداند از درجه اعتبار ساقط و طول می کشد Ptr MobilityModel>.
به عنوان مثال،

از درجه اعتبار ساقط
CourseChangeCallback (Ptr مدل)
{
...
}

اگر بخواهید این تمام چیزی است که نیاز دارید پیکربندی::ConnectWithoutContext. اگر زمینه می خواهید،
شما نیاز به پیکربندی::اتصال و از یک تابع Callback که یک زمینه رشته را می گیرد استفاده کنید. این
به این دلیل است که اتصال تابع زمینه را برای شما فراهم می کند. شما نیاز خواهید داشت:

از درجه اعتبار ساقط
CourseChangeCallback (std::string context، Ptr مدل)
{
...
}

اگر می خواهید اطمینان حاصل کنید که شما CourseChangeCallback فقط در فایل محلی شما قابل مشاهده است،
می توانید کلمه کلیدی را اضافه کنید ایستا و به این نتیجه برسیم:

باطل استاتیک
CourseChangeCallback (std:: مسیر رشته، Ptr مدل)
{
...
}

که دقیقا همان چیزی است که ما در آن استفاده کردیم سوم.سی سی مثال. شاید الان باید برگردی و
بخش قبلی (Take My Word for It) را دوباره بخوانید.

اگر به جزئیات بیشتر در مورد اجرای Callbacks علاقه مند هستید، راحت باشید
تا نگاهی به ns-3 کتابچه راهنمای. آنها یکی از متداول ترین سازه ها هستند
قسمت های سطح پایین از ns-3. به نظر من این یک چیز کاملاً شیک است.

TracedValues
قبلا در این بخش، یک کد ساده ارائه کردیم که از a استفاده می کرد
TracedValue برای نشان دادن اصول اولیه کد ردیابی. ما فقط غافل شدیم
TracedValue واقعاً چیست و چگونه می توان نوع بازگشتی و آرگومان های رسمی را پیدا کرد
پاسخ به تماس

همانطور که اشاره کردیم، فایل، traced-value.h اظهارنامه های مورد نیاز را برای ردیابی می آورد
داده هایی که از معناشناسی ارزش تبعیت می کنند. به طور کلی، معناشناسی ارزش فقط به این معنی است که شما می توانید
به جای ارسال آدرس شی، خود شی را به اطراف منتقل کنید. تمدید می کنیم
این الزام شامل مجموعه کامل عملگرهای سبک انتساب است
از پیش تعریف شده برای انواع داده های قدیمی (POD):

┌─────────────────
اپراتور= (تکالیف) │ │
├────────────────────-
اپراتور*=اپراتور/=
├────────────────────-
عملگر+=اپراتور-=
├────────────────────-
اپراتور ++ (هر دو پیشوند و │ │
│پست ثابت) │ │
├────────────────────-
اپراتور-- (هر دو پیشوند و │ │
│پست ثابت) │ │
├────────────────────-
اپراتور<<=اپراتور>>=
├────────────────────-
اپراتور&=اپراتور|=
├────────────────────-
عملگر%=اپراتور^=
└─────────────────

معنای واقعی این همه این است که شما قادر خواهید بود تمام تغییرات ایجاد شده با استفاده از آنها را ردیابی کنید
عملگرهای یک شی C++ که دارای معنایی ارزش است.

La TracedValue<> بیانیه ای که در بالا دیدیم زیرساختی را فراهم می کند که بیش از حد بارگذاری می کند
اپراتورهایی که در بالا ذکر شد و فرآیند برگشت تماس را هدایت می کند. در استفاده از هر یک از اپراتورها
بالا با a TracedValue هم مقدار قدیمی و هم مقدار جدید آن متغیر را ارائه می دهد،
در این مورد یک int32_t ارزش. با بازرسی از TracedValue اعلامیه، ما می دانیم
تابع trace sink آرگومان هایی خواهد داشت (ثابت int32_t oldValue، طراح int32_t newValue).
نوع بازگشت برای a TracedValue تابع callback همیشه است از درجه اعتبار ساقط، بنابراین انتظار می رود
امضای تماس برگشتی به صورت زیر خواهد بود:

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

La .AddTraceSource در GetTypeId روش "قلاب" مورد استفاده برای اتصال را فراهم می کند
ردیابی منبع به دنیای خارج از طریق سیستم Config. ما قبلا در مورد
سه آگرومنت اول به AddTraceSource: نام ویژگی برای سیستم پیکربندی، یک راهنما
رشته و آدرس عضو داده کلاس TracedValue.

آرگومان رشته نهایی، "ns3::Traced::Value::Int32" در مثال، نام یک
typedef برای امضای تابع برگشت به تماس ما نیاز داریم که این امضاها تعریف شوند،
و نام نوع کاملا واجد شرایط را به آن بدهید AddTraceSource، بنابراین اسناد API می تواند
یک منبع ردیابی را به امضای تابع پیوند دهید. برای TracedValue امضا است
سرراست برای TracedCallbacks قبلاً شاهد بودیم که اسناد API واقعاً کمک می کند.

واقعی مثال
بیایید مثالی از یکی از شناخته شده ترین کتاب های TCP در اطراف انجام دهیم. "TCP/IP
مصور، جلد 1: پروتکل‌ها، اثر دبلیو ریچارد استیونز یک اثر کلاسیک است. من همین الان ورق زدم
کتاب باز شد و در یک طرح زیبا از هر دو پنجره شلوغ و دنباله اجرا شد
اعداد در مقابل زمان در صفحه 366. استیونز این را "شکل 21.10. ارزش cwnd و
زمانی که داده ها در حال انتقال هستند، شماره دنباله را ارسال کنید." اجازه دهید فقط قسمت cwnd را دوباره ایجاد کنیم
از آن طرح در ns-3 با استفاده از سیستم ردیابی و gnuplot.

در دسترس منابع
اولین چیزی که باید در مورد آن فکر کنیم این است که چگونه می خواهیم داده ها را به بیرون برسانیم. این چیه که ما
نیاز به ردیابی؟ بنابراین بیایید از فهرست "همه منابع ردیابی" استفاده کنیم تا ببینیم چه کاری باید انجام دهیم
با. به یاد داشته باشید که این در یافت می شود ns-3 اسناد API. اگر از طریق آن پیمایش کنید
لیست، در نهایت خواهید یافت:
ns3::TcpNewReno

· CongestionWindow: پنجره تراکم اتصال TCP

· SlowStartThreshold: آستانه شروع آهسته TCP (بایت)

به نظر می رسد که ns-3 اجرای TCP (بیشتر) در فایل زندگی می کند
src/internet/model/tcp-socket-base.cc در حالی که انواع کنترل ازدحام در فایل هایی مانند
as src/internet/model/tcp-newreno.cc. اگر این را نمی دانید a پیشینی، شما می توانید از
بازگشتی grep استفاده فوت و فن:

$ پیدا کنید. -name '*.cc' | xargs grep -i tcp

صفحه به صفحه نمونه هایی از tcp را خواهید دید که شما را به آن فایل نشان می دهد.

آوردن مدارک کلاس برای TcpNewReno و پرش به لیست
TraceSources را خواهید یافت
TraceSources

· CongestionWindow: پنجره تراکم اتصال TCP

امضای پاسخ به تماس: ns3:: Traced::Value::Uint322Callback

با کلیک بر روی تماس پاسخ typedef پیوند ما امضایی را می بینیم که اکنون می دانید انتظار دارید:

typedef void(* ns3::Traced::Value::Int32Callback)(const int32_t oldValue, const int32_t newValue)

اکنون باید این کد را به طور کامل درک کنید. اگر یک اشاره گر به TcpNewReno,
ما میتوانیم TraceConnect به منبع ردیابی "CngestionWindow" در صورت ارائه مناسب
هدف برگشت به تماس این همان نوع منبع ردیابی است که در مثال ساده دیدیم
در ابتدای این بخش، با این تفاوت که ما در مورد آن صحبت می کنیم uint32_t بجای
int32_t. و ما می دانیم که باید یک تابع callback با آن امضا ارائه دهیم.

کشف مثال ها
همیشه بهترین کار این است که سعی کنید کدهای کاری را پیدا کنید که بتوانید آن را تغییر دهید
از شروع از صفر بنابراین اولین کار در حال حاضر این است که کدی را پیدا کنید
قبلاً منبع ردیابی «CongestionWindow» را قلاب کرده و ببینید آیا می‌توانیم آن را تغییر دهیم. مثل همیشه،
grep استفاده دوست شماست:

$ پیدا کنید. -name '*.cc' | xargs grep CongestionWindow

این به چند نامزد امیدوار کننده اشاره می کند: examples/tcp/tcp-large-transfer.cc
و src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc.

ما هنوز هیچ کد آزمایشی را مشاهده نکردیم، پس بیایید نگاهی به آنجا بیندازیم. شما خواهد شد
معمولاً متوجه می‌شوند که کد آزمایشی نسبتاً کم است، بنابراین این احتمالاً یک شرط بندی بسیار خوب است.
باز کن src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc در ویرایشگر مورد علاقه خود و جستجو کنید
"پنجره ازدحام". خواهی یافت،

ns3TcpSocket->TraceConnectWithoutContext ("CngestionWindow"،
MakeCallback (&Ns3TcpCwndTestCase1::CwndChange، این));

این باید برای شما بسیار آشنا به نظر برسد. ما در بالا ذکر کردیم که اگر یک اشاره گر داشتیم
TcpNewReno، ما می توانستیم TraceConnect به منبع ردیابی "CngestionWindow". دقیقا همینطوره
آنچه در اینجا داریم؛ بنابراین معلوم می شود که این خط کد دقیقاً همان کاری را انجام می دهد که ما می خواهیم.
بیایید پیش برویم و کد مورد نیاز خود را از این تابع استخراج کنیم (Ns3TcpCwndTestCase1::DoRun
(خالی)). اگر به این تابع نگاه کنید، متوجه خواهید شد که دقیقاً شبیه یک است ns-3
اسکریپت معلوم می شود که دقیقاً همین است. این یک اسکریپت است که توسط تست اجرا می شود
چارچوب، بنابراین ما می توانیم آن را بیرون بکشیم و در آن بپیچیم اصلی به جای در DoRun. نسبتا
پس از طی کردن این مرحله، گام به گام، فایلی را که از پورت کردن حاصل می شود، ارائه کرده ایم
این تست به یک بومی برمی گردد ns-3 فیلمنامه -- examples/tutorial/fifth.cc.

پویا پی گیری منابع
La سی سی پنجم مثال یک قانون بسیار مهم را نشان می دهد که باید آن را درک کنید
قبل از استفاده از هر نوع منبع ردیابی: باید مطمئن شوید که هدف a
پیکربندی::اتصال دستور قبل از استفاده از آن وجود دارد. این با گفتن فرقی ندارد
یک شی باید قبل از فراخوانی آن نمونه سازی شود. اگرچه این ممکن است بدیهی به نظر برسد
هنگامی که به این صورت بیان می شود، بسیاری از افرادی را که سعی در استفاده از سیستم برای اولین بار دارند، از بین می برد
زمان.

بیایید یک لحظه به اصول اولیه بازگردیم. سه مرحله اجرای اساسی وجود دارد که در آن وجود دارد
هر ns-3 اسکریپت فاز اول گاهی اوقات "زمان پیکربندی" یا "تنظیم" نامیده می شود
زمان" و در دوره ای وجود دارد که اصلی عملکرد اسکریپت شما در حال اجرا است، اما
قبل از شبیه ساز::اجرا کنید نامیده میشود. فاز دوم گاهی اوقات "زمان شبیه سازی" نامیده می شود.
و در طول دوره زمانی وجود دارد که شبیه ساز::اجرا کنید به طور فعال رویدادهای خود را اجرا می کند.
پس از اتمام اجرای شبیه سازی، شبیه ساز::اجرا کنید کنترل را دوباره به
la اصلی عملکرد. هنگامی که این اتفاق می افتد، فیلمنامه وارد چیزی می شود که می توان آن را "Teardown" نامید
فاز، زمانی است که ساختارها و اشیاء ایجاد شده در حین نصب از هم جدا می شوند و
آزاد شد

شاید رایج ترین اشتباهی که در تلاش برای استفاده از سیستم ردیابی انجام می شود، این فرض است
موجودیت هایی که به صورت پویا ساخته می شوند در طی شبیه سازی زمان در طول پیکربندی در دسترس هستند
زمان. به طور خاص، یک ns-3 پریز یک شی پویا است که اغلب توسط اپلیکیشن‌ها به
بین گره ها، در ns-3 کاربرد همیشه یک "زمان شروع" و "توقف" دارد
زمان" مرتبط با آن است. در اکثریت قریب به اتفاق موارد، یک کاربرد تلاش نخواهد کرد
برای ایجاد یک شی پویا تا زمان آن StartApplication روش در برخی از "شروع" نامیده می شود
زمان". این برای اطمینان از پیکربندی کامل شبیه سازی قبل از برنامه است
سعی می کند هر کاری انجام دهد (اگر بخواهد به گره ای که وجود ندارد وصل شود چه اتفاقی می افتد
هنوز در طول زمان پیکربندی؟). در نتیجه، در مرحله پیکربندی نمی توانید
در صورتی که یکی از آنها به صورت پویا در طی ایجاد شده باشد، یک منبع ردیابی را به یک سینک ردیابی متصل کنید
شبیه سازی.

دو راه حل برای این معما هستند

1. یک رویداد شبیه ساز ایجاد کنید که پس از ایجاد شی پویا اجرا شود و آن را قلاب کنید
ردیابی زمانی که آن رویداد اجرا می شود. یا

2. شی پویا را در زمان پیکربندی ایجاد کنید، سپس آن را قلاب کنید و شی را به آن بدهید
سیستم مورد استفاده در زمان شبیه سازی

رویکرد دوم را در پیش گرفتیم سی سی پنجم مثال. این تصمیم ما را به ایجاد نیاز داشت
la برنامه من کاربرد، که تمام هدف آن گرفتن الف است پریز به عنوان یک پارامتر

پیاده روی: سی سی پنجم
حالا بیایید نگاهی به برنامه مثالی بیندازیم که با تشریح تراکم ساختیم
تست پنجره باز کن examples/tutorial/fifth.cc در ویرایشگر مورد علاقه شما باید ببینی
چند کد آشنا به ظاهر:

/* -*- حالت:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* این برنامه نرم افزار رایگان است. شما می توانید آن را دوباره توزیع کنید و/یا تغییر دهید
* آن را تحت شرایط مجوز عمومی عمومی گنو نسخه 2 به عنوان
* منتشر شده توسط بنیاد نرم افزار آزاد؛
*
* این برنامه به امید اینکه مفید واقع شود توزیع شده است
* اما بدون ضمانت؛ حتی بدون ضمانت ضمنی
* قابلیت خرید و فروش یا تناسب اندام برای یک هدف خاص. را ببینید
* مجوز عمومی عمومی گنو برای جزئیات بیشتر.
*
* شما باید یک کپی از مجوز عمومی عمومی گنو دریافت کرده باشید
* همراه با این برنامه؛ اگر نه، به نرم افزار آزاد بنویسید
* Foundation, Include., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#عبارتند از
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"

با استفاده از فضای نام ns3;

NS_LOG_COMPONENT_DEFINE ("FifthScriptExample")؛

این همه پوشش داده شده است، بنابراین ما آن را دوباره تکرار نمی کنیم. خطوط بعدی منبع عبارتند از
تصویر شبکه و یک نظر برای رسیدگی به مشکل توضیح داده شده در بالا با پریز.

// ================================================ ============================
//
// گره 0 گره 1
// +---------------- +-----------------
// | ns-3 TCP | | ns-3 TCP |
// +---------------- +-----------------
// | 10.1.1.1 | | 10.1.1.2 |
// +---------------- +-----------------
// | نقطه به نقطه | | نقطه به نقطه |
// +---------------- +-----------------
// | |
// +----------------------+
// 5 مگابیت بر ثانیه، 2 میلی ثانیه
//
//
// می خواهیم به تغییرات در پنجره تراکم TCP ns-3 نگاه کنیم. نیاز داریم
// برای بالا بردن یک جریان و قلاب کردن ویژگی CongestionWindow در سوکت
// فرستنده. معمولاً یکی از برنامه های روشن خاموش برای تولید a استفاده می کند
// جریان دارد، اما این چند مشکل دارد. اول، سوکت روشن و خاموش
// برنامه تا زمان شروع برنامه ایجاد نمی شود، بنابراین ما ایجاد نمی کنیم
// قادر به قلاب کردن سوکت (اکنون) در زمان پیکربندی است. دوم، حتی اگر ما
// می تواند تماسی را پس از زمان شروع ترتیب دهد، سوکت عمومی نیست بنابراین ما
// نمی توانستم به آن برسم.
//
// بنابراین، ما می‌توانیم یک نسخه ساده از برنامه روشن خاموش تهیه کنیم که چه کاری را انجام می‌دهد
// ما میخواهیم. از طرف دیگر ما به پیچیدگی روشن و خاموش کردن نیاز نداریم
// کاربرد. از طرف منهای، ما یاور نداریم، پس باید بگیریم
// کمی بیشتر درگیر جزئیات است، اما این بی اهمیت است.
//
// بنابراین ابتدا یک سوکت ایجاد می کنیم و trace connect را روی آن انجام می دهیم. سپس عبور می کنیم
// این سوکت را به سازنده برنامه ساده ما وارد می کنیم که سپس ما
// در گره منبع نصب کنید.
// ================================================ ============================
//

این نیز باید خود توضیحی باشد.

بخش بعدی اعلامیه است برنامه من کاربرد که کنار هم گذاشتیم تا اجازه دهیم
la پریز در زمان پیکربندی ایجاد شود.

کلاس MyApp: برنامه عمومی
{
عمومی:

MyApp ();
مجازی ~MyApp();

تنظیم خالی (Ptr سوکت، آدرس آدرس، uint32_t packetSize،
uint32_t nPackets، DataRate dataRate)؛

خصوصی:
virtual void StartApplication (باطل)؛
virtual void StopApplication (باطل)؛

void ScheduleTx (void);
void SendPacket (باطل)؛

Ptr m_socket;
آدرس m_peer;
uint32_t m_packetSize;
uint32_t m_nPackets;
DataRate m_dataRate;
EventId m_sendEvent;
bool m_running;
uint32_t m_packetsSent;
};

می بینید که این کلاس از the به ارث می برد ns-3 کاربرد کلاس نگاهی به
src/network/model/application.h اگر به آنچه ارثی است علاقه دارید. این برنامه من
کلاس موظف به لغو StartApplication و StopApplication مواد و روش ها. اینها
زمانی که متدها به طور خودکار فراخوانی می شوند برنامه من برای شروع و توقف ارسال داده ها لازم است
در طول شبیه سازی

شروع/توقف اپلیکیشن‌ها
ارزش آن را دارد که کمی وقت بگذارید و توضیح دهید که رویدادها در واقع چگونه شروع می شوند
سیستم. این یک توضیح نسبتاً عمیق دیگر است، و اگر اینطور نیستید، می توان آن را نادیده گرفت
برنامه ریزی برای ورود به سیستم. با این حال، در آن مفید است
بحث در مورد چگونگی برخی از بخش های بسیار مهم از ns-3 کار می کند و برخی را افشا می کند
اصطلاحات مهم اگر در حال برنامه ریزی برای پیاده سازی مدل های جدید هستید، احتمالاً می خواهید
این بخش را درک کنید

رایج ترین راه برای شروع پمپاژ رویدادها، شروع یک است کاربرد. این به عنوان انجام می شود
نتیجه خطوط آشنای زیر (امیدوارم). ns-3 متن:

برنامه های ApplicationContainer = ...
apps.Start (ثانیه (1.0));
apps.Stop (ثانیه (10.0));

کد ظرف برنامه (نگاه کنید به src/network/helper/application-container.h اگر شما
علاقه مند) از طریق برنامه ها و فراخوان های موجود در آن حلقه می زند،

app->SetStartTime (startTime)؛

به عنوان یک نتیجه از برنامه ها.شروع کنید تماس بگیرید و

app->SetStopTime (stopTime)؛

به عنوان یک نتیجه از برنامه ها.توقف زنگ زدن.

نتیجه نهایی این تماس ها این است که می خواهیم شبیه ساز را به صورت خودکار داشته باشیم
با ما تماس بگیرید اپلیکیشن‌ها به آنها بگویید که چه زمانی شروع کنند و چه زمانی متوقف شوند. در شرایطی که
برنامه من، از کلاس به ارث می برد کاربرد و لغو می کند StartApplicationو
StopApplication. اینها توابعی هستند که توسط شبیه ساز در قسمت فراخوانی می شوند
زمان مناسب. در شرایطی که برنامه من آن را خواهید یافت My App::StartApplication میکند
اولیه اتصالو اتصال بر روی سوکت، و سپس جریان داده را با فراخوانی شروع می کند
My App::SendPacket. My App::StopApplication با لغو هر بسته، تولید بسته ها را متوقف می کند
رویدادهای در انتظار ارسال و سپس سوکت را می بندد.

یکی از چیزهای خوب در مورد ns-3 این است که می توانید به طور کامل اجرا را نادیده بگیرید
جزئیات نحوه شما کاربرد به صورت خودکار توسط شبیه ساز در حالت صحیح فراخوانی می شود
زمان. اما از آنجایی که ما قبلاً به اعماق آن جسارت کرده ایم ns-3 در حال حاضر، اجازه دهید برای آن بروید.

اگر شما نگاهی به src/network/model/application.cc خواهید دید که SetStartTime روش
از کاربرد فقط متغیر عضو را تنظیم می کند m_startTime و SetStopTime روش
فقط مجموعه m_stopTime. از آنجا، بدون برخی نکات، مسیر احتمالاً به پایان خواهد رسید.

کلید انتخاب مجدد مسیر این است که بدانید یک لیست جهانی از همه آنها وجود دارد
گره ها در سیستم هر زمان که یک گره در یک شبیه سازی ایجاد می کنید، یک اشاره گر به آن گره
به جهانی اضافه می شود NodeList.

نگاهی به src/network/model/node-list.cc و جستجو برای NodeList::افزودن. عموم
اجرای ایستا به یک پیاده سازی خصوصی به نام فراخوانی می کند NodeListPriv::افزودن. این
یک ایدوم نسبتا رایج در ns-3. بنابراین، نگاهی به NodeListPriv::افزودن. شما آنجا هستید
پیدا خواهد کرد،

شبیه ساز::ScheduleWithContext (شاخص، TimeStep (0)، &Node::Initialize، node);

این به شما می گوید که هرگاه یک Node در یک شبیه سازی ایجاد شود، به عنوان یک اثر جانبی، یک فراخوانی ایجاد می شود
به آن گره شروع کردن روشی برای شما برنامه ریزی شده است که در زمان صفر اتفاق می افتد. نکن
با این حال، بیش از حد این نام را بخوانید. این بدان معنا نیست که Node شروع به کار می کند
هر چیزی، می تواند به عنوان یک تماس اطلاعاتی به گره تعبیر شود که به آن می گوید که
شبیه سازی شروع شده است، نه فراخوانی برای اقدام که به Node بگوید شروع به انجام کاری کند.

پس NodeList::افزودن به طور غیرمستقیم یک تماس را برنامه ریزی می کند Node::Initialize در زمان صفر به توصیه الف
نود جدید که شبیه سازی شروع شده است. اگر به داخل نگاه کنید src/network/model/node.h شما
با این حال، روشی به نام پیدا نمی کند Node::Initialize. معلوم می شود که
شروع کردن متد از کلاس به ارث برده شده است شیء. تمام اشیاء در سیستم می توانند باشند
هنگامی که شبیه سازی شروع می شود، اطلاع داده می شود، و اشیاء کلاس Node فقط یکی از آنها هستند
اشیاء.

نگاهی به src/core/model/object.cc بعدی و جستجو کنید Object:: مقداردهی اولیه. این کد
از آن زمان به همان اندازه که انتظار داشتید ساده نیست ns-3 اشیاء پشتیبانی
تجمع. کد در Object:: مقداردهی اولیه سپس از طریق تمام اشیاء که
با هم تجمیع شده اند و آنها را فراخوانی می کند مقداردهی اولیه کنید روش. این یک اصطلاح دیگر است
که بسیار رایج است در ns-3، که گاهی اوقات "الگوی طراحی الگو" نامیده می شود: یک عمومی
متد API غیر مجازی، که در سراسر پیاده سازی ها ثابت می ماند و a را فراخوانی می کند
روش پیاده سازی مجازی خصوصی که توسط زیر کلاس ها به ارث برده و پیاده سازی می شود.
اسامی معمولاً چیزی شبیه به این هستند MethodName برای API عمومی و DoMethodName برای
API خصوصی

این به ما می گوید که باید به دنبال a باشیم Node::DoInitialize روش در
src/network/model/node.cc برای روشی که مسیر ما را ادامه خواهد داد. اگر شما محل
کد، روشی را پیدا خواهید کرد که از طریق تمام دستگاه های موجود در Node و سپس حلقه می زند
همه برنامه های موجود در Node calling دستگاه -> مقداردهی اولیه و application->Initialize
بود.

ممکن است قبلاً آن کلاس ها را بدانید دستگاه و کاربرد هر دو از کلاس ارث می برند شیء
و بنابراین گام بعدی این است که ببینیم چه زمانی چه اتفاقی می افتد کاربرد::DoInitialize is
تماس گرفت. نگاهی به src/network/model/application.cc و خواهید یافت:

از درجه اعتبار ساقط
برنامه کاربردی::DoInitialize (باطل)
{
m_startEvent = Simulator::Schedule (m_startTime، &Application::StartApplication، این)؛
if (m_stopTime != TimeStep (0))
{
m_stopEvent = Simulator::Schedule (m_stopTime، &Application::StopApplication، این)؛
}
Object::DoInitialize ();
}

در اینجا، بالاخره به انتهای مسیر می رسیم. اگر همه چیز را صاف نگه داشته اید، زمانی که شما
اجرا کردن ns-3 کاربرد، برنامه جدید شما از کلاس به ارث می رسد کاربرداست. شما
نادیده گرفتن StartApplication و StopApplication روش ها و مکانیسم هایی برای
شروع و توقف جریان داده ها از دستگاه جدید شما کاربرد. هنگامی که یک گره است
ایجاد شده در شبیه سازی، به جهانی اضافه می شود NodeList. عمل اضافه کردن یک گره به
این NodeList باعث می شود که یک رویداد شبیه ساز برای زمان صفر برنامه ریزی شود که زمان را فراخوانی می کند
Node::Initialize روش گره تازه اضافه شده که در هنگام شروع شبیه سازی فراخوانی می شود.
از آنجایی که یک Node از آن ارث می برد شیء، این به نام Object:: مقداردهی اولیه روش در گره
که به نوبه خود به نام مقداردهی اولیه کنید روش ها در همه اشیاء تجمیع شده به
گره (مدل های تحرک فکر کنید). از زمان گره شیء لغو کرده است مقداردهی اولیه کنید، که
روش زمانی فراخوانی می شود که شبیه سازی شروع شود. را Node::DoInitialize متد را فرا می خواند
شروع کردن روش های همه اپلیکیشن‌ها روی گره از آنجا که اپلیکیشن‌ها همچنین
اشیاء، این باعث می شود کاربرد::DoInitialize به نام. چه زمانی
کاربرد::DoInitialize نامیده می شود، رویدادها را برای StartApplication و
StopApplication تماس می گیرد کاربرد. این تماس ها برای شروع و توقف آن طراحی شده اند
جریان داده از کاربرد

این یک سفر نسبتا طولانی دیگر بوده است، اما فقط یک بار باید انجام شود و شما اکنون
یک قطعه بسیار عمیق دیگر را درک کنید ns-3.

La برنامه من کاربرد
La برنامه من کاربرد البته نیاز به سازنده و تخریب کننده دارد:

My App::MyApp ()
: m_socket (0)،
m_peer ()،
m_packetSize (0)،
m_nPackets (0)،
m_dataRate (0)،
m_sendEvent ()،
m_running (نادرست)،
m_packetsSent (0)
{
}

My App::~MyApp()
{
m_socket = 0;
}

وجود بیت بعدی کد دلیل اصلی نوشتن این مطلب است کاربرد in
اولین مکان.

از درجه اعتبار ساقط
My App::Setup (Ptr سوکت، آدرس آدرس، uint32_t packetSize،
uint32_t nPackets، DataRate dataRate)
{
m_socket = سوکت;
m_peer = آدرس
m_packetSize = packetSize;
m_nPackets = nPackets;
m_dataRate = نرخ داده;
}

این کد باید کاملاً گویا باشد. ما فقط متغیرهای عضو را مقداردهی اولیه می کنیم.
نکته مهم از منظر ردیابی است Ptr پریز که ما
برای ارائه به برنامه در طول زمان پیکربندی مورد نیاز است. به یاد بیاورید که ما می رویم
برای ایجاد پریز به عنوان یک TcpSocket (که توسط TcpNewReno) و آن را قلاب کنید
"CngestionWindow" منبع ردیابی قبل از ارسال آن به برپایی روش.

از درجه اعتبار ساقط
My App::StartApplication (باطل)
{
m_running = درست است.
m_packetsSent = 0;
m_socket->Bind ();
m_socket->Connect (m_peer);
SendPacket ();
}

کد بالا پیاده سازی لغو شده است برنامه::StartApplication که خواهد شد
به طور خودکار توسط شبیه ساز برای شروع ما فراخوانی می شود کاربرد در حال اجرا در مناسب
زمان. شما می توانید ببینید که آن را انجام می دهد پریز اتصال عمل. اگر آشنایی دارید
برکلی سوکتز این نباید تعجب آور باشد. این کار مورد نیاز را در محلی انجام می دهد
سمت اتصال درست همانطور که ممکن است انتظار داشته باشید. به شرح زیر اتصال آنچه هست را انجام خواهد داد
برای برقراری ارتباط با TCP در نشانی: m_peer. اکنون باید روشن شود
چرا ما باید مقدار زیادی از این را به زمان شبیه سازی موکول کنیم، زیرا اتصال نیاز دارد
یک شبکه کاملاً کارآمد برای تکمیل. پس از اتصالاز کاربرد سپس شروع می شود
ایجاد رویدادهای شبیه سازی با فراخوانی SendPacket.

بیت بعدی کد به توضیح می دهد کاربرد چگونه ایجاد رویدادهای شبیه سازی را متوقف کنیم.

از درجه اعتبار ساقط
My App::StopApplication (باطل)
{
m_running = نادرست;

if (m_sendEvent.IsRunning ())
{
شبیه ساز::لغو (m_sendEvent);
}

اگر (m_socket)
{
m_socket->Close ();
}
}

هر بار که یک رویداد شبیه سازی برنامه ریزی می شود، یک واقعه خلق شده است. اگر واقعه در انتظار است
اجرا یا اجرا، روش آن در حال اجراست بر خواهد گشت درست. در این کد اگر
در حال اجراست() درست است، ما لغو کردن رویدادی که آن را از رویداد شبیه ساز حذف می کند
صف با انجام این کار، زنجیره رویدادهایی را می‌شکنیم کاربرد برای نگه داشتن استفاده می کند
ارسال آن بسته ها و کاربرد ساکت می شود بعد از اینکه ساکت کردیم کاربرد we
نزدیک سوکتی که اتصال TCP را قطع می کند.

سوکت در واقع در تخریبگر حذف می شود که m_socket = 0 اجرا می شود. این
آخرین ارجاع به Ptr زیرین را حذف می کند که باعث تخریب کننده از
آن شیئی که باید فراخوانی شود.

به یاد بیاورید StartApplication نام SendPacket برای شروع زنجیره ای از رویدادهایی که توصیف می کند
la کاربرد رفتار.

از درجه اعتبار ساقط
My App::SendPacket (باطل)
{
Ptr بسته = ایجاد (m_packetSize)؛
m_socket->Send (packet);

if (++m_packetsSent <m_nPackets)
{
ScheduleTx ();
}
}

اینجا، شما آن را می بینید SendPacket همین کار را می کند الف را ایجاد می کند بسته و سپس یک را انجام می دهد ارسال
که اگر برکلی سوکتز را بشناسید، احتمالا همان چیزی است که انتظار داشتید ببینید.

مسئولیت آن است کاربرد برای حفظ برنامه ریزی زنجیره رویدادها، بنابراین
خطوط بعدی تماس بگیرید ScheduleTx برای برنامه ریزی یک رویداد انتقال دیگر (الف SendPacket) تا
کاربرد تصمیم می گیرد که به اندازه کافی ارسال کرده است.

از درجه اعتبار ساقط
My App::ScheduleTx (باطل)
{
اگر (m_running)
{
زمان tNext (ثانیه (m_packetSize * 8 / static_cast (m_dataRate.GetBitRate ())));
m_sendEvent = Simulator::Schedule (tNext، &MyApp::SendPacket، این)؛
}
}

اینجا، شما آن را می بینید ScheduleTx دقیقا همین کار را می کند اگر کاربرد در حال اجرا است (اگر
StopApplication فراخوانی نشده است) یک رویداد جدید را برنامه ریزی می کند که تماس می گیرد SendPacket
از نو. هشدار خوان چیزی را می بیند که کاربران جدید را نیز جذب می کند. نرخ داده
از کاربرد فقط همین است هیچ ربطی به نرخ داده یک منبع اصلی ندارد
کانال. این نرخی است که در آن کاربرد بیت ها را تولید می کند. وارد نمی شود
هر سرباری را برای پروتکل‌ها یا کانال‌های مختلفی که برای انتقال استفاده می‌کند، حساب کند
داده ها. اگر نرخ داده یک را تنظیم کنید کاربرد به همان نرخ داده ای که زمینه شما دارد
کانال در نهایت یک سرریز بافر دریافت خواهید کرد.

پی گیری غرق
تمام هدف این تمرین این است که ردیابی تماس های برگشتی از TCP را نشان دهد
پنجره ازدحام به روز شده است. قطعه کد بعدی کد مربوطه را پیاده سازی می کند
سینک ردیابی:

باطل استاتیک
CwndChange (uint32_t oldCwnd، uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
}

اکنون این باید برای شما بسیار آشنا باشد، بنابراین ما به جزئیات آن نمی پردازیم. این تابع
فقط زمان شبیه سازی فعلی و مقدار جدید پنجره تراکم را هر بار ثبت می کند
زمان تغییر آن احتمالاً می توانید تصور کنید که می توانید خروجی حاصل را بارگذاری کنید
وارد یک برنامه گرافیکی (gnuplot یا اکسل) شوید و بلافاصله یک نمودار زیبا از آن را ببینید
رفتار پنجره ازدحام در طول زمان

ما یک trace sink جدید اضافه کردیم تا نشان دهیم بسته‌ها کجا ریخته می‌شوند. ما یک خطا اضافه می کنیم
به این کد نیز مدل دهید، بنابراین ما می‌خواستیم این کار را نشان دهیم.

باطل استاتیک
RxDrop (Ptr پ)
{
NS_LOG_UNCOND ("RxDrop در " << شبیه ساز::اکنون ().GetSeconds ());
}

این سینک ردیابی به منبع ردیابی "PhyRxDrop" نقطه به نقطه متصل خواهد شد.
NetDevice. این منبع ردیابی زمانی فعال می شود که یک بسته توسط لایه فیزیکی a رها شود
NetDevice. اگر یک انحراف کوچک به سمت منبع انجام دهید
(src/point-to-point/model/point-to-point-net-device.cc) خواهید دید که این اثر
منبع اشاره می کند PointToPointNetDevice::m_phyRxDropTrace. اگر بعد به داخل نگاه کنید
src/point-to-point/model/point-to-point-net-device.h برای این متغیر عضو، شما
دریابید که به عنوان a اعلام شده است TracedCallback بسته> >. این باید به شما بگوید
که هدف برگشت فراخوان باید تابعی باشد که void را برمی گرداند و یک تک می گیرد
پارامتر که a است Ptr بسته> (با فرض استفاده از ConnectWithoutContext) -- فقط
آنچه در بالا داریم

اصلی برنامه
کد زیر باید تا به حال برای شما بسیار آشنا باشد:

INT
اصلی (int argc، char *argv[])
{
گره های NodeContainer.
nodes.Create (2);

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("تاخیر"، StringValue ("2 میلی ثانیه"));

دستگاه های NetDeviceContainer؛
دستگاه ها = pointToPoint.Install (گره ها);

این دو گره با یک کانال نقطه به نقطه بین آنها ایجاد می کند، درست همانطور که در نشان داده شده است
تصویر در ابتدای فایل

چند خط کد بعدی چیز جدیدی را نشان می دهد. اگر ارتباطی را ردیابی کنیم که رفتار می کند
به طور کامل، ما با یک پنجره ازدحام به طور یکنواخت رو به افزایش خواهیم بود. برای دیدن هر کدام
رفتار جالب، ما واقعاً می خواهیم خطاهای پیوند را معرفی کنیم که بسته ها را رها می کند.
باعث ایجاد ACK های تکراری شده و رفتارهای جالب تر پنجره تراکم را تحریک می کند.

ns-3 فراهم می کند ErrorModel اشیایی که می توان به آنها متصل شد کانال ها. ما در حال استفاده از
RateErrorModel که به ما اجازه می دهد تا خطاها را در a وارد کنیم کانال در یک معین نرخ.

Ptr em = CreateObject ()؛
em->SetAttribute ("ErrorRate"، DoubleValue (0.00001));
devices.Get (1)->SetAttribute ("ReceiveErrorModel"، PointerValue (em));

کد بالا نمونه a RateErrorModel شیء، و ما "ErrorRate" را تنظیم می کنیم صفت
به مقدار مورد نظر سپس نمونه حاصل را تنظیم می کنیم RateErrorModel به عنوان خطا
مدل استفاده شده توسط نقطه به نقطه NetDevice. این به ما مقداری ارسال مجدد و
طرح ما را کمی جالب تر کنید.

پشته InternetStackHelper;
stack.Install (گره ها)؛

آدرس Ipv4AddressHelper;
address.SetBase ("10.1.1.0"، "255.255.255.252");
رابط های Ipv4InterfaceContainer = address.Assign (دستگاه ها)؛

کد بالا باید آشنا باشد. پشته های اینترنت را روی دو گره ما نصب می کند و
رابط ایجاد می کند و آدرس های IP را برای دستگاه های نقطه به نقطه اختصاص می دهد.

از آنجایی که ما از TCP استفاده می کنیم، برای دریافت TCP به چیزی در گره مقصد نیاز داریم
اتصالات و داده ها را PacketSink کاربرد معمولا در استفاده می شود ns-3 برای آن
هدف

uint16_t sinkPort = 8080;
آدرس sinkAddress (InetSocketAddress(interfaces.GetAddress (1)، sinkPort));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory"،
InetSocketAddress (Ipv4Address::GetAny ()، sinkPort));
ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
sinkApps.Start (ثانیه (0.));
sinkApps.Stop (ثانیه (20.));

همه اینها باید آشنا باشد، به استثنای

PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory"،
InetSocketAddress (Ipv4Address::GetAny ()، sinkPort));

این کد یک نمونه را نشان می دهد PacketSinkHelper و به آن می گوید که با استفاده از کلاس سوکت ایجاد کند
ns3::TcpSocketFactory. این کلاس یک الگوی طراحی به نام "کارخانه اشیاء" را پیاده سازی می کند.
که مکانیزمی است که معمولاً برای تعیین کلاس مورد استفاده برای ایجاد اشیاء در an استفاده می شود
روش انتزاعی در اینجا، به جای اینکه خود اشیا را بسازید، آن را ارائه می کنید
PacketSinkHelper رشته ای که a را مشخص می کند TypeId رشته برای ایجاد یک شی که
سپس می تواند به نوبه خود برای ایجاد نمونه هایی از اشیاء ایجاد شده توسط کارخانه استفاده شود.

پارامتر باقیمانده به آن می گوید کاربرد کدام آدرس و پورت باید اتصال به.

دو خط کد بعدی سوکت را ایجاد می کند و منبع ردیابی را به هم متصل می کند.

Ptr ns3TcpSocket = Socket::CreateSocket (nodes.Get (0)
TcpSocketFactory::GetTypeId ());
ns3TcpSocket->TraceConnectWithoutContext ("CngestionWindow"،
MakeCallback (&CwndChange))؛

دستور اول تابع عضو استاتیک را فراخوانی می کند سوکت::CreateSocket و فراهم می کند
گره و یک صریح TypeId برای کارخانه شی که برای ایجاد سوکت استفاده می شود. این یک است
تماس سطح کمی پایین تر از PacketSinkHelper در بالا تماس بگیرید و از C++ صریح استفاده کنید
به جای یکی که با یک رشته ارجاع داده می شود تایپ کنید. در غیر این صورت، از نظر مفهومی یکسان است
چیز.

هنگامی که TcpSocket ایجاد شده و به Node متصل می شود، می توانیم استفاده کنیم
TraceConnectWithoutContext برای اتصال منبع ردیابی CongestionWindow به سینک ردیابی ما.

به یاد بیاورید که ما an را کدگذاری کردیم کاربرد بنابراین ما می توانیم آن را بگیریم پریز ما فقط (در طول
زمان پیکربندی) و از آن در زمان شبیه سازی استفاده کنید. اکنون باید آن را مثال بزنیم
کاربرد. ما برای ایجاد کمکی برای مدیریت مشکلی نداشتیم کاربرد so
ما باید آن را به صورت دستی ایجاد و نصب کنیم. این در واقع بسیار آسان است:

Ptr app = CreateObject ()؛
app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"))؛
nodes.Get (0) ->AddApplication (app);
برنامه -> شروع (ثانیه (1.))؛
برنامه -> توقف (ثانیه (20.))؛

خط اول یک را ایجاد می کند شیء از نوع برنامه من -- ما کاربرد. خط دوم می گوید
la کاربرد چی پریز برای استفاده، به چه آدرسی متصل شوید، به چه مقدار داده ارسال کنید
هر رویداد ارسال، تعداد رویدادهای ارسالی برای تولید و سرعت تولید داده ها
از آن اتفاقات

بعد، ما به صورت دستی اضافه می کنیم برنامه من کاربرد به Node مبدا و صریحاً آن را فراخوانی کنید
آغاز و توقف روش ها بر روی کاربرد به آن بگویید که چه زمانی شروع کند و چه زمانی انجامش را متوقف کند
چیز.

ما باید در واقع اتصال را از گیرنده نقطه به نقطه انجام دهیم NetDevice رها کردن رویداد
به ما RxDrop اکنون تماس بگیرید

دستگاه ها. دریافت (1)->TraceConnectWithoutContext("PhyRxDrop"، MakeCallback (&RxDrop));

اکنون باید واضح باشد که ما در حال دریافت ارجاع به دریافت هستیم گره NetDevice
از محفظه آن و اتصال منبع ردیابی تعریف شده توسط ویژگی "PhyRxDrop" در
آن دستگاه به سینک ردیابی RxDrop.

در نهایت به شبیه ساز می گوییم که هر کدام را لغو کند اپلیکیشن‌ها و فقط پردازش را متوقف کنید
رویدادها در 20 ثانیه پس از شبیه سازی.

شبیه ساز::توقف (ثانیه(20))؛
شبیه ساز::Run ();
شبیه ساز::Destroy ();

0 بازگشت؛
}

به یاد بیاورید که به محض شبیه ساز::اجرا کنید نامیده می شود، زمان پیکربندی به پایان می رسد، و شبیه سازی
زمان آغاز می شود تمام کارهایی که ما با ایجاد آن ارکستر کردیم کاربرد و آموزش آن
نحوه اتصال و ارسال داده در واقع در طول این فراخوانی تابع اتفاق می افتد.

به محض شبیه ساز::اجرا کنید برمی گردد، شبیه سازی کامل شده است و ما وارد Teardown می شویم
فاز. در این مورد، شبیه ساز:: نابود کردن از جزئیات بد مراقبت می کند و ما تازه برمی گردیم
یک کد موفقیت پس از تکمیل آن

محل دویدن و پیاده روی سی سی پنجم
از آنجایی که ما فایل را ارائه کرده ایم سی سی پنجم برای شما، اگر توزیع خود را ساخته اید (در
حالت اشکال زدایی از آنجایی که استفاده می کند NS_LOG -- به یاد بیاورید که ساخت های بهینه شده بهینه می شوند NS_LOG) آی تی
منتظر اجرای شما خواهد بود

$ ./waf -- پنجمین را اجرا کنید
Waf: ورود به فهرست "/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build"
Waf: خروج از فهرست «/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build»
"ساخت" با موفقیت به پایان رسید (0.684s)
1 536
1.0093 1072
1.01528 1608
1.02167 2144
...
1.11319 8040
1.12151 8576
1.12983 9112
RxDrop در 1.13696
...

احتمالاً می‌توانید فوراً نقطه ضعف استفاده از هر نوع چاپ را در آثار خود مشاهده کنید.
ما آن پیام‌های واف اضافی را در سراسر اطلاعات جالبمان چاپ می‌کنیم
با آن پیام های RxDrop. ما به زودی آن را برطرف خواهیم کرد، اما من مطمئن هستم که شما نمی توانید صبر کنید تا ببینید
نتایج همه این کارها اجازه دهید آن خروجی را به فایلی به نام تغییر مسیر دهیم cwnd.dat:

$ ./waf --run fifth > cwnd.dat 2>&1

اکنون "cwnd.dat" را در ویرایشگر مورد علاقه خود ویرایش کنید و وضعیت ساخت waf را حذف کرده و رها کنید
خطوط، تنها داده های ردیابی شده را باقی می گذارند (شما همچنین می توانید در مورد آن نظر دهید
TraceConnectWithoutContext("PhyRxDrop"، MakeCallback (&RxDrop))؛ در اسکریپت خلاص شوید
از قطره به همین راحتی چاپ می شود.

اکنون می‌توانید gnuplot را اجرا کنید (اگر آن را نصب کرده‌اید) و به آن بگویید تا مقداری زیبا تولید کند
تصاویر:

$ gnuplot
gnuplot> تنظیم ترمینال png اندازه 640,480
gnuplot> خروجی را تنظیم کنید "cwnd.png"
gnuplot> رسم "cwnd.dat" را با استفاده از عنوان 1:2 "پنجره ازدحام" با نقاط خطوط ترسیم کنید.
gnuplot> خروج

اکنون باید نموداری از پنجره تراکم نسبت به زمان نشستن در فایل داشته باشید
"cwnd.png" loading="lazy" که به نظر می رسد:
[تصویر]

با استفاده از سطح متوسط یاران
در بخش قبلی، ما نشان دادیم که چگونه یک منبع ردیابی را قلاب کنیم و امیدوارانه به دست آوریم
اطلاعات جالب از یک شبیه سازی شاید به خاطر بیاورید که ما تماس گرفتیم
ورود به خروجی استاندارد با استفاده از std::out یک "ساز بلانت" خیلی زودتر در این
فصل ما همچنین در مورد اینکه چگونه تجزیه خروجی گزارش به ترتیب مشکل دارد، نوشتیم
برای جداسازی اطلاعات جالب شاید برای شما هم پیش آمده باشد که ما خیلی خرج کردیم
زمان اجرای مثالی که تمام مشکلاتی را که ما مدعی رفع آن هستیم را نشان می دهد
la ns-3 سیستم ردیابی! شما درست می گویید. اما، ما را تحمل کن ما هنوز تمام نشده ایم.

یکی از مهم ترین کارهایی که می خواهیم انجام دهیم این است که به راحتی توانایی داشته باشیم
کنترل میزان خروجی خروجی از شبیه سازی؛ و ما همچنین می خواهیم آنها را نجات دهیم
داده ها را در یک فایل قرار دهید تا بتوانیم بعداً به آن مراجعه کنیم. ما می توانیم از کمک کننده های ردیابی سطح متوسط ​​استفاده کنیم
ارائه شده در ns-3 برای انجام این کار و تکمیل تصویر.

ما یک اسکریپت ارائه می کنیم که رویدادهای تغییر و رها کردن cwnd را که در مثال توسعه داده شده است می نویسد
سی سی پنجم به دیسک در فایل های جداگانه. تغییرات cwnd به عنوان ASCII جدا شده از تب ذخیره می شوند
فایل و رویدادهای drop در یک فایل PCAP ذخیره می شوند. تغییرات برای تحقق این امر هستند
کاملا کوچک.

پیاده روی: سی سی ششم
بیایید نگاهی به تغییرات مورد نیاز برای رفتن بیندازیم سی سی پنجم به سی سی ششم. باز کن
examples/tutorial/sixth.cc در ویرایشگر مورد علاقه شما شما می توانید اولین تغییر را ببینید
جستجو برای CwndChange. متوجه خواهید شد که ما امضاها را برای ردیابی تغییر داده ایم
سینک می شود و به هر سینک یک خط اضافه کرده اند که اطلاعات ردیابی شده را در a می نویسد
جریانی که یک فایل را نشان می دهد.

باطل استاتیک
CwndChange (Ptr جریان، uint32_t oldCwnd، uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << شبیه ساز::اکنون ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}

باطل استاتیک
RxDrop (Ptr فایل، Ptr پ)
{
NS_LOG_UNCOND ("RxDrop در " << شبیه ساز::اکنون ().GetSeconds ());
file->Write(Simulator::Now(), p);
}

ما یک پارامتر "stream" را به آن اضافه کرده ایم CwndChange سینک ردیابی این یک شی است که
یک جریان خروجی C++ را نگه می دارد (ایمن زنده نگه می دارد). به نظر می رسد که این بسیار ساده است
شی، اما یکی که مسائل مادام العمر را برای جریان مدیریت می کند و مشکلی را حل می کند که حتی
کاربران باتجربه ++C با آنها برخورد می کنند. به نظر می رسد که سازنده کپی برای std::ostream
خصوصی مشخص شده است. این به این معنی است که std::ostreams از معناشناسی ارزشی تبعیت نمی کنند و نمی توانند
در هر مکانیزمی که نیاز به کپی کردن جریان دارد استفاده شود. این شامل ns-3
سیستم برگشت تماس، که همانطور که به یاد دارید، به اشیایی نیاز دارد که از معنای ارزشی پیروی کنند.
همچنین توجه داشته باشید که ما خط زیر را در قسمت اضافه کرده ایم CwndChange سینک ردیابی
پیاده سازی:

*stream->GetStream () << شبیه ساز::اکنون ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;

اگر این کد را جایگزین کنید بسیار آشنا خواهد بود *stream->GetStream () با std::out، به عنوان
که در:

std::cout << شبیه ساز::اکنون ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;

این نشان می دهد که Ptr واقعاً فقط در اطراف یک
std::از جریان برای شما، و می توانید آن را در اینجا مانند هر جریان خروجی دیگری استفاده کنید.

وضعیت مشابهی در آن اتفاق می افتد RxDrop با این تفاوت که شیء در حال عبور (الف
Ptr) یک فایل PCAP را نشان می دهد. یک لاینر در سینک ردیابی به وجود دارد
یک مهر زمانی بنویسید و محتویات بسته در فایل PCAP رها شود:

file->Write(Simulator::Now(), p);

البته، اگر ما اشیایی داریم که دو فایل را نشان می دهند، باید آنها را در جایی ایجاد کنیم
و همچنین باعث انتقال آنها به رد سینک می شود. اگر در اصلی عملکرد،
کد جدیدی برای انجام این کار پیدا خواهید کرد:

AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext ("CngestionWindow"، MakeBoundCallback (&CwndChange، جریان));

...

PcapHelper pcapHelper;
Ptr file = pcapHelper.CreateFile ("sixth.pcap"، std::ios::out، PcapHelper::DLT_PPP);
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop"، MakeBoundCallback (&RxDrop، فایل));

در بخش اول قطعه کد بالا، ما در حال ایجاد فایل ردیابی ASCII هستیم.
ایجاد یک شی مسئول مدیریت آن و استفاده از گونه‌ای از callback
تابع ایجاد برای ترتیب دادن شیء به سینک منتقل شود. ردیابی ASCII ما
کمک‌کنندگان مجموعه‌ای غنی از توابع را برای آسان کردن استفاده از فایل‌های متنی (ASCII) ارائه می‌کنند. ما هستیم
فقط می‌خواهیم استفاده از تابع ایجاد جریان فایل را در اینجا نشان دهیم.

La CreateFileStream تابع اساساً به نمونه a است std::از جریان شی و
یک فایل جدید ایجاد کنید (یا یک فایل موجود را کوتاه کنید). این std::از جریان در یک بسته بندی شده است
ns-3 شی برای مدیریت مادام العمر و حل مشکل سازنده کپی.

سپس این را می گیریم ns-3 شیء نشان دهنده فایل و ارسال آن به MakeBoundCallback().
این تابع درست مانند یک تماس برگشتی ایجاد می کند MakeCallback()، اما یک مقدار جدید را به آن "پیوند" می کند
پاسخ به تماس این مقدار به عنوان اولین آرگومان به callback قبل از آن اضافه می شود
به نام

اساسا، MakeBoundCallback(&CwndChange, جریان) باعث می شود منبع ردیابی به اضافه شود
پارامتر "جریان" اضافی در جلوی لیست پارامترهای رسمی قبل از فراخوانی
پاسخ به تماس این امضای مورد نیاز را تغییر می دهد CwndChange سینک برای مطابقت با یکی
نشان داده شده در بالا، که شامل پارامتر "اضافی" است Ptr جریان.

در بخش دوم کد در قطعه بالا، a را نمونه می کنیم PcapHelper برای انجام
همان کاری که برای فایل ردیابی PCAP ما انجام دادیم AsciiTraceHelper. خط از
کد ،

Ptr file = pcapHelper.CreateFile ("sixth.pcap"،
"w"، PcapHelper::DLT_PPP);

یک فایل PCAP به نام "sixth.pcap" با حالت فایل "w" ایجاد می کند. این به این معنی است که فایل جدید
اگر فایل موجود با آن نام پیدا شود کوتاه می شود (محتوا حذف می شود). آخرین
پارامتر "نوع پیوند داده" فایل PCAP جدید است. اینها همان PCAP هستند
انواع پیوند داده های کتابخانه تعریف شده در bpf.h اگر با PCAP آشنا هستید. در این مورد،
DLT_PPP نشان می دهد که فایل PCAP حاوی بسته هایی با پیشوند نقطه به است
سرصفحه های نقطه این درست است زیرا بسته ها از دستگاه نقطه به نقطه ما می آیند
راننده. سایر انواع پیوندهای داده رایج DLT_EN10MB (10 مگابایت اترنت) مناسب برای csma هستند.
دستگاه ها و DLT_IEEE802_11 (IEEE 802.11) مناسب برای دستگاه های فای. اینها تعریف شده است
in src/network/helper/trace-helper.h اگر علاقه مند به دیدن لیست هستید را
ورودی‌های فهرست با ورودی‌های موجود مطابقت دارند bpf.h اما ما آنها را کپی می کنیم تا از منبع PCAP جلوگیری کنیم
وابستگی.

A ns-3 شیئی که نشان دهنده فایل PCAP است از آن بازگردانده می شود ایجاد فایل و در بند استفاده می شود
پاسخ تماس دقیقاً همانطور که در مورد ASCII بود.

یک مسیر انحرافی مهم: توجه به این نکته مهم است که حتی اگر هر دوی این اشیا هستند
به روش های بسیار مشابه اعلام شد،

Ptr فایل ...
Ptr جریان ...

اشیاء زیرین کاملاً متفاوت هستند. به عنوان مثال Ptr هست یک
اشاره گر هوشمند به یک ns-3 شیئی که یک چیز نسبتاً سنگین وزن است که پشتیبانی می کند
ویژگی ها و در سیستم پیکربندی یکپارچه شده است. را Ptr، در
از سوی دیگر، یک اشاره گر هوشمند به یک شی شمارش مرجع است که بسیار سبک وزن است
چیز. به یاد داشته باشید که قبل از هر گونه فرضی، به شی مورد اشاره خود نگاه کنید
در مورد "قدرت"هایی که شی ممکن است داشته باشد.

مثلاً نگاهی بیندازید src/network/utils/pcap-file-wrapper.h در توزیع و
اطلاع،

کلاس PcapFileWrapper: Public Object

آن کلاس PcapFileWrapper است ns-3 شیء به موجب وراثت آن. سپس نگاه کنید
src/network/model/output-stream-wrapper.h و توجه کنید،

کلاس OutputStreamWrapper: عمومی
SimpleRefCount

که این شی یک نیست ns-3 اصلاً شیء، "صرفا" یک شیء ++C است که اتفاق می افتد
پشتیبانی از شمارش مرجع نفوذی

نکته اینجاست که فقط به این دلیل که شما خوانده اید Ptr لزوما به این معنی نیست
که چیزی است ns-3 شیئی که می توانید از آن آویزان شوید ns-3 برای مثال صفات.

حالا به مثال برگردیم. اگر این مثال را بسازید و اجرا کنید،

$ ./waf -- ششم را اجرا کنید

خواهید دید که همان پیغام هایی را خواهید دید که زمانی که «پنجم» را اجرا کردید، اما دو فایل جدید ظاهر خواهند شد
در دایرکتوری سطح بالای شما ظاهر می شود ns-3 توزیع.

ششم.cwnd ششم.pcap

از آنجایی که "sixth.cwnd" یک فایل متنی ASCII است، می توانید آن را با آن مشاهده کنید گربه یا فایل مورد علاقه شما
بیننده

1 0 536
1.0093 536 1072
1.01528 1072 1608
1.02167 1608 2144
...
9.69256 5149 5204
9.89311 5204 5259

شما یک فایل جدا شده از برگه با مهر زمانی، یک پنجره تراکم قدیمی و یک جدید دارید
پنجره تراکم مناسب برای وارد کردن مستقیم به برنامه طرح شما. وجود ندارد
پرینت های اضافی در فایل، بدون تجزیه یا ویرایش مورد نیاز است.

از آنجایی که "sixth.pcap" یک فایل PCAP است، می توانید آن را با آن مشاهده کنید tcpdump.

خواندن از فایل sixth.pcap، نوع پیوند PPP (PPP)
1.136956 IP 10.1.1.1.49153 > 10.1.1.2.8080: Flags [.], seq 17177:17681, ack 1, win 32768, option [TS val 1133 ecr 1127, eol طول]
1.403196 IP 10.1.1.1.49153 > 10.1.1.2.8080: Flags [.], seq 33280:33784, ack 1, win 32768, option [TS val 1399 ecr 1394, eol طول]
...
7.426220 IP 10.1.1.1.49153 > 10.1.1.2.8080: Flags [.], seq 785704:786240, ack 1, win 32768, option [TS val 7423 ecr 7421, eol طول]
9.630693 IP 10.1.1.1.49153 > 10.1.1.2.8080: Flags [.], seq 882688:883224, ack 1, win 32768, option [TS val 9620 ecr 9618, eol طول]

شما یک فایل PCAP با بسته هایی دارید که در شبیه سازی رها شده اند. وجود ندارد
بسته های دیگری در فایل موجود است و هیچ چیز دیگری برای ایجاد حیات وجود ندارد
دشواری.

این یک سفر طولانی بوده است، اما ما اکنون در نقطه ای هستیم که می توانیم از آن قدردانی کنیم ns-3
سیستم ردیابی ما رویدادهای مهم را از وسط اجرای TCP بیرون کشیده ایم
و یک درایور دستگاه ما آن رویدادها را مستقیماً در فایل‌های قابل استفاده با معمولاً شناخته شده ذخیره کردیم
ابزار. ما این کار را بدون تغییر هیچ کد اصلی انجام دادیم و این کار را در داخل انجام دادیم
فقط 18 خط کد:

باطل استاتیک
CwndChange (Ptr جریان، uint32_t oldCwnd، uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << شبیه ساز::اکنون ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}

...

AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext ("CngestionWindow"، MakeBoundCallback (&CwndChange، جریان));

...

باطل استاتیک
RxDrop (Ptr فایل، Ptr پ)
{
NS_LOG_UNCOND ("RxDrop در " << شبیه ساز::اکنون ().GetSeconds ());
file->Write(Simulator::Now(), p);
}

...

PcapHelper pcapHelper;
Ptr file = pcapHelper.CreateFile ("sixth.pcap"، "w"، PcapHelper::DLT_PPP);
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop"، MakeBoundCallback (&RxDrop، فایل));

پی گیری یاران
La ns-3 کمک‌کننده‌های ردیابی محیطی غنی برای پیکربندی و انتخاب متفاوت فراهم می‌کنند
ردیابی رویدادها و نوشتن آنها در فایل ها. در بخش های قبلی، در درجه اول
BuildingTopologies، ما انواع مختلفی از روش های ردیابی کمکی طراحی شده را دیده ایم
برای استفاده در سایر کمک های (دستگاه).

شاید دیدن برخی از این تغییرات را به خاطر بیاورید:

pointToPoint.EnablePcapAll ("دوم");
pointToPoint.EnablePcap ("دوم"، p2pNodes.Get (0)->GetId ()، 0);
csma.EnablePcap ("سوم"، csmaDevices.Get (0)، true);
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

با این حال، آنچه ممکن است واضح نباشد این است که یک مدل ثابت برای همه آنها وجود دارد
روش های مرتبط با ردیابی موجود در سیستم اکنون کمی وقت می گذاریم و نگاهی می اندازیم
در "تصویر بزرگ".

در حال حاضر دو مورد استفاده اولیه از کمک ردیابی در وجود دارد ns-3: کمک کننده های دستگاه
و کمک کنندگان پروتکل کمک‌کنندگان دستگاه به مشکل تعیین ردیابی می‌پردازند
باید از طریق یک جفت (گره، دستگاه) فعال شود. برای مثال، ممکن است بخواهید مشخص کنید
که ردیابی PCAP باید در یک دستگاه خاص در یک گره خاص فعال شود. این
از دنبال می شود ns-3 مدل مفهومی دستگاه و همچنین مدل های مفهومی از
کمک های دستگاه های مختلف به طور طبیعی به دنبال این، فایل های ایجاد شده به دنبال a
- - کنوانسیون نامگذاری

کمک‌کنندگان پروتکل به مشکل تعیین ردیابی از طریق آن می‌پردازند
یک جفت پروتکل و رابط این نتیجه از ns-3 مفهومی پشته پروتکل
مدل، و همچنین مدل‌های مفهومی کمک‌کننده‌های پشته اینترنت. به طور طبیعی، ردیابی
فایل ها باید به دنبال a - - کنوانسیون نامگذاری

بنابراین کمک کننده های ردیابی به طور طبیعی در یک طبقه بندی دو بعدی قرار می گیرند. وجود دارد
نکات ظریفی که مانع از رفتار یکسان هر چهار کلاس می شود، اما ما تلاش می کنیم
کاری کنید که همه آنها تا حد امکان به طور مشابه کار کنند. و در صورت امکان آنالوگ هایی برای آن وجود دارد
همه متدها در همه کلاسها

┌────────────────┬──-
│ │ pcap │ ascii │
└────────────────┴

│دستیار کمکی │ │ │
├────────────────┼─────
│راهنمای پروتکل │ │ │
└────────────────┴

ما از رویکردی به نام a استفاده می کنیم MIXIN برای افزودن قابلیت ردیابی به کلاس های کمکی ما. آ
MIXIN کلاسی است که وقتی توسط یک زیر کلاس به ارث می رسد عملکردی را ارائه می دهد.
ارث بردن از میکسین نوعی تخصص در نظر گرفته نمی شود، اما در واقع راهی است
قابلیت جمع آوری

بیایید نگاهی گذرا به هر چهار مورد و موارد مربوط به آنها بیندازیم میکسین.

دستگاه یاران
PCAP
هدف این کمک‌ها این است که افزودن یک تسهیلات ردیابی PCAP سازگار به یک آسان‌تر باشد
ns-3 دستگاه ما می خواهیم همه طعم های مختلف ردیابی PCAP در سراسر یکسان عمل کنند
همه دستگاه‌ها، بنابراین روش‌های این کمک‌ها به دستیاران دستگاه به ارث می‌رسد. نگاهی بیاندازید
at src/network/helper/trace-helper.h اگر می خواهید در حین نگاه کردن، بحث را دنبال کنید
کد واقعی

کلاس PcapHelperForDevice هست یک MIXIN عملکرد سطح بالایی را برای استفاده فراهم می کند
ردیابی PCAP در یک ns-3 دستگاه هر دستگاهی باید یک روش مجازی را پیاده سازی کند
از این طبقه به ارث رسیده است.

خالی مجازی EnablePcapInternal (std::پیشوند رشته، Ptr nd، bool promiscuous، bool explicitFilename) = 0;

امضای این روش نمایانگر دیدگاه دستگاه محور از وضعیت در این است
مرحله. همه متدهای عمومی که از کلاس به ارث رسیده اند PcapUserHelperForDevice کاهش به
فراخوانی این روش پیاده سازی وابسته به دستگاه. مثلا پایین ترین سطح
روش PCAP

void EnablePcap (std::پیوند رشته، Ptr nd، bool promiscuous = false، bool explicitFilename = false);

اجرای دستگاه را فراخوانی خواهد کرد EnablePcapInternal به طور مستقیم. همه PCAP های عمومی دیگر
روش‌های ردیابی مبتنی بر این پیاده‌سازی برای ارائه سطح کاربر اضافی است
عملکرد. معنای این امر برای کاربر این است که همه کمک‌کنندگان دستگاه در سیستم این کار را انجام خواهند داد
همه روش های ردیابی PCAP را در دسترس داشته باشید. و این روش ها همه به یک شکل عمل خواهند کرد
در صورتی که دستگاه پیاده سازی کند EnablePcapInternal به درستی.

مواد و روش ها
void EnablePcap (std::پیوند رشته، Ptr nd، bool promiscuous = false، bool explicitFilename = false);
void EnablePcap (std::پیوند رشته، std::string ndName، bool promiscuous = false، bool explicitFilename = false);
void EnablePcap (std::پیوند رشته، NetDeviceContainer d، bool promiscuous = false);
void EnablePcap (std::پیوند رشته، NodeContainer n، bool promiscuous = false);
void EnablePcap (std::پیوند رشته، uint32_t nodeid، uint32_t deviceid، bool promiscuous = false);
void EnablePcapAll (std::پیوند رشته، bool promiscuous = false);

در هر یک از روش های نشان داده شده در بالا، یک پارامتر پیش فرض به نام وجود دارد بی قاعده که
پیش فرض به غلط. این پارامتر نشان می دهد که ردیابی نباید در آن جمع شود
حالت بی قرار اگر می‌خواهید ردیابی‌های شما شامل تمام ترافیکی باشد که دستگاه مشاهده می‌کند
(و اگر دستگاه از یک حالت غیرقانونی پشتیبانی می کند) به سادگی یک پارامتر واقعی را به هر یک از آنها اضافه کنید
تماس های بالا مثلا،

Ptr nd
...
helper.EnablePcap ("پیشوند"، nd، درست)؛

ضبط حالت بی رویه را در NetDevice مشخص شده توسط nd.

دو روش اول همچنین شامل یک پارامتر پیش فرض به نام می باشد explicit Filename که خواهد شد
در زیر مورد بحث قرار گیرد.

شما تشویق می‌شوید که اسناد API را برای کلاس مطالعه کنید PcapHelperForDevice برای پیدا کردن
جزئیات این روش ها؛ اما به طور خلاصه ...

· می توانید ردیابی PCAP را روی یک جفت گره/شبکه-دستگاه خاص با ارائه a فعال کنید
Ptr به یک EnablePcap روش. Ptr از دستگاه شبکه ضمنی است
باید دقیقاً متعلق به یک Node باشد. مثلا،

Ptr nd
...
helper.EnablePcap ("پیشوند"، nd);

· می توانید ردیابی PCAP را روی یک جفت گره/شبکه-دستگاه خاص با ارائه a فعال کنید
std::string نشان دهنده یک رشته سرویس نام شی به an EnablePcap روش.
Ptr از رشته نام به بالا نگاه می شود. دوباره، ضمنی است زیرا
دستگاه شبکه نامگذاری شده باید دقیقاً متعلق به یک Node باشد. مثلا،

نام ها::افزودن ("سرور" ...);
نام ها::افزودن ("server/eth0" ...);
...
helper.EnablePcap ("پیشوند"، "سرور/ath0");

· می‌توانید ردیابی PCAP را روی مجموعه‌ای از جفت‌های گره/شبکه-دستگاه با ارائه a فعال کنید
NetDeviceContainer. برای هر NetDevice در ظرف نوع بررسی شده است. برای هر
دستگاه از نوع مناسب (همان نوع که توسط کمکی دستگاه مدیریت می شود)، ردیابی است
فعال شد. دوباره، ضمنی است زیرا دستگاه شبکه یافت شده باید متعلق به آن باشد
دقیقا یک گره مثلا،

NetDeviceContainer d = ...;
...
helper.EnablePcap ("پیشوند"، d);

· می‌توانید ردیابی PCAP را روی مجموعه‌ای از جفت‌های گره/شبکه-دستگاه با ارائه a فعال کنید
NodeContainer. برای هر گره در NodeContainer متصل است NetDevices تکرار می شوند.
برای هر یک از NetDevice متصل به هر گره در ظرف، نوع آن دستگاه است
بررسی شد. برای هر دستگاه از نوع مناسب (همان نوع که توسط دستگاه مدیریت می شود
کمک کننده)، ردیابی فعال است.

NodeContainer n;
...
helper.EnablePcap ("پیشوند"، n);

· می توانید ردیابی PCAP را بر اساس شناسه گره و شناسه دستگاه و همچنین با فعال کنید
صریح پترن. هر گره در سیستم دارای شناسه گره عدد صحیح است و هر دستگاه متصل است
به یک Node یک شناسه دستگاه عدد صحیح دارد.

helper.EnablePcap ("پیشوند"، 21، 1);

· در نهایت، شما می توانید ردیابی PCAP را برای همه دستگاه های موجود در سیستم، با همان نوع فعال کنید
همانطور که توسط کمک کننده دستگاه مدیریت می شود.

helper.EnablePcapAll ("پیشوند");

نام پرونده ها
به طور ضمنی در توضیحات روش بالا ساخت یک نام فایل کامل توسط
روش پیاده سازی طبق قرارداد، PCAP ردیابی در ns-3 سیستم به شکل هستند
- شناسه > - id>.pcap

همانطور که قبلا ذکر شد، هر گره در سیستم دارای شناسه Node اختصاص یافته به سیستم خواهد بود. و
هر دستگاه نسبت به گره خود یک شاخص رابط (که شناسه دستگاه نیز نامیده می شود) خواهد داشت.
بنابراین، به طور پیش فرض، یک فایل ردیابی PCAP در نتیجه فعال کردن ردیابی در اول ایجاد می شود
دستگاه گره 21 با استفاده از پیشوند "پیشوند" خواهد بود پیشوند-21-1.pcap.

شما همیشه می توانید استفاده کنید ns-3 سرویس نام شیء برای روشن تر شدن این موضوع. به عنوان مثال، اگر
شما از سرویس نام شی استفاده می کنید تا نام «سرور» را به Node 21، PCAP حاصل، اختصاص دهید
نام فایل ردیابی به طور خودکار تبدیل می شود، prefix-server-1.pcap و اگر شما نیز اختصاص دهید
نام "eth0" را به دستگاه، نام فایل PCAP شما به طور خودکار این را انتخاب می کند و می شود
نام prefix-server-eth0.pcap.

در نهایت، دو تا از روش های نشان داده شده در بالا،

void EnablePcap (std::پیوند رشته، Ptr nd، bool promiscuous = false، bool explicitFilename = false);
void EnablePcap (std::پیوند رشته، std::string ndName، bool promiscuous = false، bool explicitFilename = false);

یک پارامتر پیش فرض به نام داشته باشید explicit Filename. وقتی روی true تنظیم شود، این پارامتر
مکانیزم تکمیل خودکار نام فایل را غیرفعال می کند و به شما امکان می دهد یک فایل واضح ایجاد کنید
نام فایل. این گزینه فقط در روش هایی موجود است که ردیابی PCAP را در a فعال می کنند
تک دستگاه

به عنوان مثال، به منظور ترتیب دادن یک کمک کننده دستگاه برای ایجاد یک PCAP منفرد
ضبط فایل با نام خاص my-pcap-file.pcap در یک دستگاه معین، می توان:

Ptr nd
...
helper.EnablePcap ("my-pcap-file.pcap"، nd، true، true)؛

اول درست پارامتر ردیابی حالت بیجا را فعال می کند و دومی به کمک کننده می گوید
برای تفسیر پیشوند پارامتر به عنوان نام فایل کامل

ASCII
رفتار کمک کننده ردیابی ASCII MIXIN به طور قابل ملاحظه ای شبیه به نسخه PCAP است.
نگاهی به src/network/helper/trace-helper.h اگر می خواهید بحث را دنبال کنید
در حالی که به کد واقعی نگاه می کنید.

کلاس AsciiTraceHelperForDevice عملکرد سطح بالایی را برای استفاده از ASCII اضافه می کند
ردیابی به کلاس کمکی دستگاه همانطور که در مورد PCAP، هر دستگاه باید a را پیاده سازی کند
روش مجازی منفرد که از ردیابی ASCII به ارث رسیده است MIXIN.

فضای خالی مجازی EnableAsciiInternal (Ptr جریان،
std::پیوند رشته،
Ptr nd،
BOOL SPLIPITFILENAME) = 0 ؛

امضای این روش نمایانگر دیدگاه دستگاه محور از وضعیت در این است
مرحله؛ و همچنین این واقعیت که کمک کننده ممکن است در حال نوشتن به یک جریان خروجی مشترک باشد. همه از
متدهای عمومی مرتبط با ردیابی ASCII که از کلاس به ارث رسیده است AsciiTraceHelperForDevice
به فراخوانی این روش پیاده سازی وابسته به دستگاه کاهش دهید. به عنوان مثال
روش‌های ردیابی آسکی پایین‌ترین سطح،

void EnableAscii (std::پیوند رشته، Ptr nd، bool explicitFilename = false);
void EnableAscii (Ptr جریان، Ptr nd)؛

اجرای دستگاه را فراخوانی خواهد کرد EnableAsciiInternal به طور مستقیم، ارائه یک
پیشوند یا جریان معتبر تمام روش‌های عمومی ردیابی ASCII بر این اساس خواهند بود
توابع سطح پایین برای ارائه عملکرد اضافی در سطح کاربر. این به چه معنی است
کاربر این است که تمام کمک‌کنندگان دستگاه در سیستم همه روش‌های ردیابی ASCII را خواهند داشت
در دسترس؛ و این روش‌ها در همه دستگاه‌ها به یک شکل عمل خواهند کرد
انجام EnablAsciiInternal به درستی.

مواد و روش ها
void EnableAscii (std::پیوند رشته، Ptr nd، bool explicitFilename = false);
void EnableAscii (Ptr جریان، Ptr nd)؛

void EnableAscii (std::پیوند رشته، std::string ndName، bool explicitFilename = false);
void EnableAscii (Ptr stream, std::string ndName);

void EnableAscii (std::پیوند رشته، NetDeviceContainer d)؛
void EnableAscii (Ptr جریان، NetDeviceContainer d)؛

void EnableAscii (std::پیوند رشته، NodeContainer n)؛
void EnableAscii (Ptr جریان، NodeContainer n)؛

void EnableAsciiAll (std::پیشوند رشته)؛
void EnableAsciiAll (Ptr جریان)؛

void EnableAscii (std::پیوند رشته، uint32_t nodeid، uint32_t deviceid، bool explicitFilename)؛
void EnableAscii (Ptr stream، uint32_t nodeid، uint32_t deviceid)؛

شما تشویق می‌شوید که اسناد API را برای کلاس مطالعه کنید AsciiTraceHelperForDevice به
جزئیات این روش ها را بیابید. اما به طور خلاصه ...

· دو برابر روش های موجود برای ردیابی ASCII نسبت به PCAP وجود دارد
ردیابی این به این دلیل است که، علاوه بر مدل PCAP به سبک که در آن آثاری از هر یک وجود دارد
یک جفت گره/دستگاه منحصر به فرد در یک فایل منحصر به فرد نوشته می شود، ما از مدلی پشتیبانی می کنیم که در آن ردیابی وجود دارد
اطلاعات بسیاری از جفت‌های گره/دستگاه در یک فایل مشترک نوشته می‌شود. این بدان معنی است که
- - مکانیسم تولید نام فایل با مکانیزمی جایگزین شده است
به یک فایل مشترک مراجعه کنید. و تعداد متدهای API دو برابر می شود تا به همه اجازه دهد
ترکیبات

همانطور که در ردیابی PCAP، شما می توانید ردیابی ASCII را در یک دستگاه خاص (گره، دستگاه شبکه) فعال کنید.
جفت با ارائه a Ptr به یک EnableAscii روش. Ptr ضمنی است
از آنجایی که دستگاه شبکه باید دقیقاً متعلق به یک Node باشد. مثلا،

Ptr nd
...
helper.EnableAscii ("پیشوند"، nd);

· چهار روش اول همچنین شامل یک پارامتر پیش فرض به نام explicit Filename که
مشابه پارامترهای معادل در مورد PCAP عمل می کند.

در این مورد، هیچ متن ردیابی در فایل ردیابی ASCII نوشته نمی‌شود، زیرا چنین خواهد بود
زائد. سیستم نام فایلی را که باید با استفاده از قوانین مشابه ایجاد شود را انتخاب می کند
در بخش PCAP توضیح داده شده است، با این تفاوت که فایل دارای پسوند خواهد بود TR بجای
pcap.

· اگر می خواهید ردیابی ASCII را در بیش از یک دستگاه شبکه فعال کنید و همه ردیابی ها ارسال شوند
با استفاده از یک شی برای ارجاع به یک فایل واحد، می توانید این کار را نیز انجام دهید.
ما قبلاً این را در مثال "cwnd" بالا دیده ایم:

Ptr nd1;
Ptr nd2;
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (stream, nd1);
helper.EnableAscii (stream, nd2);

در این مورد، زمینه ها را ردیابی کنید هستند در فایل ردیابی ASCII نوشته شده است زیرا آنها مورد نیاز هستند
برای رفع ابهام از دو دستگاه. توجه داشته باشید که از آنجایی که کاربر کاملاً است
با تعیین نام فایل، رشته باید شامل tr پسوند برای قوام

· می توانید ردیابی ASCII را روی یک جفت خاص (گره، شبکه-دستگاه) با ارائه یک
std::string نشان دهنده یک رشته سرویس نام شی به an EnablePcap روش.
Ptr از رشته نام به بالا نگاه می شود. دوباره، ضمنی است زیرا
دستگاه شبکه نامگذاری شده باید دقیقاً متعلق به یک Node باشد. مثلا،

نام ها::افزودن ("مشتری" ...);
نام ها::افزودن ("مشتری/eth0" ...);
نام ها::افزودن ("سرور" ...);
نام ها::افزودن ("server/eth0" ...);
...
helper.EnableAscii ("پیشوند"، "client/eth0");
helper.EnableAscii ("پیشوند"، "سرور/eth0");

این منجر به دو فایل به نام‌های «prefix-client-eth0.tr» و
``prefix-server-eth0.tr`` با ردیابی برای هر دستگاه در
فایل ردیابی مربوطه از آنجایی که تمام توابع «EnableAscii»
برای گرفتن یک بسته جریانی بیش از حد بارگذاری می شوند، می توانید از آن فرم به عنوان استفاده کنید
خوب::

نام ها::افزودن ("مشتری" ...);
نام ها::افزودن ("مشتری/eth0" ...);
نام ها::افزودن ("سرور" ...);
نام ها::افزودن ("server/eth0" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (stream، "client/eth0");
helper.EnableAscii (stream، "server/eth0");

این منجر به یک فایل ردیابی منفرد به نام می شود trace-file-name.tr که شامل همه
رویدادهای ردیابی برای هر دو دستگاه. رویدادها با زمینه ردیابی ابهام می‌شوند
رشته های.

· می توانید ردیابی ASCII را روی مجموعه ای از جفت (گره، شبکه-دستگاه) با ارائه یک
NetDeviceContainer. برای هر NetDevice در ظرف نوع بررسی شده است. برای هر
دستگاه از نوع مناسب (همان نوع که توسط کمکی دستگاه مدیریت می شود)، ردیابی است
فعال شد. دوباره، ضمنی است زیرا دستگاه شبکه یافت شده باید متعلق به آن باشد
دقیقا یک گره مثلا،

NetDeviceContainer d = ...;
...
helper.EnableAscii ("پیشوند"، d);

این منجر به ایجاد تعدادی فایل ردیابی ASCII می شود.
که هر کدام از "" پیروی می کنند - - tr``
قرارداد.

ترکیب همه ردیابی ها در یک فایل واحد مشابه نمونه ها انجام می شود
در بالا:

NetDeviceContainer d = ...;
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (stream, d);

· می توانید ردیابی ASCII را روی مجموعه ای از جفت (گره، شبکه-دستگاه) با ارائه یک
NodeContainer. برای هر گره در NodeContainer متصل است NetDevices تکرار می شوند.
برای هر یک از NetDevice متصل به هر گره در ظرف، نوع آن دستگاه است
بررسی شد. برای هر دستگاه از نوع مناسب (همان نوع که توسط دستگاه مدیریت می شود
کمک کننده)، ردیابی فعال است.

NodeContainer n;
...
helper.EnableAscii ("پیشوند"، n);

این منجر به ایجاد تعدادی فایل ردیابی ASCII می شود که هر کدام از آنها به شرح زیر است
la - شناسه > - id>.tr قرارداد. ترکیب همه ردیابی ها در یک
یک فایل به طور مشابه با مثال های بالا انجام می شود.

· می توانید ردیابی PCAP را بر اساس شناسه گره و شناسه دستگاه و همچنین با فعال کنید
صریح پترن. هر گره در سیستم دارای شناسه گره عدد صحیح است و هر دستگاه متصل است
به یک Node یک شناسه دستگاه عدد صحیح دارد.

helper.EnableAscii ("پیشوند"، 21، 1);

البته، ردیابی ها را می توان در یک فایل واحد مانند شکل بالا ترکیب کرد.

· در نهایت، شما می توانید ردیابی PCAP را برای همه دستگاه های موجود در سیستم، با همان نوع فعال کنید
همانطور که توسط کمک کننده دستگاه مدیریت می شود.

helper.EnableAsciiAll ("پیشوند");

این منجر به ایجاد تعدادی فایل ردیابی ASCII می شود، یکی برای هر دستگاه
در سیستمی از نوع مدیریت شده توسط کمک کننده. همه این فایل ها به دنبال خواهد بود
- شناسه > - id>.tr قرارداد. ترکیب همه ردیابی ها در یک واحد
فایل مشابه نمونه های بالا انجام می شود.

نام پرونده ها
ضمنی در توضیحات روش به سبک پیشوندی در بالا، ساخت کامل است
نام فایل ها با روش پیاده سازی طبق قرارداد، ASCII ردیابی در ns-3 سیستم
از فرم هستند - شناسه > - id>.tr

همانطور که قبلا ذکر شد، هر گره در سیستم دارای شناسه Node اختصاص یافته به سیستم خواهد بود. و
هر دستگاه نسبت به گره خود یک شاخص رابط (که شناسه دستگاه نیز نامیده می شود) خواهد داشت.
بنابراین، به طور پیش فرض، یک فایل ردیابی ASCII در نتیجه فعال کردن ردیابی در اول ایجاد می شود
دستگاه گره 21 با استفاده از پیشوند "پیشوند" خواهد بود پیشوند-21-1.tr.

شما همیشه می توانید استفاده کنید ns-3 سرویس نام شیء برای روشن تر شدن این موضوع. به عنوان مثال، اگر
شما از سرویس نام شی استفاده می کنید تا نام "سرور" را به گره 21 اختصاص دهید که نتیجه آن است
نام فایل ردیابی ASCII به طور خودکار تبدیل می شود prefix-server-1.tr و اگر هم تعیین کنید
نام "eth0" به دستگاه، نام فایل ردیابی ASCII شما به طور خودکار این را انتخاب می کند
و فراخوانی شود prefix-server-eth0.tr.

تعدادی از متدها دارای یک پارامتر پیش فرض هستند که نامیده می شود explicit Filename. وقتی روی تنظیم شده است
درست است، این پارامتر مکانیسم تکمیل خودکار نام فایل را غیرفعال می کند و به شما اجازه می دهد
برای ایجاد یک نام فایل صریح این گزینه فقط در روش هایی موجود است که a
پیشوند و ردیابی را در یک دستگاه فعال کنید.

پروتکل یاران
PCAP
هدف اینها میکسین این است که افزودن یک مرکز ردیابی PCAP سازگار به آن آسان شود
پروتکل ها ما می خواهیم همه طعم های مختلف ردیابی PCAP در همه یکسان عمل کنند
پروتکل ها، بنابراین روش های این کمک کننده ها توسط stack helper ها به ارث می رسد. نگاهی به
src/network/helper/trace-helper.h اگر می خواهید در حین نگاه کردن، بحث را دنبال کنید
کد واقعی

در این بخش روش‌هایی را که در پروتکل اعمال می‌شود، توضیح خواهیم داد IPv4. به
ردیابی را در پروتکل های مشابه مشخص کنید، فقط نوع مناسب را جایگزین کنید. مثلا،
استفاده از Ptr به جای یک Ptr و تماس بگیرید EnablePcapIpv6 بجای EnablePcapIpv4.

کلاس PcapHelperForIpv4 عملکرد سطح بالایی را برای استفاده از ردیابی PCAP فراهم می کند
در IPv4 پروتکل هر کمک کننده پروتکلی که این روش ها را فعال می کند باید یک واحد را پیاده سازی کند
متد مجازی که از این کلاس به ارث رسیده است. اجرای جداگانه ای برای
IPv6به عنوان مثال، اما تنها تفاوت در نام و امضای روش خواهد بود.
نام متدهای مختلف برای رفع ابهام کلاس مورد نیاز است IPv4 از جانب IPv6 که هر دو هستند
برگرفته از کلاس شیءو روش هایی که امضای یکسانی دارند.

خالی مجازی EnablePcapIpv4Internal (std::پیشوند رشته،
Ptr ipv4،
رابط uint32_t،
BOOL SPLIPITFILENAME) = 0 ؛

امضای این روش نمایانگر پروتکل و نمای رابط محوری است
وضعیت در این سطح همه متدهای عمومی که از کلاس به ارث رسیده اند PcapHelperForIpv4
به فراخوانی این روش پیاده سازی وابسته به دستگاه کاهش دهید. به عنوان مثال
روش PCAP پایین ترین سطح،

void EnablePcapIpv4 (std::پیشوند رشته، Ptr ipv4، رابط uint4_t، bool explicitFilename = false);

اجرای دستگاه را فراخوانی خواهد کرد EnablePcapIpv4Internal به طور مستقیم. همه عمومی های دیگر
روش‌های ردیابی PCAP مبتنی بر این پیاده‌سازی برای ارائه سطح کاربر اضافی است
عملکرد. معنی این موضوع برای کاربر این است که همه کمک کننده های پروتکل در سیستم هستند
تمام روش های ردیابی PCAP را در دسترس خواهد داشت. و این روش ها همگی در کار خواهند بود
در پروتکل‌ها به همین صورت در صورت پیاده‌سازی کمک‌کننده EnablePcapIpv4Internal به درستی.

مواد و روش ها
این روش ها به گونه ای طراحی شده اند که با Node- و مطابقت یک به یک داشته باشند
NetDevice- نسخه مرکزی نسخه های دستگاه. به جای Node و NetDevice جفت
محدودیت ها، ما از محدودیت های پروتکل و رابط استفاده می کنیم.

توجه داشته باشید که درست مانند نسخه دستگاه، شش روش وجود دارد:

void EnablePcapIpv4 (std::پیشوند رشته، Ptr ipv4، رابط uint4_t، bool explicitFilename = false);
void EnablePcapIpv4 (std::پیوند رشته، std::string ipv4Name، رابط uint32_t، bool explicitFilename = false);
void EnablePcapIpv4 (std::پیوند رشته، Ipv4InterfaceContainer c)؛
void EnablePcapIpv4 (std::پیوند رشته، NodeContainer n)؛
void EnablePcapIpv4 (std::پیوند رشته، uint32_t nodeid، رابط uint32_t، bool explicitFilename)؛
void EnablePcapIpv4All (std::پیشوند رشته)؛

شما تشویق می‌شوید که اسناد API را برای کلاس مطالعه کنید PcapHelperForIpv4 برای پیدا کردن
جزئیات این روش ها؛ اما به طور خلاصه ...

· می توانید ردیابی PCAP را روی یک جفت پروتکل/رابط خاص با ارائه a فعال کنید
Ptr و رابط به یک EnablePcap روش. مثلا،

Ptr ipv4 = node->GetObject ()
...
helper.EnablePcapIpv4 ("پیشوند"، ipv4، 0);

· می توانید ردیابی PCAP را روی یک جفت گره/شبکه-دستگاه خاص با ارائه a فعال کنید
std::string نشان دهنده یک رشته سرویس نام شی به an EnablePcap روش.
Ptr از رشته نام به بالا نگاه می شود. مثلا،

نام ها::افزودن ("serverIPv4" ...);
...
helper.EnablePcapIpv4 ("پیشوند"، "serverIpv4"، 1);

· می توانید ردیابی PCAP را روی مجموعه ای از جفت های پروتکل/رابط با ارائه یک فعال کنید
IPv4InterfaceContainer. برای هر IPv4 / جفت رابط در ظرف پروتکل
نوع بررسی می شود برای هر پروتکل از نوع مناسب (همان نوع مدیریت شده توسط
کمک کننده دستگاه)، ردیابی برای رابط مربوطه فعال است. مثلا،

گره های NodeContainer.
...
دستگاه های NetDeviceContainer = deviceHelper.Install (گره ها)؛
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0"، "255.255.255.0")؛
رابط های Ipv4InterfaceContainer = ipv4.Assign (دستگاه ها)؛
...
helper.EnablePcapIpv4 ("پیشوند"، رابط ها)؛

· می توانید ردیابی PCAP را روی مجموعه ای از جفت های پروتکل/رابط با ارائه یک فعال کنید
NodeContainer. برای هر گره در NodeContainer پروتکل مناسب پیدا می شود.
برای هر پروتکل، اینترفیس های آن شمارش شده و ردیابی بر روی نتیجه فعال می شود
جفت مثلا،

NodeContainer n;
...
helper.EnablePcapIpv4 ("پیشوند"، n);

· می توانید ردیابی PCAP را بر اساس شناسه گره و رابط نیز فعال کنید. در این
مورد، node-id به a ترجمه می شود Ptr و پروتکل مناسب جستجو می شود
در گره پروتکل و رابط حاصل برای مشخص کردن نتیجه استفاده می شود
منبع ردیابی

helper.EnablePcapIpv4 ("پیشوند"، 21، 1);

· در نهایت، می توانید ردیابی PCAP را برای تمام رابط های موجود در سیستم، با مرتبط، فعال کنید
پروتکل همان نوع پروتکلی است که توسط Helper دستگاه مدیریت می شود.

helper.EnablePcapIpv4All ("پیشوند");

نام پرونده ها
ضمناً در تمام توضیحات روش فوق، ساخت کامل است
نام فایل ها با روش پیاده سازی طبق قرارداد، ردیابی های PCAP برای دستگاه های موجود در آن گرفته می شود
la ns-3 سیستم به شکل " - - pcap. در مورد
ردیابی پروتکل، یک تناظر یک به یک بین پروتکل ها و گره ها. این
به دلیل پروتکل است اشیاء به تجمیع می شوند گره اشیاء. از آنجایی که جهانی وجود ندارد
شناسه پروتکل در سیستم، از شناسه Node مربوطه در نامگذاری فایل استفاده می کنیم. از این رو
امکان برخورد نام فایل در نام فایل های ردیابی خودکار انتخاب شده وجود دارد.
به همین دلیل، قرارداد نام فایل برای ردیابی پروتکل تغییر می کند.

همانطور که قبلا ذکر شد، هر Node در سیستم دارای شناسه Node اختصاص داده شده توسط سیستم خواهد بود.
از آنجایی که یک تناظر یک به یک بین نمونه های پروتکل و نمونه های Node وجود دارد
ما از شناسه Node استفاده می کنیم. هر رابط دارای شناسه رابط نسبت به پروتکل خود است. ما استفاده می کنیم
کنوانسیون " -n -من pcap. برای ردیابی نامگذاری فایل در
کمک کنندگان پروتکل

بنابراین، به طور پیش فرض، یک فایل ردیابی PCAP در نتیجه فعال کردن ردیابی در ایجاد می شود
رابط 1 پروتکل Ipv4 نود 21 با استفاده از پیشوند "پیشوند" خواهد بود
"prefix-n21-i1.pcap".

شما همیشه می توانید استفاده کنید ns-3 سرویس نام شیء برای روشن تر شدن این موضوع. به عنوان مثال، اگر
شما از سرویس نام شی استفاده می کنید تا نام "serverIpv4" را به Ptr اختصاص دهید در Node
21، نام فایل ردیابی PCAP به طور خودکار تبدیل می شود،
"prefix-nserverIpv4-i1.pcap".

تعدادی از متدها دارای یک پارامتر پیش فرض هستند که نامیده می شود explicit Filename. وقتی روی تنظیم شده است
درست است، این پارامتر مکانیسم تکمیل خودکار نام فایل را غیرفعال می کند و به شما اجازه می دهد
برای ایجاد یک نام فایل صریح این گزینه فقط در روش هایی موجود است که a
پیشوند و ردیابی را در یک دستگاه فعال کنید.

ASCII
رفتار کمک کننده های ردیابی ASCII به طور قابل ملاحظه ای مشابه مورد PCAP است. یک را بگیرید
نگاه src/network/helper/trace-helper.h اگر می خواهید در حالی که بحث را دنبال کنید
نگاه کردن به کد واقعی

در این بخش روش‌هایی را که در پروتکل اعمال می‌شود، توضیح خواهیم داد IPv4. به
ردیابی را در پروتکل های مشابه مشخص کنید، فقط نوع مناسب را جایگزین کنید. مثلا،
استفاده از Ptr به جای یک Ptr و تماس بگیرید EnableAsciiIpv6 بجای
EnableAsciiIpv4.

کلاس AsciiTraceHelperForIpv4 عملکرد سطح بالایی را برای استفاده از ASCII اضافه می کند
ردیابی به کمک پروتکل هر پروتکلی که این روش ها را فعال می کند باید a را پیاده سازی کند
متد مجازی تکی که از این کلاس به ارث رسیده است.

فضای خالی مجازی EnableAsciiIpv4Internal (Ptr جریان،
std::پیوند رشته،
Ptr ipv4،
رابط uint32_t،
BOOL SPLIPITFILENAME) = 0 ؛

امضای این روش نمایانگر نمای پروتکل و رابط محوری است
وضعیت در این سطح؛ و همچنین این واقعیت که کمک کننده ممکن است در حال نوشتن به اشتراکی باشد
جریان خروجی همه متدهای عمومی که از کلاس به ارث رسیده اند
PcapAndAsciiTraceHelperForIpv4 به فراخوانی این واحد وابسته به دستگاه کاهش دهید
روش پیاده سازی به عنوان مثال، روش های ردیابی ASCII پایین ترین سطح،

void EnableAsciiIpv4 (std::پیشوند رشته، Ptr ipv4، رابط uint4_t، bool explicitFilename = false);
void EnableAsciiIpv4 (Ptr جریان، Ptr رابط ipv4، uint4_t)؛

اجرای دستگاه را فراخوانی خواهد کرد EnableAsciiIpv4Internal به طور مستقیم، ارائه هر کدام
پیشوند یا جریان تمام روش‌های عمومی ردیابی ASCII بر این اساس خواهند بود
توابع سطح پایین برای ارائه عملکرد اضافی در سطح کاربر. این به چه معنی است
کاربر این است که تمام کمک‌کنندگان دستگاه در سیستم همه روش‌های ردیابی ASCII را خواهند داشت
در دسترس؛ و این روش‌ها در تمام پروتکل‌ها به یک شکل عمل خواهند کرد
پروتکل ها اجرا می شوند EnablAsciiIpv4Internal به درستی.

مواد و روش ها
void EnableAsciiIpv4 (std::پیشوند رشته، Ptr ipv4، رابط uint4_t، bool explicitFilename = false);
void EnableAsciiIpv4 (Ptr جریان، Ptr رابط ipv4، uint4_t)؛

void EnableAsciiIpv4 (std::پیوند رشته، std::string ipv4Name، رابط uint32_t، bool explicitFilename = false);
void EnableAsciiIpv4 (Ptr stream، std::string ipv4Name، رابط uint32_t);

void EnableAsciiIpv4 (std::پیشوند رشته، Ipv4InterfaceContainer c)؛
void EnableAsciiIpv4 (Ptr جریان، Ipv4InterfaceContainer c)؛

void EnableAsciiIpv4 (std::پیوند رشته، NodeContainer n)؛
void EnableAsciiIpv4 (Ptr جریان، NodeContainer n)؛

void EnableAsciiIpv4All (std::پیشوند رشته);
void EnableAsciiIpv4All (Ptr جریان)؛

void EnableAsciiIpv4 (std::پیوند رشته، uint32_t nodeid، uint32_t deviceid، bool explicitFilename);
void EnableAsciiIpv4 (Ptr استریم، uint32_t nodeid، رابط uint32_t)؛

شما تشویق می‌شوید که اسناد API را برای کلاس مطالعه کنید pcapandasciihelperforipv4 به
جزئیات این روش ها را بیابید. اما به طور خلاصه ...

· دو برابر روش های موجود برای ردیابی ASCII نسبت به PCAP وجود دارد
ردیابی این به این دلیل است که، علاوه بر مدل PCAP به سبک که در آن آثاری از هر یک وجود دارد
یک جفت پروتکل/رابط منحصر به فرد در یک فایل منحصر به فرد نوشته می شود، ما از مدلی پشتیبانی می کنیم که در آن
اطلاعات ردیابی برای بسیاری از جفت‌های پروتکل/رابط در یک فایل مشترک نوشته می‌شود. این
به این معنی است که -n - مکانیسم تولید نام فایل است
با مکانیزمی برای ارجاع به یک فایل مشترک جایگزین شده است. و تعداد متدهای API است
دو برابر شد تا همه ترکیب ها مجاز باشند.

همانطور که در ردیابی PCAP، می توانید ردیابی ASCII را در یک پروتکل/رابط خاص فعال کنید
جفت با ارائه a Ptr و رابط به یک EnableAscii روش. مثلا،

Ptr ipv4;
...
helper.EnableAsciiIpv4 ("پیشوند"، ipv4، 1);

در این مورد، هیچ متن ردیابی در فایل ردیابی ASCII نوشته نمی‌شود، زیرا چنین خواهد بود
زائد. سیستم نام فایلی را که باید با استفاده از قوانین مشابه ایجاد شود را انتخاب می کند
در بخش PCAP توضیح داده شده است، با این تفاوت که فایل به جای آن پسوند ".tr" خواهد داشت
از ".pcap".

· اگر می خواهید ردیابی ASCII را در بیش از یک رابط فعال کنید و همه ردیابی ها ارسال شوند
با استفاده از یک شی برای ارجاع به یک فایل واحد، می توانید این کار را نیز انجام دهید.
ما قبلاً چیزی شبیه به این را در مثال "cwnd" بالا داریم:

Ptr protocol4 = node1->GetObject ()
Ptr protocol4 = node2->GetObject ()
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (stream, protocol1, 1);
helper.EnableAsciiIpv4 (stream, protocol2, 1);

در این مورد، زمینه‌های ردیابی در فایل ردیابی ASCII نوشته می‌شوند، زیرا به آنها نیاز است
برای رفع ابهام از دو رابط. توجه داشته باشید که از آنجایی که کاربر کاملاً است
با تعیین نام فایل، رشته باید شامل ",tr" برای سازگاری باشد.

· می توانید ردیابی ASCII را روی یک پروتکل خاص با ارائه a فعال کنید std::string
نشان دهنده یک رشته سرویس نام شی به an EnablePcap روش. Ptr is
از رشته نام به بالا نگاه کرد. در در نام فایل های به دست آمده ضمنی است
یک تناظر یک به یک بین نمونه های پروتکل و گره ها وجود دارد، به عنوان مثال،

نام ها::افزودن ("node1Ipv4" ...);
نام ها::افزودن ("node2Ipv4" ...);
...
helper.EnableAsciiIpv4 ("پیشوند"، "node1Ipv4"، 1);
helper.EnableAsciiIpv4 ("پیشوند"، "node2Ipv4"، 1);

این منجر به دو فایل به نام های "prefix-nnode1Ipv4-i1.tr" و
"prefix-nnode2Ipv4-i1.tr" با ردیابی برای هر رابط در فایل ردیابی مربوطه.
از آنجایی که تمام توابع EnableAscii برای گرفتن یک استریم بسته بارگذاری می شوند، می توانید
از آن فرم نیز استفاده کنید:

نام ها::افزودن ("node1Ipv4" ...);
نام ها::افزودن ("node2Ipv4" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (جریان، "node1Ipv4"، 1)؛
helper.EnableAsciiIpv4 (جریان، "node2Ipv4"، 1)؛

این منجر به یک فایل ردیابی منفرد به نام "trace-file-name.tr" می شود که حاوی همه است
از رویدادهای ردیابی برای هر دو رابط. وقایع با ردیابی مبهم خواهند شد
رشته های زمینه

· می توانید ردیابی ASCII را در مجموعه ای از جفت های پروتکل/رابط با ارائه یک فعال کنید
IPv4InterfaceContainer. برای هر پروتکل از نوع مناسب (همان نوع
مدیریت شده توسط دستیار دستگاه)، ردیابی برای رابط مربوطه فعال است.
باز هم، ضمنی است زیرا بین هر یک مطابقت یک به یک وجود دارد
پروتکل و گره آن مثلا،

گره های NodeContainer.
...
دستگاه های NetDeviceContainer = deviceHelper.Install (گره ها)؛
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0"، "255.255.255.0")؛
رابط های Ipv4InterfaceContainer = ipv4.Assign (دستگاه ها)؛
...
...
helper.EnableAsciiIpv4 ("پیشوند"، رابط ها)؛

این منجر به ایجاد تعدادی فایل ردیابی ASCII می شود که هر کدام از آنها به شرح زیر است
را -n -من کنوانسیون .tr. ترکیب همه ردیابی ها در یک
یک فایل به طور مشابه با مثال های بالا انجام می شود:

گره های NodeContainer.
...
دستگاه های NetDeviceContainer = deviceHelper.Install (گره ها)؛
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0"، "255.255.255.0")؛
رابط های Ipv4InterfaceContainer = ipv4.Assign (دستگاه ها)؛
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (جریان، رابط ها)؛

· می‌توانید ردیابی ASCII را روی مجموعه‌ای از جفت‌های پروتکل/رابط با ارائه a فعال کنید
NodeContainer. برای هر گره در NodeContainer پروتکل مناسب پیدا می شود.
برای هر پروتکل، اینترفیس های آن شمارش شده و ردیابی بر روی نتیجه فعال می شود
جفت مثلا،

NodeContainer n;
...
helper.EnableAsciiIpv4 ("پیشوند"، n);

این منجر به ایجاد تعدادی فایل ردیابی ASCII می شود که هر کدام از آنها به شرح زیر است
را - - کنوانسیون .tr. ترکیب همه ردیابی ها در یک
یک فایل به طور مشابه با مثال های بالا انجام می شود.

· می توانید ردیابی PCAP را بر اساس شناسه گره و شناسه دستگاه نیز فعال کنید. در این
مورد، node-id به a ترجمه می شود Ptr و پروتکل مناسب جستجو می شود
در گره پروتکل و رابط حاصل برای مشخص کردن نتیجه استفاده می شود
منبع ردیابی

helper.EnableAsciiIpv4 ("پیشوند"، 21، 1);

البته، ردیابی ها را می توان در یک فایل واحد مانند شکل بالا ترکیب کرد.

· در نهایت، شما می توانید ردیابی ASCII را برای تمام رابط های موجود در سیستم، با مرتبط فعال کنید
پروتکل همان نوع پروتکلی است که توسط Helper دستگاه مدیریت می شود.

helper.EnableAsciiIpv4All ("پیشوند");

این منجر به ایجاد تعدادی فایل ردیابی ASCII می‌شود، یکی برای هر کدام
رابط در سیستم مربوط به پروتکلی از نوع مدیریت شده توسط Helper است. همه از
این فایل ها به دنبال خواهد بود -n -من
تمام ردیابی ها در یک فایل به طور مشابه با مثال های بالا انجام می شود.

نام پرونده ها
ضمنی در توضیحات روش به سبک پیشوندی در بالا، ساخت کامل است
نام فایل ها با روش پیاده سازی طبق قرارداد، ASCII ردیابی در ns-3 سیستم
به شکل " - - .tr"

همانطور که قبلا ذکر شد، هر Node در سیستم دارای شناسه Node اختصاص داده شده توسط سیستم خواهد بود.
از آنجایی که یک تناظر یک به یک بین پروتکل‌ها و گره‌ها وجود دارد، برای node-id استفاده می‌کنیم
برای شناسایی هویت پروتکل هر رابط در یک پروتکل معین دارای یک
شاخص رابط (که به سادگی یک رابط نیز نامیده می شود) نسبت به پروتکل آن. به صورت پیش فرض،
سپس، یک فایل ردیابی ASCII در نتیجه فعال کردن ردیابی در اولین دستگاه ایجاد شده است
گره 21، با استفاده از پیشوند "پیشوند"، "prefix-n21-i1.tr" خواهد بود. از پیشوند استفاده کنید
ابهام زدایی چندین پروتکل در هر گره.

شما همیشه می توانید استفاده کنید ns-3 سرویس نام شیء برای روشن تر شدن این موضوع. به عنوان مثال، اگر
شما از سرویس نام شی استفاده می کنید تا نام "serverIpv4" را به پروتکل روی Node اختصاص دهید
21، و همچنین رابط یک را مشخص کنید، نام فایل ردیابی ASCII به طور خودکار خواهد بود
تبدیل، "prefix-nserverIpv4-1.tr".

تعدادی از متدها دارای یک پارامتر پیش فرض هستند که نامیده می شود explicit Filename. وقتی روی تنظیم شده است
درست است، این پارامتر مکانیسم تکمیل خودکار نام فایل را غیرفعال می کند و به شما اجازه می دهد
برای ایجاد یک نام فایل صریح این گزینه فقط در روش هایی موجود است که a
پیشوند و ردیابی را در یک دستگاه فعال کنید.

خلاصه
ns-3 شامل یک محیط بسیار غنی است که به کاربران در سطوح مختلف امکان سفارشی سازی را می دهد
انواع اطلاعاتی که می توان از شبیه سازی ها استخراج کرد.

توابع کمکی سطح بالایی وجود دارد که به کاربران امکان می دهد به سادگی مجموعه ای از آنها را کنترل کنند
خروجی های از پیش تعریف شده به دانه بندی خوب. توابع کمکی سطح متوسطی وجود دارد که اجازه می دهد
کاربران پیچیده تر برای سفارشی کردن نحوه استخراج و ذخیره اطلاعات. و آنجا
توابع اصلی سطح پایینی هستند که به کاربران خبره اجازه می دهند تا سیستم را برای ارائه جدید تغییر دهند
اطلاعاتی که قبلاً صادر نشده است به نحوی که بلافاصله در دسترس کاربران قرار گیرد
سطوح بالاتر

این یک سیستم بسیار جامع است و ما متوجه می شویم که هضم آن بسیار زیاد است، به خصوص
برای کاربران جدید یا کسانی که از نزدیک با C++ و اصطلاحات آن آشنا نیستند. ما در نظر می گیریم
سیستم ردیابی بخش بسیار مهمی از ns-3 و بنابراین توصیه می کنیم به همان اندازه آشنا شوید
با آن امکان پذیر است احتمالاً درک بقیه موارد اینطور است ns-3 سیستم
پس از تسلط بر سیستم ردیابی بسیار ساده خواهد بود

داده ها مجموعه


فصل آخر آموزش ما برخی از اجزایی را که به آن اضافه شده اند معرفی می کند ns-3 در نسخه
3.18، و هنوز در دست توسعه هستند. این بخش آموزشی نیز یک
کار در حال انجام.

انگیزه
یکی از نکات اصلی اجرای شبیه‌سازی، تولید داده‌های خروجی است
اهداف تحقیقاتی یا صرفاً برای یادگیری در مورد سیستم. در فصل قبل، ما
زیرسیستم ردیابی و مثال را معرفی کرد سی سی ششم. که از آن PCAP یا ASCII ردیابی می شود
فایل ها تولید می شوند. این ردیابی ها برای تجزیه و تحلیل داده ها با استفاده از انواع مختلف ارزشمند هستند
ابزارهای خارجی، و برای بسیاری از کاربران، چنین داده های خروجی وسیله ای ارجح برای جمع آوری است
داده ها (برای تجزیه و تحلیل توسط ابزارهای خارجی).

با این حال، موارد استفاده برای بیش از تولید فایل ردیابی نیز وجود دارد، از جمله
زیر است:

· تولید داده هایی که به خوبی با ردیابی های PCAP یا ASCII نگاشت نمی شوند، مانند غیر بسته
داده ها (مثلاً انتقال ماشین حالت پروتکل)،

· شبیه سازی های بزرگ که نیازهای ورودی/خروجی دیسک برای تولید فایل های ردیابی است
منع یا دست و پا گیر و

· نیاز به آنلاین کاهش یا محاسبه داده ها، در طول شبیه سازی.
یک مثال خوب برای این تعریف، تعریف شرط پایان برای شبیه سازی است
زمانی که داده‌های کافی برای ایجاد اعتماد به‌اندازه کافی دریافت کرده است، چه زمانی متوقف شود
فاصله حول برآورد برخی از پارامترها

La ns-3 چارچوب جمع آوری داده ها برای ارائه این قابلیت های اضافی طراحی شده است
فراتر از خروجی مبتنی بر ردیابی توصیه می کنیم خواننده علاقه مند به این موضوع مشورت کند
la ns-3 راهنمای بررسی دقیق تر این چارچوب؛ در اینجا، ما به طور خلاصه با
یک برنامه نمونه برخی از قابلیت های در حال توسعه.

مثال رمز
نمونه آموزش examples/tutorial/seventh.cc شبیه سی سی ششم مثال ما
قبلا بررسی شده است، به جز چند تغییر. ابتدا برای IPv6 فعال شده است
پشتیبانی با یک گزینه خط فرمان:

CommandLine cmd;
cmd.AddValue ("useIpv6"، "Use Ipv6"، useV6);
cmd.Parse (argc, argv);

اگر کاربر مشخص کند از IPv6 استفاده کنید، گزینه، برنامه با استفاده از IPv6 به جای IPv4 اجرا می شود.
La کمک گزینه، در همه موجود است ns-3 برنامه هایی که از شی CommandLine به عنوان پشتیبانی می کنند
نشان داده شده در بالا، می تواند به شرح زیر استناد شود (لطفاً به استفاده از نقل قول های دوگانه توجه کنید):

./waf -- اجرای "هفتم -- کمک"

که تولید می کند:

ns3-dev-seventh-debug [Arguments Program] [Arguments General]

استدلال های برنامه:
--useIpv6: از Ipv6 استفاده کنید [نادرست]

استدلال های کلی:
--PrintGlobals: فهرست جهانی ها را چاپ کنید.
--PrintGroups: لیست گروه ها را چاپ کنید.
--PrintGroup=[group]: چاپ تمام TypeId های گروه.
--PrintTypeIds: چاپ همه TypeIds.
--PrintAttributes=[typeid]: چاپ تمام ویژگی های typeid.
--PrintHelp: این پیام راهنما را چاپ کنید.

این پیش‌فرض (استفاده از IPv4، از آنجایی که useIpv6 نادرست است) را می‌توان با جابجایی Boolean تغییر داد.
ارزش به شرح زیر است:

./waf -- run "seventh --useIpv6=1"

و نگاهی به pcap تولید شده، مانند با tcpdump:

tcpdump -r هفتم.pcap -nn -tt

این یک انحراف کوتاه در پشتیبانی IPv6 و خط فرمان بوده است، که همچنین بود
قبلا در این آموزش معرفی شد. برای مثال اختصاصی استفاده از خط فرمان،
لطفا ببینید src/core/examples/command-line-example.cc.

اکنون به جمع آوری داده ها بازگردیم. در مثال ها/آموزش/ دایرکتوری زیر را تایپ کنید
فرمان: تفاوت -u سی سی ششم سی سی هفتم، و برخی از خطوط جدید این تفاوت را بررسی کنید:

+ std::string probeType;
+ std::string tracePath;
+ if (useV6 == غلط)
+ {
...
+ probeType = "ns3::Ipv4PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
+ }
+دیگه
+ {
...
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
+ }
...
+ // از GnuplotHelper برای رسم تعداد بایت بسته در طول زمان استفاده کنید
+ GnuplotHelper plotHelper.
+
+ // طرح را پیکربندی کنید. اولین آرگومان پیشوند نام فایل است
+ // برای فایل های خروجی تولید شده. دوم و سوم و چهارم
+ // آرگومان ها به ترتیب عنوان طرح، محور x و محور y هستند.
+ plotHelper.ConfigurePlot ("seventh-packet-byte-count"،
+ "تعداد بایت بسته در برابر زمان"،
+ "زمان (ثانیه)"،
+ "تعداد بایت بسته")؛
+
+ // نوع پروب، مسیر منبع ردیابی (در فضای نام پیکربندی) و
+ // منبع ردیابی خروجی کاوشگر ("OutputBytes") برای رسم. برهان چهارم
+ // نام برچسب سری داده را در نمودار مشخص می کند. آخرین
+ // آرگومان نمودار را با تعیین محل قرار دادن کلید قالب بندی می کند.
+ plotHelper.PlotProbe (probeType،
+ TracePath،
+ "OutputBytes"،
+ "تعداد بایت بسته"،
+ GnuplotAggregator::KEY_BELOW);
+
+ // از FileHelper برای نوشتن تعداد بایت های بسته در طول زمان استفاده کنید
+ FileHelper fileHelper.
+
+ // پیکربندی فایل برای نوشتن و قالب بندی داده های خروجی.
+ fileHelper.ConfigureFile ("seventh-packet-byte-count"،
+ FileAggregator::FORMATTED);
+
+ // برچسب ها را برای این فایل خروجی فرمت شده تنظیم کنید.
+ fileHelper.Set2dFormat ("زمان (ثانیه) = %.3e\tPacket Byte Count = %.0f");
+
+ // نوع پروب، مسیر پروب (در فضای نام پیکربندی)، و را مشخص کنید
+ // کاوش منبع ردیابی خروجی ("OutputBytes") برای نوشتن.
+ fileHelper.WriteProbe (probeType،
+ TracePath،
+ "OutputBytes")؛
+
شبیه ساز::توقف (ثانیه (20))؛
شبیه ساز::Run ();
شبیه ساز::Destroy ();

خواننده دقیق هنگام آزمایش ویژگی خط فرمان IPv6 در بالا متوجه خواهد شد،
که سی سی هفتم تعدادی فایل خروجی جدید ایجاد کرده بود:

هفتم بسته-بایت-count-0.txt
هفتم بسته-بایت-count-1.txt
هفتم بسته-بایت-count.dat
هفتم بسته-بایت-count.plt
heftth-packet-byte-count.png
هفتم بسته-بایت-count.sh

اینها با عبارات اضافی معرفی شده در بالا ایجاد شدند. به ویژه توسط الف
GnuplotHelper و FileHelper. این داده ها با قلاب کردن مجموعه داده ها تولید شده اند
قطعات به ns-3 ردیابی منابع، و ترکیب داده ها به فرمت شده gnuplot و
به یک فایل متنی فرمت شده در بخش های بعدی هر یک از این موارد را بررسی خواهیم کرد.

GnuplotHelper
GnuplotHelper یک است ns-3 جسم کمکی با هدف تولید gnuplot توطئه ها با
تا آنجا که ممکن است کمتر، برای موارد رایج. قلاب می کند ns-3 ردیابی منابع با داده ها
انواع پشتیبانی شده توسط سیستم جمع آوری داده ها نه همه ns-3 منابع ردیابی انواع داده ها هستند
پشتیبانی می شود، اما بسیاری از انواع ردیابی رایج، از جمله TracedValues ​​با قدیمی ساده هستند
انواع داده (POD)

بیایید به خروجی تولید شده توسط این کمک کننده نگاه کنیم:

هفتم بسته-بایت-count.dat
هفتم بسته-بایت-count.plt
هفتم بسته-بایت-count.sh

اولی یک فایل داده gnuplot با یک سری مهرهای زمانی و بسته با فاصله است
بایت شمارش می شود در زیر نحوه پیکربندی این خروجی داده خاص را توضیح خواهیم داد، اما اجازه دهید
با فایل های خروجی ادامه دهید. پرونده هفتم بسته-بایت-count.plt یک نمودار gnuplot است
فایل، که می تواند از داخل gnuplot باز شود. خوانندگانی که نحو gnuplot را درک می کنند می توانند
ببینید که این یک فایل PNG خروجی فرمت شده به نام تولید می کند
heftth-packet-byte-count.png. در نهایت، یک اسکریپت پوسته کوچک
هفتم بسته-بایت-count.sh این فایل نمودار را از طریق gnuplot اجرا می کند تا مورد دلخواه را تولید کند
PNG (که در یک ویرایشگر تصویر قابل مشاهده است)؛ یعنی دستور:

sh هفتم بسته-بایت-count.sh

تسلیم خواهد شد heftth-packet-byte-count.png. چرا این PNG در ابتدا تولید نشد؟
محل؟ پاسخ این است که با ارائه فایل plt، کاربر می تواند به صورت دستی آن را پیکربندی کند
در صورت تمایل، قبل از تولید PNG نتیجه بگیرید.

عنوان تصویر PNG بیان می‌کند که این نمودار نموداری از «تعداد بایت بسته در مقابل زمان» است، و
که داده های کاوش شده مربوط به مسیر منبع ردیابی را ترسیم می کند:

/NodeList/*/$ns3::Ipv6L3Protocol/Tx

به کارت وایلد در مسیر ردیابی توجه کنید. به طور خلاصه، آنچه این طرح در حال ثبت است، طرح است
از بایت های بسته مشاهده شده در منبع ردیابی انتقال شی Ipv6L3Protocol.
بخش های TCP عمدتاً 596 بایتی در یک جهت و 60 بایتی TCP در جهت دیگر (دو
منابع ردیابی گره با این منبع ردیابی مطابقت داشتند).

این چگونه پیکربندی شد؟ چند بیانیه باید ارائه شود. اول، GnuplotHelper
شی باید اعلام و پیکربندی شود:

+ // از GnuplotHelper برای رسم تعداد بایت بسته در طول زمان استفاده کنید
+ GnuplotHelper plotHelper.
+
+ // طرح را پیکربندی کنید. اولین آرگومان پیشوند نام فایل است
+ // برای فایل های خروجی تولید شده. دوم و سوم و چهارم
+ // آرگومان ها به ترتیب عنوان طرح، محور x و محور y هستند.
+ plotHelper.ConfigurePlot ("seventh-packet-byte-count"،
+ "تعداد بایت بسته در برابر زمان"،
+ "زمان (ثانیه)"،
+ "تعداد بایت بسته")؛

تا این مرحله، یک نمودار خالی پیکربندی شده است. پیشوند نام فایل اولین مورد است
آرگومان، عنوان طرح دوم، برچسب محور x سوم، و برچسب محور y است.
استدلال چهارم

مرحله بعدی پیکربندی داده ها است و در اینجا منبع ردیابی قلاب می شود.
ابتدا توجه داشته باشید که در برنامه چند متغیر را برای استفاده بعدی اعلام کردیم:

+ std::string probeType;
+ std::string tracePath;
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";

ما در اینجا از آنها استفاده می کنیم:

+ // نوع پروب، مسیر منبع ردیابی (در فضای نام پیکربندی) و
+ // منبع ردیابی خروجی کاوشگر ("OutputBytes") برای رسم. برهان چهارم
+ // نام برچسب سری داده را در نمودار مشخص می کند. آخرین
+ // آرگومان نمودار را با تعیین محل قرار دادن کلید قالب بندی می کند.
+ plotHelper.PlotProbe (probeType،
+ TracePath،
+ "OutputBytes"،
+ "تعداد بایت بسته"،
+ GnuplotAggregator::KEY_BELOW);

دو آرگومان اول نام نوع پروب و مسیر منبع ردیابی هستند. اینها
وقتی می‌خواهید از این چارچوب برای ترسیم موارد دیگر استفاده کنید، احتمالاً تشخیص دو مورد از سخت‌ترین موارد است
آثار ردیابی کاوشگر در اینجا است Tx منبع ردیابی کلاس پروتکل Ipv6L3. زمانی که ما
اجرای این کلاس را بررسی کنید (src/internet/model/ipv6-l3-protocol.cc) می توانیم مشاهده کنیم:

.AddTraceSource ("Tx"، "ارسال بسته IPv6 به رابط خروجی."،
MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace))

این می گوید Tx نامی برای متغیر است m_txTrace، که دارای بیانیه ای است:

/ **
* پاسخ کوتاه برای ردیابی بسته های TX (انتقال).
*/
TracedCallback , Ptr , uint6_t> m_txTrace;

به نظر می رسد که این امضای منبع ردیابی خاص توسط یک کلاس Probe پشتیبانی می شود (what
ما در اینجا نیاز داریم) از کلاس Ipv6PacketProbe. فایل ها را ببینید
src/internet/model/ipv6-packet-probe.{h,cc}.

بنابراین، در عبارت PlotProbe بالا، می بینیم که دستور در حال قلاب کردن ردیابی است
منبع (شناسایی شده توسط رشته مسیر) با یک تطابق ns-3 نوع پروب از Ipv6PacketProbe. اگر
ما از این نوع کاوشگر (منطبق با امضای منبع ردیابی) پشتیبانی نکردیم، نمی‌توانستیم
از این عبارت استفاده کرد (اگرچه برخی از گزاره‌های سطح پایین‌تر می‌توانستند پیچیده‌تر باشند
استفاده می شود، همانطور که در راهنما توضیح داده شده است).

Ipv6PacketProbe خود منابع ردیابی را صادر می کند که داده ها را از آن استخراج می کند
شی بسته کاوش شده:

TypeId
Ipv6PacketProbe::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::Ipv6PacketProbe")
SetParent ()
.AddConstructor ()
.AddTraceSource ( "خروجی"،
"بسته به علاوه شی IPv6 و رابط آن که به عنوان خروجی برای این کاوشگر عمل می کند"
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_output))
.AddTraceSource ( "OutputBytes"،
"تعداد بایت های بسته"،
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_outputBytes))
;
برگرد
}

آرگومان سوم عبارت PlotProbe ما مشخص می کند که ما به
تعداد بایت های این بسته؛ به طور خاص، "OutputBytes" منبع ردیابی از
Ipv6PacketProbe. در نهایت، دو استدلال آخر عبارت، افسانه طرح را ارائه می دهد
برای این سری داده ("تعداد بایت بسته")، و یک دستور قالب بندی گنوپلات اختیاری
(GnuplotAggregator::KEY_BELOW) که می خواهیم کلید نمودار در زیر نمودار درج شود.
گزینه های دیگر عبارتند از NO_KEY، KEY_INSIDE و KEY_ABOVE.

پشتیبانی پی گیری انواع
مقادیر ردیابی شده زیر در زمان نوشتن با Probes پشتیبانی می شوند:

┌¡****************************الم ────────────────────┐
│ نوع TracedValue │ نوع پروب │ فایل │
├¡****************************الم ────────────────────┤
│double │ DoubleProbe │ stats/model/double-probe.h │
├¡****************************الم ────────────────────┤
│uint8_t │ Uinteger8Probe │ stats/model/uinteger-8-probe.h │
├¡****************************الم ────────────────────┤
│uint16_t │ Uinteger16Probe │ stats/model/uinteger-16-probe.h │
├¡****************************الم ────────────────────┤
│uint32_t │ Uinteger32Probe │ stats/model/uinteger-32-probe.h │
├¡****************************الم ────────────────────┤
│bool │ BooleanProbe │ stats/model/uinteger-16-probe.h │
├¡****************************الم ────────────────────┤
│ns3::Time │ TimeProbe │ stats/model/time-probe.h │
└¡****************************الم ────────────────────┘

انواع TraceSource زیر در زمان نگارش توسط Probes پشتیبانی می شوند:

┌¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┐
├¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┤
├¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┤
├¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┤
├¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┤
├¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┤
└¡******************************الم ves vers vs vs vs virecs vs vs valb ──────────┘

همانطور که مشاهده می شود، تنها تعداد کمی از منابع ردیابی پشتیبانی می شوند و همه آنها به سمت آن گرایش دارند
خروجی اندازه بسته (بر حسب بایت). با این حال، بسیاری از انواع داده های اساسی
موجود به عنوان TracedValues ​​را می توان با این کمک ها پشتیبانی کرد.

FileHelper
کلاس FileHelper فقط یک تغییر از مثال قبلی GnuplotHelper است. را
برنامه نمونه خروجی فرمت شده از همان داده های مهر زمانی را ارائه می دهد، مانند موارد زیر:

زمان (ثانیه) = 9.312e+00 بسته تعداد بایت = 596
زمان (ثانیه) = 9.312e+00 بسته تعداد بایت = 564

دو فایل ارائه شده است، یکی برای گره "0" و دیگری برای گره "1" همانطور که در قسمت مشاهده می شود
نام فایل ها بیایید کد را تکه تکه بررسی کنیم:

+ // از FileHelper برای نوشتن تعداد بایت های بسته در طول زمان استفاده کنید
+ FileHelper fileHelper.
+
+ // پیکربندی فایل برای نوشتن و قالب بندی داده های خروجی.
+ fileHelper.ConfigureFile ("seventh-packet-byte-count"،
+ FileAggregator::FORMATTED);

پیشوند فایل کمکی اولین آرگومان است و مشخص کننده فرمت بعدی است. مقداری
گزینه های دیگر برای قالب بندی عبارتند از SPACE_SEPARATED، COMMA_SEPARATED، و TAB_SEPARATED.
کاربران می توانند قالب بندی را (اگر FORMATTED مشخص شده باشد) با یک رشته قالب تغییر دهند
مانند موارد زیر:

+
+ // برچسب ها را برای این فایل خروجی فرمت شده تنظیم کنید.
+ fileHelper.Set2dFormat ("زمان (ثانیه) = %.3e\tPacket Byte Count = %.0f");

در نهایت، منبع ردیابی علاقه باید قلاب شود. باز هم probeType و tracePath
از متغیرهای این مثال استفاده شده است و منبع ردیابی خروجی پروب "OutputBytes" است
قلاب شده:

+
+ // نوع پروب، مسیر منبع ردیابی (در فضای نام پیکربندی) و
+ // کاوش منبع ردیابی خروجی ("OutputBytes") برای نوشتن.
+ fileHelper.WriteProbe (probeType،
+ TracePath،
+ "OutputBytes")؛
+

فیلدهای عام در این مشخص کننده منبع ردیابی با دو منبع ردیابی مطابقت دارند. بر خلاف
مثال GnuplotHelper، که در آن دو سری داده روی یک طرح قرار داده شده اند، در اینجا، دو
فایل های جداگانه روی دیسک نوشته می شوند.

خلاصه
پشتیبانی از جمع آوری داده ها از ns-3.18 جدید است و پشتیبانی اولیه برای ارائه سری های زمانی است
خروجی اضافه شده است الگوی اصلی توضیح داده شده در بالا ممکن است در داخل تکرار شود
دامنه پشتیبانی از کاوشگرهای موجود و منابع ردیابی. قابلیت های بیشتر از جمله
پردازش آمار در نسخه های بعدی اضافه خواهد شد.

نتیجه گیری


آینده
این سند به عنوان یک سند زنده در نظر گرفته شده است. امیدواریم و انتظار داریم در طول زمان رشد کند
برای پوشاندن بیشتر و بیشتر مهره ها و پیچ ها ns-3.

نوشتن فصل‌های راهنما و آموزشی چیزی نیست که همه ما در مورد آن هیجان‌زده می‌شویم، اما همینطور است
برای پروژه بسیار مهم است اگر در یکی از این زمینه ها متخصص هستید لطفا
در نظر گرفتن کمک به ns-3 با ارائه یکی از این فصول؛ یا هر فصل دیگری شما
ممکن است فکر کند مهم است

بستن
ns-3 یک سیستم بزرگ و پیچیده است. پوشاندن همه چیزهای شما غیرممکن است
باید در یک آموزش کوچک بدانید. خوانندگانی که می خواهند بیشتر بیاموزند تشویق می شوند
اسناد اضافی زیر را بخوانید:

· ns-3 کتابچه راهنمای

· ns-3 اسناد کتابخانه مدل

· ns-3 داکسیژن (اسناد API)

· ns-3 ویکی

-- ns-3 تیم توسعه.

با استفاده از خدمات onworks.net از آموزش آنلاین ns-3 استفاده کنید


سرورها و ایستگاه های کاری رایگان

دانلود برنامه های ویندوز و لینوکس

دستورات لینوکس

Ad