آموزش شبیه ساز شبکه ns-3. فصل 5

آموزش شبیه ساز شبکه ns-3. فصل 5
فصل 1,2
فصل 3
فصل 4

5 تنظیمات
5.1 استفاده از ماژول ورود به سیستم
5.1.1 مروری بر ورود
5.1.2 ورود به سیستم را فعال کنید
5.1.3 افزودن ورود به کد شما
5.2 استفاده از آرگومان های خط فرمان
5.2.1 نادیده گرفتن مقادیر مشخصه پیش فرض
5.2.2 گرفتن دستورات خود
5.3 استفاده از سیستم ردیابی
5.3.1 ردیابی ASCII
تجزیه ردیابی ASCII
5.3.2 PCAP Trace

فصل 5

تنظیم

5.1 استفاده از ماژول ورود به سیستم

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

5.1.1 مروری بر ورود

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

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

باید بدانید که ما یک مکانیسم هدف کلی - ردیابی - برای استخراج داده ها از مدل های شما ارائه می دهیم که باید خروجی ترجیحی برای شبیه سازی باشد (برای اطلاعات بیشتر در مورد سیستم ردیابی ما، به بخش آموزشی 5.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_INFO را نیز ممکن می‌سازد. _WARN و NS_LOG_ERROR.

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

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

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

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

5.1.2 ورود به سیستم را فعال کنید

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

$ ./waf --run scratch/myfirst

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

$ Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 'build'
finished successfully (0.413s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

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

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

در حال حاضر، برنامه 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

بنابراین ما متغیر shell NS_LOG را به مقدار زیر تنظیم می کنیم.

UdpEchoClientApplication=level_all

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

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

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

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

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

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

اکنون می توانید ببینید که تمام پیام هایی که از برنامه UDP echo Client می آیند به این صورت شناسایی می شوند. پیام "Received 1024 bytes from 10.1.1.2" اکنون به وضوح مشخص شده است که از برنامه مشتری echo آمده است. پیام باقیمانده باید از برنامه UDP echo server باشد. ما می‌توانیم این مؤلفه را با وارد کردن فهرستی از مؤلفه‌های جدا شده با کولون در متغیر محیطی NS_LOG فعال کنیم.

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

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

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

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

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (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(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (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(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

به یاد بیاورید که فیلمنامه خراش / first.cc برنامه اکو سرور را یک ثانیه قبل از شروع شبیه سازی شروع کرد. اکنون می توانید آن روش را ببینید StartApplication سرور در واقع در ثانیه اول فراخوانی می شود. همچنین ممکن است متوجه شوید که echo client در ثانیه دوم شبیه سازی شروع می شود، همانطور که در اسکریپت پرسیدیم.

اکنون می توانید پیشرفت شبیه سازی را در تماس دنبال کنید ScheduleTransmit در کلاینتی که HandleRead callback Send را در برنامه سرور اکو فرا می خواند. توجه داشته باشید که زمان سپری شده برای ارسال یک بسته از طریق پیوند نقطه به نقطه 3,69 میلی ثانیه است. می‌بینید که سرور اکو پیامی را ثبت می‌کند که به بسته پاسخ داده است، و سپس، پس از تاخیر در کانال، می‌بینید که مشتری echo بسته اکو را به روش HandleRead خود دریافت می‌کند.

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

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

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

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

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

5.1.3 افزودن ورود به کد شما

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

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

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

NodeContainer nodes;
nodes.Create (2);

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

$ ./waf
$ export NS_LOG=
Теперь, если вы запустите скрипт,
$ ./waf --run scratch/myfirst

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

$ export NS_LOG=FirstScriptExample=info

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

5.2 استفاده از آرگومان های خط فرمان

5.2.1 نادیده گرفتن مقادیر مشخصه پیش فرض

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

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

int
main (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}

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

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

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.

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

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

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

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

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

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
The default data rate for point to point links

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

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

...
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
...

ادامه دهید و یک اسکریپت جدید با آن ایجاد کنید وف (./ واف) و بیایید به عقب برگردیم و برخی از ورودی ها را از برنامه UDP echo server اضافه کنیم و پیشوند زمان را اضافه کنیم.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

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

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

به یاد بیاورید که آخرین باری که به زمان شبیه سازی نگاه کردیم، لحظه ای که بسته توسط سرور اکو دریافت شد، 2,00369 ثانیه بود.

2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1

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

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

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

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

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

--ns3::PointToPointChannel::Delay=[0ns]:
Transmission delay through the channel

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

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

در این مورد، زمانی را که به صراحت DataRate و Delay را در اسکریپت تنظیم کرده بودیم، بازیابی می کنیم:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.00369s Received 1024 bytes from 10.1.1.1
2.00369s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

توجه داشته باشید که بسته پس از 2,00369 ثانیه دوباره توسط سرور دریافت می شود. ما در واقع می توانیم هر یک از ویژگی های استفاده شده در اسکریپت را به این ترتیب تنظیم کنیم. به طور خاص، می‌توانیم ویژگی‌های MaxPackets را روی مقادیر غیر یک تنظیم کنیم UdpEchoClient.

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

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

سؤال طبیعی که در این مرحله مطرح می شود این است که چگونه می توان از وجود همه این صفات مطلع شد. باز هم، سیستم خط فرمان یک تابع کمکی برای این موضوع دارد. اگر از خط فرمان کمک بخواهیم، ​​باید ببینیم:

$ ./waf --run "scratch/myfirst --PrintHelp"
myfirst [Program Arguments] [General Arguments]
General Arguments:
--PrintGlobals: Print the list of globals.
--PrintGroups: Print the list of groups.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintTypeIds: Print all TypeIds.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintHelp: Print this help message.

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

./waf --run "scratch/myfirst --PrintGroup=PointToPoint"
TypeIds in group PointToPoint:
ns3::PointToPointChannel
ns3::PointToPointNetDevice
ns3::PointToPointRemoteChannel
ns3::PppHeader

در اینجا می‌توانید نام‌های TypeId موجود برای جستجوی ویژگی‌ها را پیدا کنید، برای مثال در
--PrintAttributes = ns3 :: PointToPointChannelهمانطور که در بالا نشان داده شده.

راه دیگر برای یادگیری ویژگی ها از طریق Doxygen ns-3 است. صفحه ای وجود دارد که تمام ویژگی های ثبت شده در شبیه ساز را فهرست می کند.

5.2.2 گرفتن دستورات خود

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

int
main (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);
cmd.Parse (argc, argv);
...

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

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

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

$ ./waf --run "scratch/myfirst --PrintHelp"
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.403s)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.
User Arguments:
--nPackets: Number of packets to echo

اگر می خواهید تعداد بسته های ارسال شده را تغییر دهید، می توانید این کار را با تنظیم آرگومان خط فرمان -nPackets انجام دهید.

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

حالا باید ببینید

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
Sent 1024 bytes to 10.1.1.2
3.25732s Received 1024 bytes from 10.1.1.1
3.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

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

5.3 استفاده از سیستم ردیابی

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

#include <iostream>
...
int main ()
{
...
std::cout << "The value of x is " << x << std::endl;
...
}

شما حتی می توانید از یک ماژول ورود به سیستم برای اضافه کردن ساختار کمی به راه حل خود استفاده کنید. بسیاری از مشکلات شناخته شده ناشی از این رویکرد وجود دارد، و بنابراین ما یک زیرسیستم ردیابی رویداد کلی برای حل این مشکلات ارائه کرده ایم.

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

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

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

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

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

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

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

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

5.3.1 ردیابی ASCII

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

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

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

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

تماس خارجی EnableAsciiAll() به دستیار می گوید که می خواهید ردیابی ASCII را برای همه اتصالات دستگاه نقطه به نقطه در شبیه سازی خود بگنجانید و می خواهید گیرنده های ردیابی (مشخص شده) اطلاعات حرکت بسته را در قالب ASCII ضبط کنند.

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

$ ./waf --run scratch/myfirst

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

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

تجزیه ردیابی ASCII

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

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

+: یک عملیات صف در صف دستگاه رخ داد.
-: عملیات بازیابی عنصر در صف دستگاه رخ داده است.
د: بسته حذف شد، معمولاً به دلیل پر بودن صف.
r: بسته توسط یک دستگاه شبکه دریافت شد.

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

0 +
1 2
2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
3 ns3::PppHeader (
4   Point-to-Point Protocol: IP (0x0021))
6   ns3::Ipv4Header (
7     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
8     length: 1052 10.1.1.1 > 10.1.1.2)
9     ns3::UdpHeader (
10      length: 1032 49153 > 9)
11      Payload (size=1024)

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

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

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

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

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

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

0 r
1 2.25732
2 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
3   ns3::Ipv4Header (
4     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
5     length: 1052 10.1.1.1 > 10.1.1.2)
6     ns3::UdpHeader (
7       length: 1032 49153 > 9)
8       Payload (size=1024)

توجه داشته باشید که عملیات ردیابی اکنون r است و زمان شبیه سازی به 2,25732 ثانیه افزایش یافته است. اگر آموزش را به دقت دنبال کرده باشید، به این معنی است که DataRate و Link Delay دستگاه های شبکه را در مقادیر پیش فرض خود رها کرده اید. همانطور که در قسمت قبل دیدید این زمان باید آشنا باشد.

ورودی فضای نام منبع ردیابی (خط 2) اصلاح شده است تا نشان دهد که این رویداد از گره 1 (/NodeList/1) و بسته توسط منبع ردیابی دریافت می شود (/MacRx). دنبال کردن حرکت بسته در توپولوژی با نگاه کردن به ردهای باقی مانده در فایل برای شما باید نسبتاً آسان باشد.

5.3.2 PCAP Trace

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

فعال کردن ردیابی pcap با یک خط کد انجام می شود.

pointToPoint.EnablePcapAll ("myfirst");

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

برای نمونه اسکریپت ما، در نهایت فایل هایی با نام "myfirst-0-0.pcap"و"myfirst-1-0.pcap"، که به ترتیب ردیابی های pcap برای نود 0-دستگاه 0 و گره 1-دستگاه 0 هستند. هنگامی که خط کد را برای فعال کردن ردیابی pcap اضافه کردید، می توانید اسکریپت را به روش معمول اجرا کنید:

$ ./waf --run scratch/myfirst

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

خواندن خروجی با tcpdump

در حال حاضر، ساده ترین راه برای مشاهده فایل های pcap استفاده از tcpdump است.

$ tcpdump -nn -tt -r myfirst-0-0.pcap
reading from file myfirst-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
reading from file myfirst-1-0.pcap, link-type PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024

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

خواندن خروجی با Wireshark

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

منبع: www.habr.com

اضافه کردن نظر