الإنجليزيةالفرنسيةالإسبانية

OnWorks فافيكون

ns-3-tutorial - عبر الإنترنت في السحابة

قم بتشغيل البرنامج التعليمي ns-3 في مزود الاستضافة المجاني من OnWorks عبر Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

هذا هو الأمر ns-3-التعليمي الذي يمكن تشغيله في مزود الاستضافة المجانية OnWorks باستخدام إحدى محطات العمل المجانية المتعددة على الإنترنت مثل Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

برنامج:

اسم


ns-3-تعليمي - ns-3 تعليمي

هذا هو NS-3 البرنامج التعليمي. الوثائق الأولية لمشروع ns-3 متاحة في خمسة
نماذج:

· NS-3 Doxygen: توثيق واجهات برمجة التطبيقات العامة لجهاز المحاكاة

· درس تعليمي (هذه وثيقة)، دليل ، ومكتبة نموذجية لـ آخر الافراج عن
تطوير شجرة

· NS-3 ويكي

هذه الوثيقة مكتوبة باللغة reStructuredText لـ أبو الهول ويتم الحفاظ عليه في
وثيقة / تعليمي دليل الكود المصدري ns-3.

مقدمة


إنّ NS-3 simulator هو محاكي شبكة حدث منفصل يستهدف بشكل أساسي البحث
والاستخدام التعليمي. ال NS-3 تنفيذ المشاريع ، الذي بدأ في عام 2006 ، هو مشروع مفتوح المصدر
تطوير NS-3.

الغرض من هذا البرنامج التعليمي هو تقديم الجديد NS-3 المستخدمين إلى النظام بشكل منظم
طريق. يصعب أحيانًا على المستخدمين الجدد جمع المعلومات الأساسية من التفاصيل
كتيبات وتحويل هذه المعلومات إلى محاكاة العمل. في هذا البرنامج التعليمي ، نحن
سيبني العديد من نماذج المحاكاة ، وتقديم وشرح المفاهيم الأساسية و
الميزات كما نذهب.

عندما يتكشف البرنامج التعليمي ، سنقدم الملف الكامل NS-3 التوثيق والتقديم
مؤشرات إلى التعليمات البرمجية المصدر للمهتمين بالتعمق في أعمال
نظام.

تجدر الإشارة إلى بعض النقاط الرئيسية في البداية:

· NS-3 مفتوح المصدر ، ويسعى المشروع جاهدًا للحفاظ على بيئة مفتوحة لـ
الباحثين للمساهمة ومشاركة برامجهم.

· NS-3 ليس امتدادًا متوافقًا مع الإصدارات السابقة لـ NS-2؛ إنها محاكاة جديدة. الاثنان
تمت كتابة كل من أجهزة المحاكاة بلغة C ++ ولكن NS-3 هو جهاز محاكاة جديد لا يدعم
NS-2 واجهات برمجة التطبيقات. بعض الموديلات من NS-2 تم بالفعل استدارتها من NS-2 إلى NS-3.
سيستمر المشروع في الحفاظ عليها NS-2 في حين NS-3 يتم بناؤه ، وسوف يدرس
آليات الانتقال والتكامل.

من نحن؟ NS-3
NS-3 تم تطويره لتوفير منصة محاكاة شبكة مفتوحة وقابلة للتوسيع ، من أجل
البحث الشبكي والتعليم. باختصار، NS-3 يقدم نماذج لكيفية حزم البيانات
تعمل الشبكات وتؤدى ، وتوفر محرك محاكاة للمستخدمين لإجراء
تجارب المحاكاة. بعض أسباب الاستخدام NS-3 تشمل إجراء الدراسات التي
أكثر صعوبة أو لا يمكن إجراؤها باستخدام أنظمة حقيقية ، لدراسة سلوك النظام
في بيئة يمكن التحكم فيها بشكل كبير وقابلة للتكرار ، وللتعرف على كيفية عمل الشبكات.
سيلاحظ المستخدمون أن النموذج المتاح تم تعيينه في NS-3 يركز على نمذجة كيفية الإنترنت
تعمل البروتوكولات والشبكات ، ولكن NS-3 لا يقتصر على أنظمة الإنترنت ؛ عدة مستخدمين
يستخدمون NS-3 لنمذجة الأنظمة غير المستندة إلى الإنترنت.

توجد العديد من أدوات المحاكاة لدراسات محاكاة الشبكة. فيما يلي عدد قليل
السمات المميزة لـ NS-3 على عكس الأدوات الأخرى.

· NS-3 تم تصميمه كمجموعة من المكتبات التي يمكن دمجها معًا وأيضًا مع أخرى
مكتبات البرامج الخارجية. بينما توفر بعض منصات المحاكاة للمستخدمين ملف
بيئة واجهة مستخدم رسومية واحدة متكاملة يتم فيها تنفيذ جميع المهام
من، NS-3 هو أكثر نمطية في هذا الصدد. العديد من الرسوم المتحركة الخارجية وتحليل البيانات
وأدوات التصور يمكن استخدامها مع NS-3. ومع ذلك ، يجب أن يتوقع المستخدمون العمل في
سطر الأوامر وباستخدام أدوات تطوير برامج C ++ و / أو Python.

· NS-3 يستخدم بشكل أساسي على أنظمة Linux ، على الرغم من وجود دعم لـ FreeBSD و Cygwin
(لنظام التشغيل Windows) ، ودعم Windows Visual Studio الأصلي قيد التنفيذ
المتقدمة.

· NS-3 ليس منتجًا برمجيًا مدعومًا رسميًا لأي شركة. الدعم ل NS-3
يتم على أساس أفضل جهد على القائمة البريدية ns-3-users.

في حالة NS-2 المستخدمين
لمن هم على دراية NS-2 (أداة شائعة سبقت NS-3) ، الأكثر وضوحا من الخارج
تغيير عند الانتقال إلى NS-3 هو اختيار لغة البرمجة النصية. البرامج في NS-2 .
نصت في OTcl ويمكن تصور نتائج المحاكاة باستخدام Network Animator
نام. لا يمكن تشغيل محاكاة في NS-2 بحتة من C ++ (على سبيل المثال ، باعتباره رئيسي ()
البرنامج بدون أي OTcl). علاوة على ذلك ، فإن بعض مكونات NS-2 مكتوبة بلغة C ++ و
آخرون في OTcl. في NS-3، المحاكي مكتوب بالكامل بلغة C ++ ، مع بايثون اختياري
الارتباطات. لذلك يمكن كتابة نصوص المحاكاة بلغة C ++ أو Python. رسامو الرسوم المتحركة الجدد
والمتخيلون متاحة وتحت التطوير الحالي. منذ 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 المتطورة) ، ودعمها لكود التنفيذ
يقبل مجموعة واسعة جدًا من النماذج عالية الدقة. قد يفاجأ المستخدمون لمعرفة ذلك
يمكن تغليف مكدس شبكات Linux بالكامل في ملف NS-3 العقدة ، باستخدام Direct
إطار تنفيذ التعليمات البرمجية (DCE). NS-2 يمكن أحيانًا نقل النماذج إلى ملفات NS-3، خصوصا
إذا تم تنفيذها في C ++.

إذا كنت في شك ، فإن الدليل الجيد هو النظر إلى كل من المحاكيات (بالإضافة إلى غيرها
المحاكاة) ، وعلى وجه الخصوص النماذج المتاحة لبحثك ، ولكن ضع في اعتبارك
أن تجربتك قد تكون أفضل في استخدام الأداة التي يتم تطويرها بنشاط و
مصانة (NS-3).

المساهمة
NS-3 هو محاكاة بحثية وتعليمية ، من قبل مجتمع البحث ومن أجله. فإنه سوف
الاعتماد على المساهمات المستمرة للمجتمع لتطوير نماذج جديدة أو تصحيح أو
الحفاظ على الموجودة ، وتبادل النتائج. هناك بعض السياسات التي نأمل أن تفعلها
تشجيع الناس على المساهمة في NS-3 مثل ما لديهم من أجل NS-2:

ترخيص مفتوح المصدر على أساس توافق GNU GPLv2

· ويكي

· ساهمت رمز الصفحة ، على غرار NS-2رمز المساهمة الشهير صفحة

· فتح علة تعقب

نحن ندرك أنه إذا كنت تقرأ هذه الوثيقة ، فإن المساهمة في المشروع هي
ربما لا يكون مصدر قلقك الأول في هذه المرحلة ، لكننا نريدك أن تكون على دراية بذلك
المساهمة في روح المشروع وحتى فعل إسقاط ملاحظة لنا
حول تجربتك المبكرة مع NS-3 (على سبيل المثال ، "لم يكن قسم البرنامج التعليمي هذا واضحًا ...") ،
هي محل تقدير كبير تقارير الوثائق التي لا معنى لها ، وما إلى ذلك.

البرنامج التعليمي منظمة
يفترض البرنامج التعليمي أن المستخدمين الجدد قد يتبعون في البداية مسارًا مثل ما يلي:

· حاول تنزيل وبناء نسخة ؛

· حاول تشغيل بعض نماذج البرامج.

· انظر إلى إخراج المحاكاة ، وحاول تعديله.

نتيجة لذلك ، حاولنا تنظيم البرنامج التعليمي على طول التسلسل العريض أعلاه
التالي.

الموارد


إنّ شبكة
هناك العديد من الموارد الهامة أي منها 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-ديف. الإصدارات السابقة و
يمكن أيضًا العثور على المستودعات التجريبية للمطورين الأساسيين هناك.

زئبقي
تحتاج أنظمة البرامج المعقدة إلى طريقة ما لإدارة المنظمة والتغييرات التي تطرأ على
الكود الأساسي والوثائق. هناك طرق عديدة للقيام بهذا العمل الفذ ، ويمكنك القيام بذلك
سمعت عن بعض الأنظمة المستخدمة حاليًا للقيام بذلك. المتزامنة
ربما يكون نظام الإصدار (CVS) هو الأكثر شهرة.

إنّ NS-3 يستخدم المشروع Mercurial كنظام إدارة التعليمات البرمجية المصدر. على الرغم من أنك لا تفعل ذلك
بحاجة إلى معرفة الكثير عن Mercurial لإكمال هذا البرنامج التعليمي ، نوصي
التعرف على Mercurial واستخدامه للوصول إلى شفرة المصدر. Mercurial له امتداد
موقع الويب في http://www.selenic.com/mercurial/، والتي يمكنك من خلالها الحصول على ثنائي أو مصدر
إصدارات نظام إدارة تكوين البرامج (SCM). سيلينيك (المطور
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
بمجرد تنزيل شفرة المصدر إلى نظامك المحلي ، ستحتاج إلى تجميع ذلك
مصدر لإنتاج برامج قابلة للاستخدام. تمامًا كما في حالة إدارة الكود المصدري ، هناك
هناك العديد من الأدوات المتاحة لأداء هذه الوظيفة. ربما الأكثر شهرة من هؤلاء
الأدوات جعل. إلى جانب كونها الأكثر شهرة ، جعل ربما هو الأصعب
لاستخدامها في نظام كبير جدًا وقابل للتكوين بدرجة عالية. بسبب هذا ، العديد من البدائل
تم تطويره. تم تطوير هذه الأنظمة مؤخرًا باستخدام Python
لغة.

يستخدم نظام البناء Waf على NS-3 مشروع. إنه أحد الجيل الجديد من
أنظمة بناء مبنية على بايثون. لن تحتاج إلى فهم أي لغة بايثون لبناء ملف
القائمة NS-3 نظام.

للمهتمين بالتفاصيل الدموية لـ Waf ، يمكن العثور على موقع الويب الرئيسي على
http://code.google.com/p/waf/.

التطوير البيئة
كما ذكر أعلاه ، فإن البرمجة النصية بتنسيق NS-3 يتم إجراؤه في C ++ أو Python. أكثر من NS-3 API هو
متوفر في Python ، لكن النماذج مكتوبة بلغة C ++ في كلتا الحالتين. عمل
يفترض في هذا المستند معرفة لغة C ++ والمفاهيم الكينونية. سوف نأخذ
بعض الوقت لمراجعة بعض المفاهيم الأكثر تقدمًا أو ربما لغة غير مألوفة
الميزات والتعابير وأنماط التصميم كما تظهر. لا نريد هذا البرنامج التعليمي
انتقل إلى برنامج تعليمي C ++ ، على الرغم من ذلك ، لذلك نتوقع أمرًا أساسيًا للغة.
هناك عدد لا يمكن تصوره تقريبًا من مصادر المعلومات حول C ++ المتاحة على
الويب أو المطبوع.

إذا كنت مستخدمًا جديدًا لـ C ++ ، فقد ترغب في العثور على كتاب تعليمي أو كتاب طبخ أو موقع ويب
والعمل من خلال الميزات الأساسية للغة على الأقل قبل المتابعة. ل
نموذج، البرنامج التعليمي.

إنّ NS-3 يستخدم النظام عدة مكونات من "سلسلة أدوات" جنو من أجل التنمية. أ
سلسلة أدوات البرمجيات هي مجموعة أدوات البرمجة المتاحة في بيئة معينة. ل
مراجعة سريعة لما تم تضمينه في سلسلة أدوات جنو انظر ،
http://en.wikipedia.org/wiki/GNU_toolchain. NS-3 يستخدم gcc و GNU binutils و gdb.
ومع ذلك ، فإننا لا نستخدم أدوات نظام البناء GNU ، ولا التصنيع ولا الأدوات الآلية. نحن نستخدم Waf
لهذه الوظائف.

عادةً ما يكون ملف NS-3 المؤلف سيعمل في Linux أو بيئة تشبه Linux. لأولئك
يعمل تحت Windows ، توجد بيئات تحاكي بيئة Linux
بدرجات مختلفة. ال NS-3 تم دعم المشروع في الماضي (ولكن ليس حاليًا)
التطوير في بيئة Cygwin لهؤلاء المستخدمين. يرى http://www.cygwin.com/ لـ
تفاصيل حول التنزيل ، وقم بزيارة NS-3 wiki لمزيد من المعلومات حول Cygwin و
NS-3. MinGW غير مدعوم رسميًا حاليًا. بديل آخر لـ Cygwin هو
قم بتثبيت بيئة جهاز ظاهري مثل خادم VMware وتثبيت نظام Linux الظاهري
آلة.

البريزة برمجة وتطوير
سنفترض مرفقًا أساسيًا مع Berkeley Sockets API في الأمثلة المستخدمة في هذا
درس تعليمي. إذا كنت جديدًا على المقابس ، فإننا نوصي بمراجعة واجهة برمجة التطبيقات وبعض الاستخدامات الشائعة
حالات. للحصول على نظرة عامة جيدة على برمجة مآخذ TCP / IP ، نوصي TCP / IP مآخذ in
C, دوناهو كالفيرت.

هناك موقع ويب مرتبط يتضمن مصدرًا للأمثلة الموجودة في الكتاب ، والتي
يمكنك أن تجد في: http://cs.baylor.edu/~donahoo/practical/CSockets/.

إذا فهمت الفصول الأربعة الأولى من الكتاب (أو لأولئك الذين ليس لديهم وصول
إلى نسخة من الكتاب ، عملاء وخوادم الصدى الموضحة في موقع الويب أعلاه) ستفعل
أن تكون في حالة جيدة لفهم البرنامج التعليمي. يوجد كتاب مشابه عن البث المتعدد
مآخذ الإرسال المتعدد مآخذ ماكوفسكي ألمروث. يغطي المواد التي قد تحتاج إليها
افهم إذا نظرت إلى أمثلة الإرسال المتعدد في التوزيع.

الحصول على بدأت


يهدف هذا القسم إلى جعل المستخدم في حالة عمل تبدأ بآلة
ربما لم يكن لديه NS-3 المثبتة. وهو يغطي المنصات المدعومة والمتطلبات الأساسية وطرق
تحصل NS-3، طرق البناء NS-3، وطرق التحقق من الإنشاء وتشغيل البرامج البسيطة.

نظرة عامة
NS-3 تم بناؤه كنظام من مكتبات البرامج التي تعمل معًا. يمكن أن تكون برامج المستخدم
مكتوبة ترتبط (أو تستورد من) هذه المكتبات. برامج المستخدم مكتوبة بلغة
إما لغات البرمجة C ++ أو Python.

NS-3 يتم توزيعه ككود مصدر ، مما يعني أن النظام المستهدف يحتاج إلى
بيئة تطوير البرمجيات لبناء المكتبات أولاً ، ثم بناء المستخدم
برنامج. NS-3 يمكن توزيعها من حيث المبدأ كمكتبات مبنية مسبقًا لمجموعة مختارة
الأنظمة ، وقد يتم توزيعها في المستقبل بهذه الطريقة ، ولكن في الوقت الحاضر ، العديد من المستخدمين
في الواقع يقومون بعملهم عن طريق التحرير NS-3 نفسها ، لذا فإن وجود شفرة المصدر حولها لإعادة بنائها
المكتبات مفيدة. إذا كان شخص ما يرغب في القيام بمهمة صنع مسبق الصنع
مكتبات وحزم لأنظمة التشغيل ، يرجى الاتصال بالبريدية ns-Developers
قائمة.

في ما يلي ، سنلقي نظرة على طريقتين للتنزيل والبناء NS-3. الأول هو
لتنزيل وبناء إصدار رسمي من موقع الويب الرئيسي. والثاني هو جلب
وبناء نسخ تطوير من NS-3. سنستعرض كلا المثالين منذ الأدوات
المعنية مختلفة قليلا.

تحميل NS-3
إنّ NS-3 النظام ككل هو نظام معقد إلى حد ما ولديه عدد من التبعيات عليه
المكونات الأخرى. إلى جانب الأنظمة التي من المرجح أن تتعامل معها كل يوم (ملف
GNU toolchain ، Mercurial ، محرر نصوص) ستحتاج إلى التأكد من أن عددًا من
مكتبات إضافية موجودة على نظامك قبل المتابعة. NS-3 يوفر ويكي
صفحة تتضمن صفحات بها العديد من التلميحات والنصائح المفيدة. إحدى هذه الصفحات هي
صفحة "التثبيت" ، http://www.nsnam.org/wiki/Installation.

يوضح قسم "المتطلبات الأساسية" في صفحة wiki هذه الحزم المطلوبة
دعم مشترك NS-3 الخيارات ، كما يوفر الأوامر المستخدمة لتثبيتها من أجل
متغيرات Linux الشائعة. سيتعين على مستخدمي Cygwin استخدام مثبت Cygwin (إذا كنت من مستخدمي
مستخدم Cygwin ، لقد استخدمته لتثبيت Cygwin).

قد ترغب في اغتنام هذه الفرصة لاستكشاف NS-3 ويكي قليلا لأن هناك حقا
ثروة من المعلومات هناك.

من هذه النقطة فصاعدًا ، سنفترض أن القارئ يعمل في Linux أو
بيئة محاكاة Linux (Linux ، Cygwin ، إلخ.) وتحتوي على GNU toolchain مثبتة و
التحقق مع المتطلبات المسبقة المذكورة أعلاه. سوف نفترض ذلك أيضًا
لديك Mercurial و Waf مثبتان ويعملان على النظام المستهدف.

إنّ NS-3 الكود متاح في مستودعات Mercurial على الخادم http://code.nsnam.org.
يمكنك أيضًا تنزيل إصدار tarball من http://www.nsnam.org/release/، أو يمكنك العمل
مع مستودعات باستخدام Mercurial. نوصي باستخدام Mercurial ما لم يكن هناك فائدة
سبب عدم القيام بذلك. راجع نهاية هذا القسم للحصول على إرشادات حول كيفية الحصول على كرة تار
الافراج.

إن أبسط طريقة لبدء استخدام مستودعات Mercurial هي استخدام ملحق ns-3-allinone
بيئة. هذه مجموعة من البرامج النصية التي تدير تنزيل وبناء ملفات
أنظمة فرعية مختلفة من NS-3 لك. نوصي أن تبدأ الخاص بك NS-3 العمل في هذا
بيئة.

ممارسة واحدة هي إنشاء دليل يسمى مساحة العمل في الدليل الرئيسي للفرد تحته
يمكن للمرء الاحتفاظ بمستودعات Mercurial المحلية. أي اسم دليل سيفي بالغرض ، لكننا سنفترض
أن مساحة العمل مستخدم هنا (ملاحظة: اتفاقيات إعادة الشراء يمكن أيضًا استخدامها في بعض الوثائق كملف
مثال اسم الدليل).

تحميل NS-3 باستخدام a تاربال
تعد كرة القطران تنسيقًا خاصًا لأرشيف البرامج حيث يتم تجميع ملفات متعددة
معًا وربما يكون الأرشيف مضغوطًا. NS-3 يتم توفير إصدارات البرامج عبر أ
تاربال القابل للتنزيل. عملية التنزيل NS-3 عبر tarball بسيط ؛ انت فقط
عليك اختيار إصدار وتنزيله وفك ضغطه.

لنفترض أنك ، كمستخدم ، ترغب في بناء NS-3 في دليل محلي يسمى
مساحة العمل. إذا كنت تتبنى ملف مساحة العمل نهج الدليل ، يمكنك الحصول على نسخة من الإصدار
عن طريق كتابة ما يلي في قشرة Linux (استبدل أرقام الإصدارات المناسبة ،
بالطبع):

$ cd
مساحة عمل $ mkdir
مساحة عمل $ cd
$ وجيت http://www.nsnam.org/release/ns-allinone-3.22.tar.bz2
tar xjf ns-allinone-3.22.tar.bz2 دولار

إذا قمت بالتغيير إلى الدليل NS- ألينون 3.22 يجب أن تشاهد عددًا من الملفات:

ليرة سورية
ثوابت الخبز. py ns-3.22 README
build.py netanim-3.105 pybindgen-0.16.0.886 util.py

أنت الآن جاهز لبناء القاعدة NS-3 التوزيع.

تحميل NS-3 باستخدام خبز
Bake هي أداة للتكامل والبناء الموزعين ، تم تطويرها لـ NS-3 مشروع.
يمكن استخدام Bake لجلب إصدارات التطوير من NS-3 البرامج ، وللتنزيل و
بناء ملحقات للقاعدة NS-3 التوزيع ، مثل تنفيذ الرمز المباشر
البيئة ، ومهد محاكاة الشبكة ، والقدرة على إنشاء روابط Python جديدة ، وغيرها.

مؤخرا NS-3 الإصدارات ، تم تضمين Bake في الإصدار tarball. التكوين
الملف المضمن في الإصدار الذي تم إصداره سيسمح لأحد بتنزيل أي برنامج كان
الحالي في وقت الإصدار. هذا هو ، على سبيل المثال ، إصدار Bake الذي هو
وزعت مع NS-3.21 يمكن استخدام الإصدار لجلب المكونات الخاصة بذلك NS-3 الافراج عن
أو أقدم ، ولكن لا يمكن استخدامها لجلب المكونات للإصدارات اللاحقة (ما لم يكن ملف
Bakeconf.xml تم تحديث الملف).

يمكنك أيضًا الحصول على أحدث نسخة من خبز عن طريق كتابة ما يلي في Linux الخاص بك
شل (على افتراض أنك قمت بتثبيت Mercurial):

$ cd
مساحة عمل $ mkdir
مساحة عمل $ cd
استنساخ $ hg http://code.nsnam.org/bake

أثناء تنفيذ الأمر hg (Mercurial) ، يجب أن ترى شيئًا مشابهًا لما يلي
عرض،


دليل الوجهة: خبز
يطلب كل التغييرات
مضيفا مجموعات التغييرات
مضيفا البيانات
مضيفا تغييرات الملف
تمت إضافة 339 مجموعة تغييرات مع 796 تغييرًا إلى 63 ملفًا
التحديث إلى الفرع الافتراضي
تم تحديث 45 ملفًا ، 0 تم دمج الملفات ، 0 إزالة الملفات ، 0 ملفات لم يتم حلها

بعد اكتمال أمر النسخ ، يجب أن يكون لديك دليل يسمى خبز، محتويات
والتي يجب أن تبدو على النحو التالي:

ليرة سورية
bake bakeconf.xml doc create-binary.py TODO
اختبار أمثلة bake.py

لاحظ أنك قمت بالفعل بتنزيل بعض نصوص Python ووحدة Python تسمى
خبز. ستكون الخطوة التالية هي استخدام هذه البرامج النصية لتنزيل وبناء ملف NS-3
توزيع من اختيارك.

هناك عدد قليل من أهداف التكوين المتاحة:

1. NS-3.22: الوحدة المقابلة للإصدار ؛ سيتم تنزيل مكونات مماثلة
لإطلاق القطران.

2. NS-3-ديف: وحدة مماثلة ولكن باستخدام شجرة كود التطوير

3. NS- ألينون 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 في مسارك ، مثل ما يلي (مثال Linux bash shell). أولا ، التغيير
في دليل "bake" ، ثم قم بتعيين متغيرات البيئة التالية

تصدير $ BAKE_HOME = `pwd`
مسار التصدير $ = مسار الدولار: $ BAKE_HOME: $ BAKE_HOME / build / bin
$ export PYTHONPATH = $ PYTHONPATH: $ BAKE_HOME: $ BAKE_HOME / build / lib

سيؤدي هذا إلى وضع برنامج bake.py في مسار الصدفة ، وسيسمح للبرامج الأخرى بذلك
البحث عن الملفات التنفيذية والمكتبات التي أنشأتها bake. على الرغم من أن العديد من حالات استخدام الخبز لا تفعل ذلك
تتطلب إعداد PATH و PYTHONPATH على النحو الوارد أعلاه ، والبنيات الكاملة من ns-3-allinone (مع
الحزم الاختيارية) عادةً ما تفعل.

انتقل إلى دليل مساحة العمل واكتب ما يلي في قشرتك:

$ ./bake.py تكوين -e ns-3.22

بعد ذلك ، سنطلب bake للتحقق مما إذا كانت لدينا أدوات كافية لتنزيل مكونات مختلفة.
النوع:

$ ./bake.py الاختيار

يجب أن ترى شيئًا مثل ما يلي ،

> بايثون - حسنًا
> مترجم GNU C ++ - حسنًا
> زئبقي - حسنًا
> CVS - حسنًا
> GIT - حسنًا
> بازار - حسنًا
> أداة القطران - حسنًا
> أداة فك الضغط - حسنًا
> أداة Unrar - مفقود
> 7z أداة ضغط البيانات - حسنًا
> أداة ضغط البيانات XZ - حسنًا
> تقديم - موافق
> cMake - حسنًا
> أداة التصحيح - حسنًا
> أداة autoreconf - حسنًا

> بحث المسار عن الأدوات: /usr/lib64/qt-3.3/bin / usr / lib64 / ccache
/ البيرة / المحلية / بن / بن / البيرة / بن / usr / local / sbin / usr / sbin / sbin
/ home / tomh / bin bin

على وجه الخصوص ، أدوات التنزيل مثل Mercurial و CVS و GIT و Bazaar هي أدواتنا الأساسية
في هذه المرحلة ، لأنها تسمح لنا بإحضار الكود. الرجاء التثبيت في عداد المفقودين
في هذه المرحلة ، بالطريقة المعتادة لنظامك (إذا كنت قادرًا على ذلك) ، أو الاتصال
مسؤول النظام لديك حسب الحاجة لتثبيت هذه الأدوات.

بعد ذلك ، حاول تنزيل البرنامج:

$ ./bake.py تنزيل

يجب أن تسفر عن شيء مثل:

>> البحث عن pygoocanvas التبعية للنظام - حسنًا
>> البحث عن تبعية النظام python-dev - حسنًا
>> البحث عن نظام تبعية pygraphviz - موافق
>> تنزيل pybindgen-0.16.0.886 - حسنًا
>> البحث عن تبعية النظام g ++ - OK
>> البحث عن تبعية النظام qt4 - موافق
>> تنزيل netanim-3.105 - حسنًا
>> تنزيل ns-3.22 - حسنًا

يشير ما سبق إلى أنه تم تنزيل ثلاثة مصادر. افحص ال مصدر دليل
الآن واكتب ls؛ يجب على المرء أن يرى:

ليرة سورية
نتانيم-3.105 ns-3.22 pybindgen-0.16.0.886

أنت الآن جاهز لبناء NS-3 التوزيع.

ابني NS-3
ابني مع build.py
عند العمل من كرة تار تم إصدارها ، في المرة الأولى التي تقوم فيها ببناء ملف NS-3 مشروع يمكنك
بناء باستخدام برنامج ملائم موجود في ALLINONE الدليل. هذا البرنامج يسمى
build.py. سيعمل هذا البرنامج على تهيئة المشروع لك في أغلب الأحيان
طريقة مفيدة. ومع ذلك ، يرجى ملاحظة أن التكوين أكثر تقدمًا والعمل مع NS-3 سوف
عادة ما تنطوي على استخدام الأم NS-3 نظام البناء ، Waf ، ليتم تقديمه لاحقًا في هذا
البرنامج التعليمي.

إذا قمت بالتنزيل باستخدام tarball ، يجب أن يكون لديك دليل يسمى شيء مثل
NS- ألينون 3.22 تحت الخاص بك ~ / مساحة العمل الدليل. اكتب ما يلي:

$ ./build.py - أمثلة التمكين - اختبارات التمكين

لأننا نعمل مع أمثلة واختبارات في هذا البرنامج التعليمي ، ولأنها ليست كذلك
بنيت بشكل افتراضي في NS-3، فإن الحجج الخاصة بـ build.py تخبرها ببنائها لنا. ال
يتخلف البرنامج أيضًا عن بناء جميع الوحدات المتاحة. في وقت لاحق ، يمكنك البناء NS-3
بدون أمثلة واختبارات ، أو حذف الوحدات غير الضرورية لعملك ،
لو كنت تريد.

سترى الكثير من رسائل إخراج المحول البرمجي النموذجية معروضة أثناء إنشاء البرنامج النصي للبناء
القطع المختلفة التي قمت بتنزيلها. في النهاية يجب أن ترى ما يلي:

Waf: مغادرة الدليل "/path/to/workspace/ns-allinone-3.22/ns-3.22/build"
انتهى "البناء" بنجاح (6 م 25.032 ث)

الوحدات المبنية:
تطبيقات هوائي aodv
بناء الجسر مخزن التكوين
الأساسية csma تخطيط csma
طاقة dsdv dsr
fd-net-جهاز مراقبة تدفق الإنترنت
شبكة lr-wpan lte
التنقل MPI netanim (بدون Python)
شبكة nix-vector-routing olsr
انتشار التخطيط من نقطة إلى نقطة من نقطة إلى نقطة
ستة احصائيات الطيف
اختبار جسر الصنبور (بدون بايثون) قراءة طبولوجيا
موجة جهاز شبكة افتراضية
واي فاي wimax

الوحدات التي لم يتم إنشاؤها (انظر البرنامج التعليمي ns-3 للتوضيح):
برايت انقر فوق openflow
متخيل

دليل الخروج "./ns-3.22"

فيما يتعلق بالجزء الخاص بالوحدات غير المبنية:

الوحدات التي لم يتم إنشاؤها (انظر البرنامج التعليمي ns-3 للتوضيح):
برايت انقر فوق openflow
متخيل

هذا يعني فقط أن البعض NS-3 الوحدات النمطية التي لها تبعيات على مكتبات خارجية قد لا تفعل ذلك
أو أن التكوين طلب على وجه التحديد عدم بنائها. نعم هو كذلك
لا يعني أن جهاز المحاكاة لم يبني بنجاح أو أنه سيقدم خطأ
نتائج الوحدات المدرجة على أنها قيد الإنشاء.

ابني مع خبز
إذا استخدمت bake أعلاه لجلب شفرة المصدر من مستودعات المشروع ، فيمكنك المتابعة
استخدامه للبناء NS-3. اكتب

$ ./bake.py البناء

ويجب أن ترى شيئًا مثل:

>> بناء pybindgen-0.16.0.886 - حسنًا
>> بناء netanim-3.105 - حسنًا
>> المبنى ns-3.22 - حسنًا

ملحوظة: لصحتك! يمكن أيضا نفذ على حد سواء خطوات، بإمكانك تحميله نساعدك في بناء by دعوة bake.py نشر'.

إذا حدث فشل ، فالرجاء إلقاء نظرة على ما يقوله الأمر التالي
أنت؛ قد يعطي تلميحًا إلى تبعية مفقودة:

عرض $ ./bake.py

سيؤدي هذا إلى سرد التبعيات المختلفة للحزم التي تحاول بناءها.

ابني مع WAF
حتى هذه النقطة ، استخدمنا إما build.py النصي أو خبز أداة للحصول عليها
بدأت بالبناء NS-3. هذه الأدوات مفيدة للبناء NS-3 ودعم
المكتبات ، ويدعون إلى NS-3 الدليل لاستدعاء أداة Waf build للقيام بامتداد
البناء الفعلي. ينتقل معظم المستخدمين بسرعة إلى استخدام Waf مباشرة لتكوين و
نساعدك في بناء NS-3. لذا ، للمتابعة ، يرجى تغيير دليل العمل الخاص بك إلى NS-3 دليل
الذي قمت ببنائه في البداية.

ليس مطلوبًا بشكل صارم في هذه المرحلة ، ولكن سيكون من المفيد اتخاذ منعطف طفيف
وإلقاء نظرة على كيفية إجراء تغييرات على تكوين المشروع. ربما الأكثر
سيكون تغيير التكوين المفيد الذي يمكنك إجراؤه هو إنشاء الإصدار الأمثل من
شفرة. بشكل افتراضي ، قمت بتكوين مشروعك لإنشاء نسخة تصحيح الأخطاء. دعنا نقول
مشروع إنشاء بناء محسن. لشرح ل Waf أنه ينبغي القيام به على النحو الأمثل
التي تتضمن الأمثلة والاختبارات ، سوف تحتاج إلى تنفيذ ما يلي
أوامر:

./waf نظيف
$ ./waf --build-profile = الأمثل - أمثلة التمكين - تكوين الاختبارات الممكنة

يؤدي هذا إلى تشغيل Waf خارج الدليل المحلي (الذي يتم توفيره كراحة لك).
لا يعد الأمر الأول لتنظيف البنية السابقة ضروريًا تمامًا ولكن
هي ممارسة جيدة (ولكن انظر البناء ملامح، أقل)؛ سوف يزيل ما تم بناؤه مسبقًا
المكتبات وملفات الكائنات الموجودة في الدليل يبني/. عندما يتم إعادة تكوين المشروع
ويقوم نظام البناء بالتحقق من التبعيات المختلفة ، يجب أن ترى الإخراج الذي يبدو
على غرار ما يلي:

الإعداد إلى:.
الانطلاق إلى: البناء
التحقق من "gcc" (c compiler): / usr / bin / gcc
التحقق من إصدار cc: 4.2.1
التحقق من 'g ++' (مترجم c ++): / usr / bin / g ++
يتضمن فحص التعزيز: 1_46_1
التحقق من تعزيز libs: حسنًا
التحقق من ارتباط التعزيز: حسنًا
التحقق من موقع النقر: غير موجود
التحقق من وجود برنامج 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: نعم
التحقق من header sys / inttypes.h: غير موجود
التحقق من header sys / types.h: نعم
التحقق من header sys / stat.h: نعم
التحقق من رأس dirent.h: نعم
التحقق من عنوان stdlib.h: نعم
التحقق من وجود إشارة الرأس. h: نعم
التحقق من وجود pthread.h رأس: نعم
التحقق من عنوان stdint.h: نعم
التحقق من العنوان inttypes.h: نعم
التحقق من header sys / inttypes.h: غير موجود
التحقق من مكتبة RT: غير موجود
التحقق من رأس netpacket / packet.h: غير موجود
التحقق من header sys / ioctl.h: نعم
التحقق من header net / if.h: غير موجود
التحقق من header 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 = مهمل- d ... الدعم: حسنًا
التحقق من علم التجميع -Wno-error = مهمل- d ... الدعم: حسنًا
التحقق من علم التجميع - التعرج الصارم ... الدعم: حسنًا
التحقق من علم التجميع - التعرج الصارم ... الدعم: حسنًا
التحقق من وجود علامة تجميع -Wstrict-Aliasing ... الدعم: حسنًا
التحقق من وجود علامة تجميع -Wstrict-Aliasing ... الدعم: حسنًا
التحقق من برنامج doxygen: / usr / local / bin / doxygen
---- ملخص لميزات NS-3 الاختيارية:
بناء الملف الشخصي: التصحيح
بناء الدليل: بناء
ربط بايثون: مُمكّن
تكامل BRITE: غير ممكّن (لم يتم تمكين BRITE (راجع الخيار - مع brite))
NS-3 انقر فوق التكامل: غير ممكّن (لم يتم تمكين nsclick (راجع الخيار - مع nsclick))
GtkConfigStore: مُمكّن
XmlIo: ممكن
أساسيات الترابط: مُمكّن
Real Time Simulator: مُمكّن (librt غير متوفر)
جهاز صافي تمت محاكاته: ممكّن ( تشمل لم يتم الكشف عنها)
واصف ملف NetDevice: مُمكّن
انقر فوق FdNetDevice: غير ممكّن (يحتاج إلى linux / if_tun.h)
مضاهاة FdNetDevice: غير ممكّن (يحتاج netpacket / packet.h)
PlanetLab FdNetDevice: لم يتم تمكينه (لم يتم اكتشاف نظام التشغيل PlanetLab (راجع الخيار --force-planetlab))
مهد محاكاة الشبكة: غير ممكّن (لم يتم العثور على NSC (راجع الخيار - with-nsc))
دعم MPI: مُمكّن
NS-3 OpenFlow Integration: غير ممكّن (لم يتم العثور على مكتبات التعزيز المطلوبة ، مفقودة: النظام ، الإشارات ، نظام الملفات)
إخراج بيانات احصائيات SQlite: ممكن
انقر فوق Bridge: غير ممكّن ( تشمل لم يتم الكشف عنها)
متخيل PyViz: ممكن
استخدم sudo لضبط suid bit: غير ممكّن (الخيار - تمكين - sudo غير محدد)
بناء الاختبارات: ممكن
بناء الأمثلة: ممكن
مكتبة جنو العلمية (GSL): مُمكّن
انتهى "التكوين" بنجاح (1.944 ثانية)

لاحظ الجزء الأخير من الإخراج أعلاه. بعض NS-3 لا يتم تمكين الخيارات افتراضيًا أو
تتطلب دعمًا من النظام الأساسي للعمل بشكل صحيح. على سبيل المثال ، لتمكين
XmlTo ، يجب العثور على مكتبة libxml-2.0 في النظام. إذا لم تكن هذه المكتبة
وجدت المقابلة NS-3 لن يتم تمكين الميزة وستكون الرسالة
عرض. لاحظ كذلك أن هناك ميزة لاستخدام البرنامج سودو لضبط suid
قليلا من بعض البرامج. لا يتم تمكين هذا افتراضيًا ولذا يتم الإبلاغ عن هذه الميزة
على أنها "غير ممكّنة".

انتقل الآن وعد إلى بنية التصحيح التي تتضمن الأمثلة والاختبارات.

./waf نظيف
$ ./waf --build-profile = التصحيح - أمثلة التمكين - تكوين الاختبارات الممكنة

تم تكوين نظام البناء الآن ويمكنك إنشاء إصدارات تصحيح الأخطاء من NS-3
البرامج ببساطة عن طريق الكتابة

$ ./واف

حسنًا ، آسف ، لقد جعلتك تبني NS-3 جزء من النظام مرتين ، لكنك الآن تعرف كيفية ذلك
تغيير التكوين وبناء كود محسن.

يدعم البرنامج النصي build.py الذي تمت مناقشته أعلاه أيضًا ملف - أمثلة قابلة للتمكين تمكين الاختبارات
الحجج ، ولكن بشكل عام ، لا تدعم بشكل مباشر خيارات waf الأخرى ؛ على سبيل المثال ، هذا
لن يعمل:

$ ./build.py - تعطيل بيثون

سوف يؤدي إلى

build.py: خطأ: لا يوجد خيار من هذا القبيل: --disable-python

ومع ذلك ، فإن المشغل الخاص -- يمكن استخدامها لتمرير خيارات إضافية إلى waf ، لذلك
بدلاً من ما سبق ، سيعمل ما يلي:

$ ./build.py - - تعطيل بيثون

لأنه يولد الأمر الأساسي ./waff تكوين --تعطيل الثعبان.

فيما يلي بعض النصائح التمهيدية حول Waf.

ضبط مقابل البناء
بعض أوامر Waf لها معنى فقط أثناء مرحلة التكوين وبعض الأوامر تكون كذلك
صالحة في مرحلة البناء. على سبيل المثال ، إذا أردت استخدام ميزات المحاكاة الخاصة بـ
NS-3، قد ترغب في تمكين إعداد suid bit باستخدام sudo كما هو موضح أعلاه. هذا
تبين أنه أمر خاص بوقت التكوين ، ولذا يمكنك إعادة التكوين باستخدام
الأمر التالي الذي يتضمن أيضًا الأمثلة والاختبارات.

$ ./waf تكوين --enable-sudo - أمثلة قابلة للتمكين - اختبارات تمكين

إذا قمت بذلك ، فسيكون Waf قد شغّل sudo لتغيير برامج إنشاء المقبس الخاصة بـ
رمز مضاهاة لتشغيل كجذر.

هناك العديد من خيارات التكوين ووقت البناء الأخرى المتاحة في Waf. لاستكشاف هذه
الخيارات ، اكتب:

$ ./waf - help

سنستخدم بعض الأوامر المتعلقة بالاختبار في القسم التالي.

البناء ملامح
لقد رأينا بالفعل كيف يمكنك تكوين Waf لـ تصحيح or الأمثل يبني:

$ ./waf --build-profile = debug

يوجد أيضًا ملف تعريف بناء وسيط ، الافراج عن. -d هو مرادف ل
--بناء الملف الشخصي.

بشكل افتراضي ، يضع Waf عناصر البناء في ملف نساعدك في بناء الدليل. يمكنك تحديد ملف
دليل الإخراج المختلفة مع --خارج الخيار ، على سبيل المثال

$ ./waf تكوين --out = foo

يتيح لك دمج هذا مع ملفات تعريف الإنشاء التبديل بين خيارات الترجمة المختلفة
بطريقة نظيفة:

$ ./waf تكوين --build-profile = debug --out = build / debug
$ ./waf بناء

$ ./waf تكوين --build-profile = محسن - out = بناء / محسن
$ ./waf بناء


يتيح لك هذا العمل مع إصدارات متعددة بدلاً من الكتابة فوق الأخيرة دائمًا
يبني. عند التبديل ، سيقوم Waf فقط بتجميع ما يجب عليه ، بدلاً من إعادة تجميعه
كل شىء.

عندما تقوم بتبديل ملفات تعريف البناء مثل هذا ، عليك أن تكون حريصًا لإعطاء نفس الشيء
معلمات التكوين في كل مرة. قد يكون من المناسب تحديد بعض البيئة
متغيرات لمساعدتك على تجنب الأخطاء:

تصدير $ NS3CONFIG = "- أمثلة التمكين - اختبارات التمكين"
$ export NS3DEBUG = "- إنشاء ملف تعريف = تصحيح - خارج = بناء / تصحيح"
$ تصدير NS3OPT == "- ملف تعريف البناء = محسن - خارج = بناء / محسن"

$ ./waf قم بتكوين $ NS3CONFIG $ NS3DEBUG
$ ./waf بناء

$ ./waf قم بتهيئة $ NS3CONFIG $ NS3OPT
$ ./waf بناء

المجمعين
في الأمثلة أعلاه ، يستخدم Waf مترجم GCC C ++ ، ز ++، للبناء NS-3. ومع ذلك،
من الممكن تغيير مترجم C ++ الذي يستخدمه Waf من خلال تحديد CXX بيئة
عامل. على سبيل المثال ، لاستخدام مترجم Clang C ++ ، رنة ++,

$ CXX = تكوين "clang ++" ./waf
$ ./waf بناء

يمكن للمرء أيضًا إعداد Waf للقيام بالتجميع الموزع باستخدام com.distcc بطريقة مماثلة:

$ CXX = "تهيئة distcc g ++" ./waf
$ ./waf بناء

مزيد من المعلومات عن com.distcc ويمكن العثور على التجميع الموزع عليه تنفيذ المشاريع صفحة مع
قسم التوثيق.

تثبيت
يمكن استخدام Waf لتثبيت مكتبات في أماكن مختلفة على النظام. الافتراضي
الموقع الذي يتم فيه إنشاء المكتبات والملفات التنفيذية موجود في نساعدك في بناء الدليل ، ولأن
Waf يعرف موقع هذه المكتبات والملفات التنفيذية ، وليس من الضروري التثبيت
المكتبات في أماكن أخرى.

إذا اختار المستخدمون تثبيت أشياء خارج دليل الإنشاء ، فقد يصدر المستخدمون ملف
./waff تثبيت يأمر. بشكل افتراضي ، بادئة التثبيت هي / البيرة / المحلية، وبالتالي ./waff
تثبيت سيتم تثبيت البرامج في / البيرة / المحلية / بن، والمكتبات / البيرة / المحلية / ليبو
رؤوس إلى / usr / local / include. عادةً ما تكون امتيازات المستخدم المتميز مطلوبة للتثبيت إلى
البادئة الافتراضية ، لذلك سيكون الأمر النموذجي سودو ./waff تثبيت. عند الجري
برامج Waf ، سيفضل Waf أولاً استخدام المكتبات المشتركة في دليل الإنشاء ،
ثم سيبحث عن المكتبات في مسار المكتبة الذي تم تكوينه في البيئة المحلية. لذا
عند تثبيت مكتبات على النظام ، فمن الممارسات الجيدة التحقق من أن المقصود
المكتبات قيد الاستخدام.

يمكن للمستخدمين اختيار التثبيت إلى بادئة مختلفة عن طريق تمرير --اختصار الخيار في
ضبط الوقت ، مثل:

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

إذا قام المستخدم لاحقًا بعد الإنشاء بإصدار ملف ./waff تثبيت الأمر ، البادئة / اختيار / محلي
وسوف تستخدم.

إنّ ./waff نظيف يجب استخدام الأمر قبل إعادة تكوين المشروع إذا كان Waf سيكون
تستخدم لتثبيت الأشياء ببادئة مختلفة.

باختصار ، ليس من الضروري الاتصال ./waff تثبيت لاستخدام NS-3. معظم المستخدمين لن يفعلوا ذلك
بحاجة إلى هذا الأمر لأن Waf سوف يلتقط المكتبات الحالية من ملف نساعدك في بناء الدليل،
ولكن قد يجد بعض المستخدمين أنه مفيد إذا كانت حالة استخدامهم تتضمن العمل مع برامج خارجية
ل NS-3 الدليل.

واحد WAF
يوجد نص Waf واحد فقط ، في المستوى الأعلى من NS-3 شجرة المصدر. وأنت تعمل أنت
قد تجد نفسك تقضي الكثير من الوقت في يخدش/، أو في العمق src / ...، وتحتاج إلى
استدعاء Waf. يمكنك فقط أن تتذكر مكانك ، وتستدعي Waf مثل هذا:

$ ../../../واف ...

ولكن هذا الأمر ممل وعرضة للخطأ ، وهناك حلول أفضل.

إذا كان لديك كامل NS-3 مستودع هذه الجوهرة الصغيرة هي البداية:

$ cd $ (جذر hg) && ./waf ...

والأفضل من ذلك هو تعريف هذا على أنه دالة صدفة:

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

بناء الواف دولار

إذا كان لديك فقط كرة القطران ، فيمكن لمتغير البيئة أن يساعدك:

تصدير $ NS3DIR = "$ PWD"
$ function waff {cd $ NS3DIR && ./waf $ *؛ }

خدش $ cd
بناء الواف دولار

قد يكون من المغري في دليل الوحدة إضافة ملف تافه WAF النصي على غرار
EXEC ../../وف. من فضلك لا. إنه أمر محير للقادمين الجدد ، وعندما يتم بشكل سيء
يؤدي إلى أخطاء بناء خفية. الحلول المذكورة أعلاه هي السبيل للذهاب.

الاختبار NS-3
يمكنك إجراء اختبارات الوحدة الخاصة بـ NS-3 التوزيع عن طريق تشغيل ./test.py -c النواة
النصي:

$ ./test.py -c الأساسية

يتم إجراء هذه الاختبارات بالتوازي مع Waf. يجب أن ترى في النهاية تقريرًا يقول ذلك

تم اجتياز 92 اختبارًا من 92 اختبارًا (نجح 92 اختبارًا ، فشل 0 ، 0 تعطل ، 0 أخطاء فالغريند)

هذه هي الرسالة المهمة.

سترى أيضًا ملخص الإخراج من Waf وعداء الاختبار الذي ينفذ كل اختبار ،
الذي سيبدو في الواقع مثل:

Waf: إدخال الدليل "/ path / to / workspace / ns-3-allinone / ns-3-dev / build"
Waf: ترك الدليل "/ path / to / workspace / ns-3-allinone / ns-3-dev / build"
انتهى "البناء" بنجاح (1.799 ثانية)

الوحدات المبنية:
جسر تطبيقات aodv
انقر فوق config-store core
csma csma تخطيط dsdv
مراقبة تدفق الطاقة في الاتحاد الاقتصادي والنقدي
شبكة الإنترنت lte
التنقل MPI netanim
شبكة nix-vector-routing ns3tcp
ns3wifi olsr التدفق المفتوح
انتشار التخطيط من نقطة إلى نقطة من نقطة إلى نقطة
احصائيات الطيف جسر الصنبور
أدوات اختبار القالب
طوبولوجيا-قراءة uan virtual-net-device
واي فاي متخيل wimax

اجتياز: TestSuite ns3-wifi-تدخل
PASS: TestSuite المدرج التكراري



PASS: كائن TestSuite
PASS: TestSuite مولدات الأرقام العشوائية
تم اجتياز 92 اختبارًا من 92 اختبارًا (نجح 92 اختبارًا ، فشل 0 ، 0 تعطل ، 0 أخطاء فالغريند)

يتم تشغيل هذا الأمر عادةً بواسطة المستخدمين للتحقق بسرعة من أن ملف NS-3 التوزيع له
بنيت بشكل صحيح. (لاحظ ترتيب ملف يمر: يمكن أن تختلف الخطوط ، وهذا أمر جيد. ما هى
المهم هو أن يكون سطر الملخص في النهاية يشير إلى اجتياز جميع الاختبارات ؛ لا شيء فشل أو
تحطم.)

الركض a سيناريو
عادة ما نقوم بتشغيل البرامج النصية تحت سيطرة Waf. هذا يسمح لنظام البناء بالتأكد
أن مسارات المكتبة المشتركة تم تعيينها بشكل صحيح وأن المكتبات متاحة في
مدة العرض. لتشغيل برنامج ، ما عليك سوى استخدام ملف --يركض الخيار في Waf. دعونا تشغيل NS-3
مكافئ لبرنامج hello world في كل مكان عن طريق كتابة ما يلي:

$ ./waf - تشغيل hello-simulator

يتحقق Waf أولاً للتأكد من أن البرنامج مبني بشكل صحيح وينفذ بناء إذا
مطلوب. ثم يقوم Waf بتنفيذ البرنامج الذي ينتج المخرجات التالية.

مرحبا محاكي

تهانينا! أنت الآن مستخدم ns-3!

ابحث عن do I do if I لا انظر تعريف هيه انتاج؟

إذا رأيت رسائل Waf تشير إلى أن البناء قد اكتمل بنجاح ، لكن لا تفعل ذلك
راجع إخراج "Hello Simulator" ، فمن المحتمل أنك قمت بتبديل وضع الإنشاء إلى
الأمثل في ال ابني مع WAF قسم ، ولكن فاتهم التغيير مرة أخرى إلى تصحيح واسطة.
تستخدم كافة مخرجات وحدة التحكم المستخدمة في هذا البرنامج التعليمي ملف NS-3 عنصر تسجيل ذلك
مفيد لطباعة رسائل المستخدم إلى وحدة التحكم. الناتج من هذا المكون هو
يتم تعطيله تلقائيًا عندما تقوم بترجمة التعليمات البرمجية المحسّنة - يتم "تحسينها". اذا أنت
لا ترى إخراج "Hello Simulator" ، اكتب ما يلي:

$ ./waf config --build-profile = debug --enable -amples --enable-tests

لإخبار Waf ببناء إصدارات تصحيح الأخطاء من NS-3 البرامج التي تتضمن الأمثلة
والاختبارات. لا يزال يتعين عليك إنشاء إصدار التصحيح الفعلي للرمز عن طريق الكتابة

$ ./واف

الآن ، إذا قمت بتشغيل مرحبا محاكي البرنامج ، يجب أن تشاهد الإخراج المتوقع.

البرنامج الحجج
لتغذية وسيطات سطر الأوامر إلى ملف NS-3 يستخدم البرنامج هذا النمط:

$ ./waf - تشغيل - قالب الأوامر = "٪ s "

استبدل اسم البرنامج الخاص بك بـ ، وحجج .
--نموذج الأمر الحجة إلى Waf هي في الأساس وصفة لبناء الواقع
يجب أن يستخدم Waf سطر الأوامر لتنفيذ البرنامج. يتحقق Waf من أن البناء هو
مكتمل ، يعيّن مسارات المكتبة المشتركة ، ثم يستدعي الملف القابل للتنفيذ باستخدام
سطر الأوامر ، وإدراج اسم البرنامج لملف %s نائب. (أعترف بهذا
محرجًا بعض الشيء ، لكن هذا هو الحال. نرحب بالبقع!)

مثال آخر مفيد بشكل خاص هو تشغيل مجموعة اختبار بمفردها. لنفترض أن ملف
اختباري مجموعة الاختبار موجودة (لا توجد). أعلاه ، استخدمنا ./test.py البرنامج النصي لتشغيل كامل
عدد كبير من الاختبارات بالتوازي ، من خلال استدعاء برنامج الاختبار الحقيقي مرارًا وتكرارًا ، عداء اختبار.
استدعاء عداء اختبار مباشرة لاختبار واحد:

$ ./waf - تشغيل الاختبار - قالب الأوامر = "٪ s --suite = mytest --verbose"

هذا ينقل الحجج إلى عداء اختبار برنامج. منذ اختباري غير موجود ، و
سيتم إنشاء رسالة خطأ. لطباعة ملف عداء اختبار الخيارات:

$ ./waf - تشغيل الاختبار - قالب الأوامر = "٪ s --help"

التصحيح
يهرب NS-3 البرامج الخاضعة لسيطرة أداة مساعدة أخرى ، مثل مصحح الأخطاء (على سبيل المثال جدب)
أو مدقق الذاكرة (على سبيل المثال فالغريند) ، يمكنك استخدام ملف - أمر-قالب = "..." .

على سبيل المثال ، لتشغيل ملف NS-3 برنامج مرحبا محاكي مع الحجج تحت
جدب المصحح:

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

لاحظ أن NS-3 اسم البرنامج يتماشى مع --يركض الحجة ، وأداة التحكم
(هنا جدب) هو الرمز المميز الأول في ملف - كومماند قالب جدال. ال --args يروي جدب
أن ما تبقى من سطر الأوامر ينتمي إلى برنامج "أدنى". (بعض جدب's
لا تفهم ال --args ميزة. في هذه الحالة ، احذف وسائط البرنامج من ملف
--نموذج الأمر، واستخدام جدب أمر طقم وسائط.)

يمكننا الجمع بين هذه الوصفة والوصفة السابقة لإجراء اختبار تحت مصحح الأخطاء:

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

العمل الدليل
يحتاج Waf إلى الركض من موقعه في الجزء العلوي من NS-3 شجرة. هذا يصبح العمل
الدليل حيث سيتم كتابة ملفات الإخراج. ولكن ماذا لو كنت تريد الاحتفاظ بهذه الأشياء
هيه NS-3 شجرة المصدر؟ استخدم ال --cwd حجة:

$ ./waf --cwd = ...

قد يكون من الأنسب أن تبدأ بدليل العمل الخاص بك حيث تريد الإخراج
الملفات ، وفي هذه الحالة يمكن أن يساعد القليل من المراوغة:

وظيفة $ واف {
CWD = "الأشخاص بالدولار الأمريكي"
cd $ NS3DIR> / dev / null
./waf --cwd = "$ CWD" $ *
القرص المضغوط -> / dev / null
}

يحفظ زخرفة الإصدار السابق هذا دليل العمل الحالي ، cdل
دليل Waf ، ثم يوجه Waf لتغيير دليل العمل الى الخلف إلى المحفوظين
دليل العمل الحالي قبل تشغيل البرنامج.

المفاهيمي نبذة عامة


أول شيء يتعين علينا القيام به قبل البدء فعليًا في النظر أو الكتابة NS-3 الكود هو
شرح بعض المفاهيم الأساسية والتجريدية في النظام. قد يظهر الكثير من هذا
واضح للبعض بشفافية ، لكننا نوصي بأخذ الوقت الكافي لقراءة هذا
قسم فقط للتأكد من أنك تبدأ على أساس متين.

القفل تجريدات
في هذا القسم ، سنراجع بعض المصطلحات المستخدمة بشكل شائع في الشبكات ، ولكن لها امتداد
معنى محدد في NS-3.

العقدة
في لغة الإنترنت ، يُطلق على جهاز الحوسبة الذي يتصل بشبكة اسم مضيف or
في بعض الأحيان النهاية نظام. لان NS-3 هو شبكة محاكاة ، وليس على وجه التحديد ملف
الإنترنت محاكاة ، نحن لا نستخدم مصطلح المضيف عمدًا لأنه قريب
المرتبطة بالإنترنت وبروتوكولاتها. بدلاً من ذلك ، نستخدم مصطلحًا أكثر عمومية أيضًا
المستخدمة من قبل المحاكيات الأخرى التي نشأت في نظرية الرسم البياني --- العقدة.

In NS-3 يسمى تجريد جهاز الحوسبة الأساسي بالعقدة. هذا التجريد
ممثلة في C ++ بالفئة العقدة. العقدة توفر فئة طرق لإدارة
تمثيلات الأجهزة الحاسوبية في المحاكاة.

يجب أن تفكر في أ العقدة كجهاز كمبيوتر ستضيف إليه وظائف. يضيف واحد
أشياء مثل التطبيقات وحزم البروتوكولات والبطاقات الطرفية المرتبطة بها
برامج تشغيل لتمكين الكمبيوتر من القيام بعمل مفيد. نستخدم نفس النموذج الأساسي في NS-3.

التطبيق
عادةً ما يتم تقسيم برامج الكمبيوتر إلى فئتين عريضتين. تطبيقات الكمبيوتر تنظم
موارد الكمبيوتر المختلفة مثل الذاكرة ودورات المعالج والقرص والشبكة وما إلى ذلك ،
وفقًا لبعض النماذج الحاسوبية. برامج النظام عادة لا تستخدم هذه الموارد
لإكمال المهام التي تفيد المستخدم بشكل مباشر. عادةً ما يقوم المستخدم بتشغيل ملف استمارتنا
يكتسب ويستخدم الموارد التي يتحكم فيها برنامج النظام لإنجاز بعض
هدف.

في كثير من الأحيان ، يتم إنشاء خط الفصل بين النظام وبرامج التطبيق في
تغيير مستوى الامتياز الذي يحدث في اعتراضات نظام التشغيل. في NS-3 لا يوجد حقيقي
مفهوم نظام التشغيل ولا سيما مفهوم مستويات الامتياز أو استدعاءات النظام.
ومع ذلك ، لدينا فكرة التطبيق. تمامًا كما تعمل تطبيقات البرامج
أجهزة كمبيوتر لأداء المهام في "العالم الحقيقي" ، NS-3 تشغيل التطبيقات NS-3 العقد إلى
محرك المحاكاة في عالم المحاكاة.

In NS-3 التجريد الأساسي لبرنامج المستخدم الذي يولد بعض النشاط
مقلد هو التطبيق. يتم تمثيل هذا التجريد في C ++ بواسطة الفصل
التطبيق. التطبيق يوفر class طرقًا لإدارة تمثيلات
نسختنا من التطبيقات على مستوى المستخدم في عمليات المحاكاة. يتوقع من المطورين أن
تتخصص في التطبيق فئة في معنى البرمجة الشيئية لخلق جديد
التطبيقات. في هذا البرنامج التعليمي ، سوف نستخدم تخصصات الفصل التطبيق تسمى
UdpEchoClientApplication UdpEchoServerApplication. كما قد تتوقع ، هذه
تقوم التطبيقات بتكوين مجموعة تطبيقات عميل / خادم تُستخدم لإنشاء ومحاكاة صدى
حزم الشبكة

قناة
في العالم الحقيقي ، يمكن توصيل جهاز كمبيوتر بشبكة. في كثير من الأحيان على وسائل الإعلام
تدفقات البيانات في هذه الشبكات تسمى قنوات. عند توصيل كابل Ethernet الخاص بك بـ
القابس في الحائط ، فأنت تقوم بتوصيل جهاز الكمبيوتر الخاص بك باتصال Ethernet
قناة. في عالم المحاكاة NS-3، واحد يربط أ العقدة لكائن يمثل أ
قناة الاتصال. هنا يسمى التجريد الأساسي للشبكة الفرعية للاتصال بـ
قناة ويمثلها الفصل في C ++ قناة.

إنّ قناة يوفر class طرقًا لإدارة كائنات الشبكة الفرعية للاتصالات و
ربط العقد بهم. القنوات قد يكون متخصصًا أيضًا من قبل المطورين في الكائن
بمعنى البرمجة الموجهة. أ قناة قد يصمم التخصص شيئًا بسيطًا مثل a
الأسلاك. المتخصصين قناة يمكن أيضًا تصميم أشياء معقدة مثل شبكة إيثرنت كبيرة
التبديل ، أو الفضاء ثلاثي الأبعاد المليء بالعوائق في حالة الشبكات اللاسلكية.

سوف نستخدم إصدارات متخصصة من قناة تسمى قناة CsmaChannel, PointToPointChannel
قناة واي فاي في هذا البرنامج التعليمي. ال قناة CsmaChannel، على سبيل المثال ، نماذج لنسخة من
شبكة الاتصالات الفرعية التي تنفذ أ الناقل إحساس متعدد الوصول الاتصالات
واسطة. هذا يعطينا وظائف تشبه إيثرنت.

شبكة الجهاز
كان الأمر في السابق هو أنك إذا أردت توصيل أجهزة كمبيوتر بشبكة ، فعليك القيام بذلك
شراء نوع معين من كبلات الشبكة وجهاز يسمى (بمصطلحات الكمبيوتر الشخصي) أ
محيطي فيزا وماستركارد التي يجب تثبيتها في جهاز الكمبيوتر الخاص بك. إذا كانت البطاقة الطرفية
نفذت بعض وظائف الشبكات ، فقد أطلقوا عليها اسم بطاقات واجهة الشبكة ، أو بطاقات NIC.
تأتي معظم أجهزة الكمبيوتر اليوم مزودة بأجهزة واجهة الشبكة المضمنة ولا يرى المستخدمون
هذه اللبنات الأساسية.

لن تعمل بطاقة واجهة الشبكة (NIC) بدون برنامج تشغيل للتحكم في الأجهزة. في Unix (أو
Linux) ، تم تصنيف قطعة من الأجهزة الطرفية على أنها ملف جهاز. يتم التحكم في الأجهزة
استخدام جهاز السائقين، ويتم التحكم في أجهزة الشبكة (NIC) باستخدام شبكة جهاز
السائقين تعرف بشكل جماعي باسم صاف الأجهزة. في Unix و Linux ، تشير إلى هذه الشبكات
الأجهزة بأسماء مثل eth0.

In NS-3 هيه صاف جهاز يغطي التجريد كلاً من برنامج تشغيل البرنامج والمحاكاة
المعدات. يتم "تثبيت" جهاز الشبكة في ملف العقدة من أجل تمكين العقدة إلى
التواصل مع الآخرين العقد في المحاكاة عبر القنوات. تمامًا كما هو الحال في الكمبيوتر الحقيقي ،
a العقدة قد يكون متصلاً بأكثر من واحد قناة عبر عدة NetDevices.

يتم تمثيل صافي تجريد الجهاز في C ++ بالفئة NetDevice. NetDevice
يوفر class طرقًا لإدارة الاتصالات بـ العقدة قناة أشياء؛ و ربما
متخصص من قبل المطورين بمعنى البرمجة الشيئية. سوف نستخدم ملف
العديد من الإصدارات المتخصصة من NetDevice تسمى جهاز CsmaNet, PointToPointNetDevice,
جهاز WifiNet في هذا البرنامج التعليمي. تمامًا كما تم تصميم Ethernet NIC للعمل مع ملف
شبكة إيثرنت جهاز CsmaNet تم تصميمه للعمل مع قناة CsmaChannel؛ ال
PointToPointNetDevice تم تصميمه للعمل مع PointToPointChannel و WifiNetNevice
تم تصميمه للعمل مع قناة واي فاي.

طبيعة الكابل المساعدون
في شبكة حقيقية ، ستجد أجهزة كمبيوتر مضيفة بها بطاقات NIC مضافة (أو مدمجة). في NS-3 we
ستقول أنك ستجد العقد مع المرفقة NetDevices. في شبكة محاكاة كبيرة
سوف تحتاج إلى ترتيب العديد من الاتصالات بين العقد, NetDevices القنوات.

منذ الاتصال NetDevices إلى العقد, NetDevices إلى القنوات، تعيين عناوين IP ،
وما إلى ذلك ، هي مثل هذه المهام الشائعة في NS-3، نحن نقدم ما نسميه طوبولوجيا المساعدين لعمل هذا
سهل قدر الإمكان. على سبيل المثال ، قد يستغرق الأمر العديد من العناصر المميزة NS-3 العمليات الأساسية ل
قم بإنشاء NetDevice ، وإضافة عنوان MAC ، وتثبيت جهاز الشبكة هذا على ملف العقدة، قم بتكوين
مكدس بروتوكول العقدة ، ثم قم بتوصيل NetDevice ل قناة. المزيد من العمليات
قد يكون مطلوبًا لتوصيل أجهزة متعددة بقنوات متعددة النقاط ثم الاتصال
الشبكات الفردية معًا في أعمال الإنترنت. نحن نقدم كائنات مساعد طوبولوجيا
اجمع بين هذه العمليات المميزة العديدة في نموذج سهل الاستخدام لراحتك.

A الأول NS-3 سيناريو
إذا قمت بتنزيل النظام كما تم اقتراحه أعلاه ، فسيكون لديك إصدار NS-3 في
دعا الدليل اتفاقيات إعادة الشراء تحت دليل منزلك. قم بالتغيير إلى دليل الإصدار هذا ، و
يجب أن تجد بنية دليل مثل ما يلي:

أمثلة المؤلفين لأدوات الخدش waf.bat *
الروابط LICENSE src تستخدم. أدوات waf
بناء 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: "gnu" ؛ وضع علامات الجدولة البادئة: لا شيء ؛ - * - * /

هذا دائمًا موضوع مثير للجدل إلى حد ما ، لذلك قد نخرجه من الطريق
فورا. ال NS-3 مشروع ، مثل معظم المشاريع الكبيرة ، اعتمد أسلوب الترميز ل
التي يجب أن تلتزم بها جميع التعليمات البرمجية المساهمة. إذا كنت ترغب في المساهمة في التعليمات البرمجية الخاصة بك في
المشروع ، سيتعين عليك في النهاية التوافق مع NS-3 معيار الترميز كما هو موضح في
الملف doc / codingstd.txt أو المعروضة على صفحة ويب المشروع هنا.

نوصيك ، حسنًا ، أن تعتاد على الشكل والمظهر NS-3 رمز واعتماد
هذا المعيار كلما كنت تعمل مع الكود الخاص بنا. كل فريق التطوير و
لقد فعل المساهمون ذلك بكميات مختلفة من التذمر. سطر وضع emacs أعلاه
يسهل الحصول على التنسيق الصحيح إذا كنت تستخدم محرر emacs.

إنّ NS-3 simulator مرخص باستخدام رخصة جنو العمومية العامة. سترى ملف
قانون جنو المناسب في رأس كل ملف في NS-3 توزيع. في كثير من الأحيان
سوف ترى إشعار حقوق التأليف والنشر لإحدى المؤسسات المشاركة في NS-3 المشروع أعلاه
نص GPL والمؤلف المذكور أدناه.

/*
* هذا البرنامج مجاني ؛ يمكنك إعادة توزيعه و / أو تعديله
* بموجب شروط رخصة جنو العمومية الإصدار 2 كـ
* نشرته مؤسسة البرمجيات الحرة ؛
*
* يتم توزيع هذا البرنامج على أمل أن يكون مفيدا ،
* ولكن بدون أي ضمان ؛ حتى بدون الضمان الضمني لـ
* القابلية للتسويق أو الملاءمة لغرض معين. انظر
* رخصة جنو العمومية لمزيد من التفاصيل.
*
* يجب أن تكون قد تلقيت نسخة من رخصة جنو العمومية العامة
* مع هذا البرنامج ؛ إذا لم يكن كذلك ، فاكتب إلى البرمجيات الحرة
* Foundation، Inc.، 59 Temple Place، Suite 330، Boston، MA 02111-1307 USA
*/

وحدة ويشمل
يبدأ الكود الصحيح بعدد من عبارات التضمين.

# تضمين "ns3 / core-module.h"
# تضمين "ns3 / network-module.h"
# تضمين "ns3 / internet-module.h"
# تضمين "ns3 / point-to-point-module.h"
#include "ns3 / applications-module.h"

لمساعدة مستخدمي البرامج النصية عالية المستوى لدينا على التعامل مع العدد الكبير من ملفات التضمين الموجودة في
النظام الذي قمنا بتجميعه يشتمل على وحدات كبيرة نسبيًا. نحن نقدم ملف
قم بتضمين الملف الذي سيحمل بشكل متكرر جميع ملفات التضمين المستخدمة في كل وحدة.
بدلاً من الاضطرار إلى البحث عن العنوان الذي تحتاجه بالضبط ، وربما يتعين عليك الحصول على ملف
عدد التبعيات بشكل صحيح ، نمنحك القدرة على تحميل مجموعة من الملفات بشكل كبير
تقسيمات. ليس هذا هو النهج الأكثر كفاءة ولكنه بالتأكيد يجعل الكتابة
البرامج النصية أسهل بكثير.

كل واحد من NS-3 تضمين الملفات في دليل يسمى ns3 (تحت الإنشاء
الدليل) أثناء عملية الإنشاء للمساعدة في تجنب تضمين تضاربات اسم الملف. ال
ns3 / core-module.h يتوافق الملف مع الوحدة النمطية ns-3 التي ستجدها في الدليل
src / الأساسية في توزيع الإصدار الذي تم تنزيله. إذا قمت بإدراج هذا الدليل سوف تفعل
العثور على عدد كبير من ملفات الرأس. عندما تقوم ببناء ، سيضع Waf العنوان العام
الملفات في ملف ns3 دليل تحت المناسب بناء / تصحيح or بناء / الأمثل دليل
حسب التكوين الخاص بك. سوف Waf أيضا تلقائيا إنشاء وحدة تشمل
ملف لتحميل كافة ملفات الترويسة العامة.

نظرًا لأنك ، بالطبع ، تتبع هذا البرنامج التعليمي دينيًا ، فستكون قد فعلت ذلك بالفعل
a

$ ./waf -d debug - أمثلة قابلة للتمكين - تكوين اختبارات التمكين

من أجل تكوين المشروع لأداء تصميمات تصحيح الأخطاء التي تتضمن أمثلة واختبارات.
ستكون قد قمت أيضًا بعمل ملف

$ ./واف

لبناء المشروع. حتى الآن إذا نظرت في الدليل ../../build/debug/ns3 سوف
ابحث عن أربع وحدات تتضمن الملفات الموضحة أعلاه. يمكنك إلقاء نظرة على محتويات
هذه الملفات ووجدوا أنها تتضمن جميع الجمهور تضمين الملفات في الخاصة بهم
الوحدات المعنية.

Ns3 مساحة الاسم
السطر التالي في first.cc البرنامج النصي هو إعلان مساحة الاسم.

باستخدام مساحة الاسم ns3 ؛

إنّ NS-3 تم تنفيذ المشروع في مساحة اسم C ++ تسمى ns3. هذه المجموعات كلها
NS-3- الإعلانات ذات الصلة في نطاق خارج نطاق الاسم العالمي ، والتي نأمل أن تساعد
مع التكامل مع التعليمات البرمجية الأخرى. C ++ استخدام يقدم البيان NS-3 مساحة الاسم
في المنطقة التصريحية الحالية (العالمية). هذه طريقة رائعة لقول ذلك بعد ذلك
هذا الإعلان، لن تضطر إلى الكتابة ns3:: عامل دقة النطاق قبل كل شيء
هيه NS-3 الكود من أجل استخدامه. إذا لم تكن على دراية بمساحات الأسماء، فيرجى استشارة
تقريبًا أي برنامج تعليمي لـ C++ ومقارنة ns3 مساحة الاسم والاستخدام هنا مع مثيلات
الأمراض المنقولة جنسيا مساحة الاسم و استخدام مساحة الاسم الأمراض المنقولة جنسيا. البيانات التي غالبا ما تجدها في المناقشات
of cout والجداول.

تسجيل
السطر التالي من البرنامج النصي هو ما يلي،

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 الخاصة بوحدة التسجيل. في ال
قائمة # تعريففي أعلى الصفحة سترى الإدخال الخاص بـ
NS_LOG_COMPONENT_DEFINE. قبل القفز، ربما يكون من الجيد البحث عن
"الوصف التفصيلي" لوحدة التسجيل للتعرف على العملية الشاملة. أنت
يمكنك إما التمرير لأسفل أو تحديد الرابط "المزيد..." ضمن مخطط التعاون للقيام به
هذا.

بمجرد أن تكون لديك فكرة عامة عما يحدث، قم بإلقاء نظرة على ما هو محدد
NS_LOG_COMPONENT_DEFINE توثيق. لن أقوم بتكرار الوثائق هنا، ولكن
تلخيص، هذا السطر يعلن عن مكون تسجيل يسمى مثال FirstScript ذلك يسمح
يمكنك تمكين وتعطيل تسجيل رسائل وحدة التحكم بالرجوع إلى الاسم.

الرئيسية الوظيفة
الأسطر التالية من البرنامج النصي ستجدها هي،

مادبا
main (int argc، char * argv [])
{

هذا مجرد إعلان عن الوظيفة الرئيسية لبرنامجك (البرنامج النصي). تماما كما في
أي برنامج C++، تحتاج إلى تحديد وظيفة رئيسية ستكون أول وظيفة يتم تشغيلها.
لا يوجد شيء خاص على الإطلاق هنا. لك NS-3 البرنامج النصي هو مجرد برنامج C ++.

يقوم السطر التالي بتعيين دقة الوقت إلى نانوثانية واحدة، وهو ما يحدث ليكون الإعداد الافتراضي
القيمة:

الوقت::SetResolution (الوقت::NS)؛

الدقة هي أصغر قيمة زمنية يمكن تمثيلها (وكذلك أصغر قيمة زمنية
فرق يمكن تمثيله بين قيمتين زمنيتين). يمكنك تغيير القرار بالضبط
مرة واحدة. الآلية التي تتيح هذه المرونة هي إلى حد ما متعطشة للذاكرة، لذا بمجرد
تم ضبط الدقة بشكل صريح، حيث نقوم بتحرير الذاكرة، مما يمنع إجراء المزيد من التحديثات.
(إذا لم تقم بتعيين الدقة بشكل صريح، فسيتم ضبطها بشكل افتراضي على نانو ثانية واحدة، و
سيتم تحرير الذاكرة عند بدء المحاكاة.)

يتم استخدام السطرين التاليين من البرنامج النصي لتمكين مكوني التسجيل اللذين تم إنشاؤهما
في تطبيقات Echo Client وEcho Server:

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

إذا كنت قد قرأت وثائق مكون التسجيل، فسوف ترى ذلك هناك
هناك عدد من مستويات تسجيل الإسهاب/التفاصيل التي يمكنك تمكينها في كل مكون.
يعمل هذان السطران من التعليمات البرمجية على تمكين تسجيل التصحيح على مستوى INFO لعملاء الارتداد و
الخوادم. سيؤدي هذا إلى قيام التطبيق بطباعة الرسائل أثناء إرسال الحزم
واستلامها أثناء المحاكاة.

سننتقل الآن مباشرةً إلى عملية إنشاء الهيكل وإجراء المحاكاة.
نحن نستخدم الكائنات المساعدة للطوبولوجيا لجعل هذه المهمة سهلة قدر الإمكان.

طبيعة الكابل المساعدون
NodeContainer
السطرين التاليين من التعليمات البرمجية في البرنامج النصي الخاص بنا سوف يقومان بالفعل بإنشاء ملف NS-3 العقدة الأشياء التي
سوف تمثل أجهزة الكمبيوتر في المحاكاة.

عقد NodeContainer
العقد.إنشاء (2);

دعنا نجد الوثائق الخاصة بـ NodeContainer الفصل قبل أن نواصل. طريق اخر
للدخول إلى الوثائق الخاصة بفصل معين عبر فصول دراسية علامة التبويب في Doxygen
الصفحات. إذا كان لا يزال لديك Doxygen في متناول يدك، فما عليك سوى التمرير لأعلى إلى أعلى الصفحة و
حدد فصول دراسية فاتورة غير مدفوعة. من المفترض أن تظهر لك مجموعة جديدة من علامات التبويب، واحدة منها مبوبة
قائمة. ضمن علامة التبويب هذه، سترى قائمة بجميع العناصر NS-3 الطبقات. حرك الفأرة لأسفل،
البحث عن ns3 :: NodeContainer. عندما تجد الفصل الدراسي، قم بالمضي قدمًا وحدده للانتقال إليه
الوثائق الخاصة بالفئة.

ربما تتذكر أن أحد تجريداتنا الأساسية هو العقدة. وهذا يمثل جهاز كمبيوتر
والتي سنضيف إليها أشياء مثل مكدسات البروتوكول والتطبيقات والأجهزة الطرفية
بطاقات. ال NodeContainer يوفر مساعد الطوبولوجيا طريقة ملائمة لإنشاء وإدارة و
الوصول إلى أي العقدة الكائنات التي نقوم بإنشائها من أجل تشغيل المحاكاة. السطر الأول أعلاه
يعلن فقط عن NodeContainer الذي نسميه العقد. السطر الثاني يدعو إنشاء
طريقة على العقد كائن ويطلب من الحاوية إنشاء عقدتين. كما هو موضح في
Doxygen، الحاوية تستدعي أسفل إلى NS-3 النظام المناسب لإنشاء اثنين العقدة
الكائنات ويخزن المؤشرات إلى تلك الكائنات داخليًا.

العقد كما هي في البرنامج النصي لا تفعل شيئًا. الخطوة التالية في بناء أ
الطوبولوجيا هي ربط عقدنا معًا في شبكة. أبسط شكل من أشكال الشبكة نحن
الدعم هو رابط واحد من نقطة إلى نقطة بين عقدتين. سنقوم ببناء واحدة من هؤلاء
الروابط هنا.

PointToPointHelper
نحن نقوم ببناء رابط من نقطة إلى نقطة، وبنمط سيصبح تمامًا
مألوف بالنسبة لك، نحن نستخدم كائنًا مساعدًا للطوبولوجيا للقيام بالأعمال ذات المستوى المنخفض المطلوبة لوضعها
الرابط معا. تذكر أن اثنين من التجريدات الرئيسية لدينا هما NetDevice و
قناة. في العالم الحقيقي، تتوافق هذه المصطلحات تقريبًا مع البطاقات الطرفية و
كابلات الشبكة. عادةً ما يكون هذين الأمرين مرتبطين ببعضهما البعض بشكل وثيق ولا يمكن لأحدهما ذلك
نتوقع التبادل، على سبيل المثال، أجهزة Ethernet والقنوات اللاسلكية. طوبولوجيا لدينا
يتبع المساعدون هذا الاقتران الحميم وبالتالي ستستخدم واحدًا
PointToPointHelper للتكوين والاتصال NS-3 PointToPointNetDevice
PointToPointChannel الكائنات في هذا البرنامج النصي.

الأسطر الثلاثة التالية في البرنامج النصي هي،

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5 ميجا بت في الثانية"))؛
pointToPoint.SetChannelAttribute ("Delay"، StringValue ("2ms"))؛

السطر الأول،

PointToPointHelper pointToPoint;

ينشئ مثيل أ PointToPointHelper كائن على المكدس. من منظور رفيع المستوى
السطر التالي،

pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5 ميجا بت في الثانية"))؛

يحكي PointToPointHelper كائن لاستخدام القيمة "5Mbps" (خمسة ميغابت في الثانية) كما
"DataRate" عندما يقوم بإنشاء ملف PointToPointNetDevice موضوع.

من منظور أكثر تفصيلاً، تتوافق السلسلة "DataRate" مع ما نسميه بـ
السمة ل PointToPointNetDevice. إذا نظرت إلى Doxygen للفئة
ns3::PointToPointNetDevice وابحث عن الوثائق الخاصة بـ GetTypeId الطريقة، سوف
العثور على قائمة السمات المحددة للجهاز. من بينها "DataRate"
السمة. الأكثر وضوحا للمستخدم NS-3 الكائنات لديها قوائم مماثلة من السمات. نحن نستخدم هذا
آلية لتكوين عمليات المحاكاة بسهولة دون إعادة الترجمة كما سترون في ملف
القسم التالي.

على غرار "DataRate" على PointToPointNetDevice سوف تجد "تأخير" السمة
المرتبطة PointToPointChannel. السطر الأخير،

pointToPoint.SetChannelAttribute ("Delay"، StringValue ("2ms"))؛

يحكي PointToPointHelper لاستخدام القيمة "2ms" (ملي ثانية) كقيمة
تأخير الإرسال لكل قناة من نقطة إلى نقطة يتم إنشاؤها لاحقًا.

NetDeviceContainer
في هذه المرحلة من البرنامج النصي، لدينا NodeContainer الذي يحتوي على عقدتين. لدينا
PointToPointHelper التي هي معدة وجاهزة للتصنيع PointToPointNetDevices والأسلاك
PointToPointChannel الكائنات بينهما. تماما كما استخدمنا NodeContainer طوبولوجيا
كائن مساعد لإنشاء العقد بالنسبة لمحاكاة لدينا، سوف نطلب من PointToPointHelper
للقيام بالعمل المتضمن في إنشاء أجهزتنا وتكوينها وتثبيتها لنا. نحن
سوف تحتاج إلى قائمة بجميع كائنات NetDevice التي تم إنشاؤها، لذلك نستخدم ملف
NetDeviceContainer للاحتفاظ بها تمامًا كما استخدمنا NodeContainer للاحتفاظ بالعقد التي نستخدمها
مخلوق. السطرين التاليين من التعليمات البرمجية،

أجهزة NetDeviceContainer؛
الأجهزة = pointToPoint.Install (العقد)؛

سينتهي من تكوين الأجهزة والقناة. السطر الأول يعلن عن الجهاز
الحاوية المذكورة أعلاه والثانية تقوم برفع الأحمال الثقيلة. ال تثبيت طريقة
هيه PointToPointHelper يأخذ NodeContainer كمعلمة. داخلياً، أ
NetDeviceContainer أنشئ. لكل عقدة في NodeContainer (يجب أن يكون هناك بالضبط
اثنان للارتباط من نقطة إلى نقطة) أ PointToPointNetDevice يتم إنشاؤها وحفظها في الجهاز
حاوية. أ PointToPointChannel هو خلق واثنين PointToPointNetDevices .
مُرفَق. عندما يتم إنشاء الكائنات بواسطة PointToPointHelperأطلقت حملة السمات سابقا
يتم استخدام مجموعة في المساعد لتهيئة المقابلة السمات في المخلوق
شاء.

بعد تنفيذ pointToPoint.Install (العقد) عند الاتصال سيكون لدينا عقدتان، لكل منهما
تم تثبيت جهاز شبكة من نقطة إلى نقطة وقناة واحدة من نقطة إلى نقطة بينهما.
سيتم تكوين كلا الجهازين لنقل البيانات بسرعة خمسة ميغابت في الثانية عبر
قناة لها تأخير إرسال يبلغ XNUMX ميلي ثانية.

InternetStackHelper
لدينا الآن عقد وأجهزة تم تكوينها، ولكن ليس لدينا أي مجموعات بروتوكولات مثبتة
على العقد لدينا. سوف يعتني السطران التاليان من التعليمات البرمجية بذلك.

مكدس InternetStackHelper؛
مكدس التثبيت (العقد) ؛

إنّ InternetStackHelper هو مساعد طوبولوجي لمكدسات الإنترنت ما
PointToPointHelper هو لأجهزة الشبكة من نقطة إلى نقطة. ال تثبيت تأخذ الطريقة
NodeContainer كمعلمة. عند تنفيذه، سيتم تثبيت Internet Stack
(TCP، UDP، IP، وما إلى ذلك) على كل عقدة في حاوية العقدة.

IPv4AddressHelper
بعد ذلك نحتاج إلى ربط الأجهزة الموجودة على عقدنا بعناوين IP. نحن نقدم أ
مساعد طوبولوجيا لإدارة تخصيص عناوين IP. واجهة برمجة التطبيقات (API) الوحيدة المرئية للمستخدم هي
قم بتعيين عنوان IP الأساسي وقناع الشبكة لاستخدامهما عند تنفيذ العنوان الفعلي
التخصيص (والذي يتم على مستوى أدنى داخل المساعد).

السطرين التاليين من التعليمات البرمجية في مثالنا النصي، first.cc,

عنوان Ipv4AddressHelper؛
عنوان.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 المخصصة وسيقوم بإنشاء ملف
خطأ فادح إذا تسببت بطريق الخطأ في إنشاء نفس العنوان مرتين (وهو ما يعد خطأً فادحًا).
من الصعب جدًا تصحيح الخطأ، بالمناسبة).

السطر التالي من التعليمات البرمجية،

Ipv4InterfaceContainer واجهات = عنوان.تعيين (الأجهزة)؛

ينفذ تعيين العنوان الفعلي. في NS-3 نحن نجعل الارتباط بين IP
العنوان والجهاز باستخدام واجهة IPv4 هدف. تماما كما نحتاج في بعض الأحيان إلى قائمة
net التي تم إنشاؤها بواسطة المساعد للرجوع إليها مستقبلاً نحتاج أحيانًا إلى قائمة
واجهة IPv4 شاء. ال 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 (Seconds (1.0));
serverApps.Stop (ثواني (10.0))؛

يعلن السطر الأول من التعليمات البرمجية في المقتطف أعلاه عن UdpEchoServerHelper. كل عادة،
هذا ليس التطبيق نفسه، بل هو كائن يستخدم لمساعدتنا في إنشاء الفعلي
التطبيقات. أحد اتفاقياتنا هو المكان مطلوب السمات في المساعد
البناء. وفي هذه الحالة، لا يستطيع المساعد أن يفعل أي شيء مفيد إلا إذا تم توفيره له
رقم المنفذ الذي يعرفه العميل أيضًا. بدلاً من مجرد اختيار واحد والأمل
كل شيء يعمل على ما يرام، ونحن نطلب رقم المنفذ كمعلمة للمنشئ. ال
المنشئ، بدوره، ببساطة يفعل SetAttribute مع القيمة التي تم تمريرها. إذا كنت تريد، أنت
يمكن ضبط "المنفذ" السمة إلى قيمة أخرى في وقت لاحق باستخدام SetAttribute.

على غرار العديد من الكائنات المساعدة الأخرى، فإن UdpEchoServerHelper الكائن لديه تثبيت
طريقة. إن تنفيذ هذه الطريقة هو الذي يسبب الصدى الأساسي بالفعل
سيتم إنشاء مثيل لتطبيق الخادم وإرفاقه بالعقدة. ومن المثير للاهتمام أن تثبيت
تأخذ الطريقة NodeContainer كمعلمة تماما مثل غيرها تثبيت الأساليب لدينا
مرئي. هذا هو في الواقع ما تم تمريره إلى الطريقة على الرغم من أنه لا يبدو كذلك
هذه القضية. هناك C++ ضمني تحويل في العمل هنا الذي يأخذ نتيجة
العقد (1) (الذي يُرجع مؤشرًا ذكيًا إلى كائن العقدة --- Ptr) ويستخدم ذلك
في منشئ لم يذكر اسمه NodeContainer ثم يتم تمريره إلى تثبيت. إذا كنت
من أي وقت مضى في حيرة من أمر العثور على توقيع أسلوب معين في كود C++ الذي يتم تجميعه وتشغيله
حسنًا، ابحث عن هذه الأنواع من التحويلات الضمنية.

ونحن الآن نرى ذلك echoServer.Install سيقوم بتثبيت أ UdpEchoServerApplication على
تم العثور على العقدة في الفهرس رقم واحد من NodeContainer اعتدنا على إدارة العقد لدينا. تثبيت
سيُرجع حاوية تحتوي على مؤشرات لجميع التطبيقات (واحدة في هذه الحالة
منذ أن مررنا أ NodeContainer تحتوي على عقدة واحدة) تم إنشاؤها بواسطة المساعد.

تتطلب التطبيقات وقتًا "لبدء" توليد حركة المرور وقد تستغرق وقتًا اختياريًا لذلك
"قف". نحن نقدم كليهما. يتم ضبط هذه الأوقات باستخدام حاوية التطبيق طرق
آبدأ قلة النوم. تأخذ هذه الأساليب الوقت: حدود. في هذه الحالة نستخدم صريح C + +
تسلسل التحويل لأخذ C++ double 1.0 وتحويله إلى NS-3 الوقت: الكائن باستخدام
a ثانية يقذف. انتبه إلى أن قواعد التحويل قد يتحكم فيها مؤلف النموذج،
وC++ لها قواعدها الخاصة، لذلك لا يمكنك دائمًا افتراض أن المعلمات ستكون سعيدة
تحويلها لك. الخطين،

serverApps.Start (Seconds (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 (Seconds (1.0)))؛
echoClient.SetAttribute ("PacketSize"، UintegerValue (1024))؛

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
ClientApps.Start (ثواني (2.0))؛
ClientApps.Stop (Seconds (10.0));

ومع ذلك، بالنسبة لعميل الصدى، نحتاج إلى تعيين خمسة مختلفة السمات. أول إثنين
السمات يتم تعيينها أثناء بناء UdpEchoClientHelper. نحن نمرر المعلمات
التي يتم استخدامها (داخليًا للمساعد) لتعيين "RemoteAddress" و"RemotePort"
السمات وفقا لاتفاقيتنا لجعل المطلوبة السمات المعلمات في
بناة مساعدين.

أذكر أننا استخدمنا IPv4InterfaceContainer لتتبع عناوين IP لدينا
المخصصة لأجهزتنا. الواجهة الصفرية في واجهات الحاوية سوف
تتوافق مع عنوان IP الخاص بالعقدة الصفرية في العقد حاوية. الأول
واجهة في واجهات تتوافق الحاوية مع عنوان IP الخاص بالعقدة الأولى في
هيه العقد حاوية. لذا، في السطر الأول من الكود (من الأعلى)، نقوم بإنشاء ملف
helper وإخباره بذلك قم بتعيين العنوان البعيد للعميل ليكون عنوان IP
المخصصة للعقدة التي يوجد عليها الخادم. ونقول لها أيضًا أن تقوم بالترتيب للإرسال
الحزم إلى المنفذ التاسع.

"الحزم القصوى" السمة يخبر العميل بالحد الأقصى لعدد الحزم التي نسمح له بها
إرسال أثناء المحاكاة. الفاصل" السمة يخبر العميل كم من الوقت يجب أن ينتظر
بين الحزم و"حجم الحزمة" السمة يخبر العميل بمدى حجم الحزمة الخاصة به
ينبغي أن تكون الحمولات. مع هذا المزيج المميز من السمات، نحن نقول
العميل لإرسال حزمة واحدة بحجم 1024 بايت.

تمامًا كما في حالة خادم الصدى، فإننا نطلب من عميل الصدى أن يفعل ذلك آبدأ قلة النوم، لكن
هنا نبدأ تشغيل العميل بعد ثانية واحدة من تمكين الخادم (بعد ثانيتين من بدء تشغيل الخادم).
محاكاة).

محاكاة
ما يتعين علينا القيام به في هذه المرحلة هو تشغيل المحاكاة فعليًا. يتم ذلك باستخدام
الوظيفة العالمية محاكي :: تشغيل.

محاكي :: تشغيل () ؛

عندما قمنا سابقًا بتسمية الطرق،

serverApps.Start (Seconds (1.0));
serverApps.Stop (ثواني (10.0))؛

ClientApps.Start (ثواني (2.0))؛
ClientApps.Stop (Seconds (10.0));

لقد قمنا بالفعل بجدولة الأحداث في جهاز المحاكاة في 1.0 ثانية و 2.0 ثانية وحدثين
في 10.0 ثانية. متى محاكي :: تشغيل يتم استدعاء، سيبدأ النظام في البحث من خلال
قائمة الأحداث المجدولة وتنفيذها. أولاً سيتم تشغيل الحدث في 1.0 ثانية،
والذي سيعمل على تمكين تطبيق خادم الصدى (قد يؤدي هذا الحدث بدوره إلى جدولة العديد من الأحداث
أحداث أخرى). بعد ذلك سيتم تشغيل الحدث المجدول لمدة t=2.0 ثانية والذي سيبدأ
تطبيق عميل الصدى. مرة أخرى، قد يقوم هذا الحدث بجدولة العديد من الأحداث الأخرى. البداية
سيبدأ تنفيذ الحدث في تطبيق عميل الصدى مرحلة نقل البيانات
المحاكاة عن طريق إرسال حزمة إلى الخادم.

سيؤدي إرسال الحزمة إلى الخادم إلى إطلاق سلسلة من الأحداث
يتم جدولته تلقائيًا خلف الكواليس والذي سيؤدي إلى تنفيذ آليات
صدى الحزمة وفقًا لمعلمات التوقيت المختلفة التي قمنا بتعيينها في البرنامج النصي.

في النهاية، نظرًا لأننا نرسل حزمة واحدة فقط (تذكر ملف MaxPackets السمة كان من المقرر ان
one)، فإن سلسلة الأحداث التي يتم تشغيلها بواسطة طلب صدى العميل الواحد سوف تتضاءل و
سوف تصبح المحاكاة خاملة. وبمجرد حدوث ذلك، فإن الأحداث المتبقية ستكون قلة النوم
الأحداث للخادم والعميل. عندما يتم تنفيذ هذه الأحداث، لا توجد
مزيد من الأحداث لمعالجة و محاكي :: تشغيل عائدات. ثم تكتمل المحاكاة.

كل ما تبقى هو التنظيف. يتم ذلك عن طريق استدعاء الدالة العمومية
محاكاة::تدمير. كما وظائف المساعد (أو مستوى منخفض NS-3 كود) تم تنفيذها، هم
تم ترتيبها بحيث يتم إدخال الخطافات في جهاز المحاكاة لتدمير كافة الكائنات
التي تم إنشاؤها. لم يكن عليك تتبع أي من هذه الأشياء بنفسك ---
كل ما عليك فعله هو الاتصال محاكاة::تدمير والخروج. ال NS-3 اعتنى النظام
الجزء الصعب بالنسبة لك. باقي سطورنا الأولى NS-3 النصي، first.cc، افعل فقط
على ما يلي:

جهاز محاكاة :: تدمير () ؛
0 العودة؛
}

متى هيه محاكاة سوف قف؟
NS-3 هو محاكاة الأحداث المنفصلة (DE). في مثل هذه المحاكاة، يرتبط كل حدث
مع زمن تنفيذها، وتستمر المحاكاة من خلال تنفيذ الأحداث في الزمن
ترتيب وقت المحاكاة. قد تتسبب الأحداث في جدولة أحداث مستقبلية (على سبيل المثال، أ
قد يعيد المؤقت جدولة نفسه لينتهي في الفاصل الزمني التالي).

عادةً ما يتم تشغيل الأحداث الأولية بواسطة كل كائن، على سبيل المثال، سيقوم IPv6 بجدولة جهاز التوجيه
الإعلانات، وطلبات الجيران، وما إلى ذلك، يقوم التطبيق بجدولة الحزمة الأولى
إرسال الحدث، الخ.

عندما تتم معالجة حدث ما، فقد يُنشئ حدثًا واحدًا أو صفرًا أو أكثر. على سبيل المحاكاة
يتم تنفيذ الأحداث، ولكن قد يتم (أو لا) إنشاء المزيد من الأحداث. ال
ستتوقف المحاكاة تلقائيًا عند عدم وجود أحداث أخرى في قائمة انتظار الأحداث، أو عندما
تم العثور على حدث توقف خاص. يتم إنشاء حدث Stop من خلال محاكاة::توقف
(توقف الوقت)؛ وظيفة.

هناك حالة نموذجية حيث محاكاة::توقف من الضروري للغاية لوقف
المحاكاة: عندما يكون هناك حدث مستدام بذاته. أحداث مكتفية ذاتيا (أو متكررة).
هي الأحداث التي تعيد جدولة نفسها دائمًا. ونتيجة لذلك، فإنهم يحتفظون دائمًا بالحدث
قائمة الانتظار غير فارغة.

هناك العديد من البروتوكولات والوحدات التي تحتوي على أحداث متكررة، على سبيل المثال:

· FlowMonitor – فحص دوري للحزم المفقودة

· RIPng - البث الدوري لتحديث جداول التوجيه

· إلخ.

في هذه الحالات، محاكاة::توقف ضروري لإيقاف المحاكاة بأمان. في
بالإضافة إلى ذلك، متى NS-3 في وضع المضاهاة، RealtimeSimulator يستخدم للحفاظ على
ساعة محاكاة تتماشى مع ساعة الآلة، و محاكاة::توقف من الضروري التوقف
هذه العملية.

العديد من برامج المحاكاة في البرنامج التعليمي لا تستدعي صراحةً محاكاة::توقف,
نظرًا لأن قائمة انتظار الأحداث ستنفد الأحداث تلقائيًا. ومع ذلك، فإن هذه البرامج سوف
قبول أيضا دعوة ل محاكاة::توقف. على سبيل المثال، البيان الإضافي التالي في
سيقوم برنامج المثال الأول بجدولة توقف واضح عند 11 ثانية:

+ محاكي :: توقف (ثواني (11.0))؛
محاكي :: تشغيل () ؛
جهاز محاكاة :: تدمير () ؛
0 العودة؛
}

ما ورد أعلاه لن يغير سلوك هذا البرنامج فعليًا، نظرًا لأن هذا خاص
تنتهي المحاكاة بشكل طبيعي بعد 10 ثوانٍ. ولكن إذا قمت بتغيير وقت التوقف
البيان أعلاه من 11 ثانية إلى 1 ثانية، ستلاحظ أن المحاكاة
يتوقف قبل طباعة أي مخرجات على الشاشة (نظرًا لأن الإخراج يحدث في وقت قريب من 2
ثواني من وقت المحاكاة).

من المهم الاتصال محاكاة::توقف قبل دعوة محاكي :: تشغيل؛ غير ذلك،
محاكي :: تشغيل لا يجوز أبدًا إعادة التحكم إلى البرنامج الرئيسي لتنفيذ الإيقاف!

ابني معلمتك اليوغا سيناريو
لقد جعلنا من السهل بناء البرامج النصية البسيطة الخاصة بك. كل ما عليك فعله هو إسقاط
البرنامج النصي في الدليل المؤقت وسيتم إنشاؤه تلقائيًا إذا قمت بتشغيل Waf.
دعنا نحاول. ينسخ أمثلة/البرنامج التعليمي/first.cc في خدش الدليل بعد التغيير
العودة إلى دليل المستوى الأعلى.

$ سي دي../ ..
أمثلة $ cp/tutorial/first.ccخدش/myfirst.cc

الآن أنشئ المثال الأول للبرنامج النصي باستخدام waf:

$ ./واف

يجب أن تشاهد الرسائل التي تبلغك بأن حسابك الخاص بي أولا تم بناء المثال بنجاح.

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[614/708] cxx:خدش/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.357 ثانية)

يمكنك الآن تشغيل المثال (لاحظ أنه إذا قمت بإنشاء برنامجك في الدليل المؤقت
يجب عليك تشغيله خارج الدليل المؤقت):

$ ./waf --تشغيل الصفر/myfirst

يجب أن تشاهد بعض الإخراج:

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.418 ثانية)
تم إرسال 1024 بايت إلى 10.1.1.2
تم استلام 1024 بايت من 10.1.1.1
تم استلام 1024 بايت من 10.1.1.2

هنا ترى أن نظام البناء يتحقق للتأكد من أن الملف قد تم إنشاؤه و
ثم يديره. ترى أن مكون التسجيل في عميل الارتداد يشير إلى أنه قد تم الإرسال
حزمة واحدة بحجم 1024 بايت إلى خادم Echo Server على الإصدار 10.1.1.2. ترى أيضًا مكون التسجيل
على خادم الصدى نقول أنه تلقى 1024 بايت من 10.1.1.1. خادم الصدى
يردد صدى الحزمة بصمت وترى سجل عميل الارتداد الذي استلم الحزمة الخاصة به
العودة من الخادم.

NS-3 مصدر رمز
الآن بعد أن استخدمت بعضًا من NS-3 المساعدين الذين قد ترغب في إلقاء نظرة على بعض
كود المصدر الذي ينفذ هذه الوظيفة. يمكن تصفح أحدث رمز على
خادمنا على الرابط التالي: http://code.nsnam.org/ns-3-dev. هناك، سوف ترى
صفحة ملخص Mercurial لدينا NS-3 شجرة التنمية.

في أعلى الصفحة ستجد عدد من الروابط

ملخص | مختصرة | سجل التغيير | رسم بياني | العلامات | ملفات

انطلق وحدد ملف ملفات وصلة. هذا هو المستوى الأعلى لمعظمنا
مستودعات سوف ننظر:

drwxr-xr-x [أعلى]
drwxr-xr-x يربط ملفات بايثون
ملفات doc drwxr-xr-x
ملفات أمثلة drwxr-xr-x
ملفات drwxr-xr-x ns3
ملفات الصفر drwxr-xr-x
ملفات drwxr-xr-x src
ملفات الأدوات المساعدة drwxr-xr-x
-rw-r--r-- 2009-07-01 12:47 +0200 560 ملف hgignore | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 1886 ملف hgtags | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 1276 ملف المؤلفين | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html ملف | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 17987 ملف الترخيص | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 3742 الملف التمهيدي | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 16171 ملف ملاحظات الإصدار | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 6 ملف النسخة | المراجعات | علق
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 ملف waf | المراجعات | علق
-rwxr-xr-x 2009-07-01 12:47 +0200 28 ملف waf.bat | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 35395 ملف wscript | المراجعات | علق
-rw-r--r-- 2009-07-01 12:47 +0200 7673 ملف wutils.py | المراجعات | علق

أمثلة البرامج النصية لدينا موجودة في أمثلة الدليل. إذا قمت بالنقر فوق أمثلة سوف ترى
قائمة الدلائل الفرعية. أحد الملفات الموجودة في البرنامج التعليمي الدليل الفرعي هو first.cc. إذا كنت
انقر على first.cc ستجد الرمز الذي مررت به للتو.

كود المصدر موجود بشكل رئيسي في SRC الدليل. يمكنك عرض كود المصدر إما عن طريق
بالنقر على اسم الدليل أو بالنقر على ملفات الارتباط على يمين
اسم الدليل. إذا قمت بالنقر فوق SRC الدليل، سيتم نقلك إلى قائمة
هيه SRC الدلائل الفرعية. إذا قمت بعد ذلك بالنقر فوق النواة الدليل الفرعي، وسوف تجد قائمة
ملفات. الملف الأول الذي ستجده (حتى كتابة هذه السطور) هو إحباط.ح. إذا قمت بالنقر فوق
إحباط.ح الرابط، سيتم إرسالك إلى الملف المصدر ل إحباط.ح الذي يحتوي على وحدات ماكرو مفيدة
للخروج من البرامج النصية إذا تم الكشف عن ظروف غير طبيعية.

يمكن العثور على الكود المصدري للمساعدين الذين استخدمناهم في هذا الفصل في
src/applications/helper الدليل. لا تتردد في التجول في شجرة الدليل للحصول عليه
الشعور بما هو موجود وأسلوب NS-3 البرامج.

القرص


باستخدام هيه تسجيل وحدة
لقد ألقينا بالفعل نظرة سريعة على 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 -- تسجيل الرسالة المرتبطة دون قيد أو شرط (لا يوجد مستوى سجل مرتبط).

يمكن طلب كل مستوى منفردًا أو بشكل تراكمي؛ ويمكن إعداد التسجيل باستخدام أ
متغير بيئة الصدفة (NS_LOG) أو عن طريق تسجيل استدعاء وظيفة النظام. كما شوهد
في وقت سابق من البرنامج التعليمي، كان نظام التسجيل يحتوي على وثائق Doxygen والآن سيكون ملف
الوقت المناسب للاطلاع على وثائق وحدة التسجيل إذا لم تكن قد قمت بذلك.

الآن بعد أن قرأت الوثائق بتفصيل كبير، دعنا نستخدم بعضًا من هذه المعرفة
للحصول على بعض المعلومات المثيرة للاهتمام من الصفر/myfirst.cc مثال البرنامج النصي لديك
تم بنيانه مسبقا.

تمكين تسجيل
دعونا نستخدم متغير البيئة NS_LOG لتشغيل المزيد من التسجيل، ولكن أولاً، فقط
احصل على اتجاهاتنا، وقم بتشغيل البرنامج النصي الأخير تمامًا كما فعلت سابقًا،

$ ./waf --تشغيل الصفر/myfirst

يجب أن تشاهد الإخراج المألوف الآن للأول NS-3 برنامج المثال

$ Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.413 ثانية)
تم إرسال 1024 بايت إلى 10.1.1.2
تم استلام 1024 بايت من 10.1.1.1
تم استلام 1024 بايت من 10.1.1.2

اتضح أن الرسائل "المرسلة" و"المستلمة" التي تراها أعلاه يتم تسجيلها بالفعل
رسائل من UdpEchoClientApplication UdpEchoServerApplication. يمكننا أن نسأل
تطبيق العميل، على سبيل المثال، لطباعة المزيد من المعلومات عن طريق تحديد مستوى التسجيل الخاص به
عبر متغير البيئة NS_LOG.

سأفترض من الآن فصاعدًا أنك تستخدم غلافًا يشبه sh يستخدم
بناء الجملة "VARIABLE=value". إذا كنت تستخدم غلافًا يشبه csh، فسيتعين عليك القيام بذلك
تحويل الأمثلة الخاصة بي إلى بناء جملة "قيمة setenv VARIABLE" التي تتطلبها تلك الأصداف.

في الوقت الحالي، يستجيب تطبيق عميل صدى UDP للسطر التالي من التعليمات البرمجية
الصفر/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.404 ثانية)
UdpEchoClientApplication:UdpEchoClient()
تطبيق أودبيكوكلينت:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:إرسال ()
تم إرسال 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(هذا) في وظائف الأعضاء
يفضل. استخدم NS_LOG_FUNCTION_NOARGS() فقط في الوظائف الثابتة. لاحظ، مع ذلك، أن
لا توجد متطلبات في NS-3 النظام الذي يجب أن تدعم النماذج أي معين
وظيفة التسجيل. ويترك القرار المتعلق بكمية المعلومات التي يتم تسجيلها
مطور النموذج الفردي. وفي حالة تطبيقات الصدى، يوجد قدر كبير من السجل
الإخراج متاح.

يمكنك الآن رؤية سجل استدعاءات الوظائف التي تم إجراؤها على التطبيق. اذا أنت
انظر عن كثب ستلاحظ وجود نقطتين واحدتين بين السلسلة UdpEchoClientApplication
واسم الطريقة التي ربما كنت تتوقع فيها مشغل نطاق C++ (::). هذا هو
متعمد.

الاسم ليس في الواقع اسم فئة، بل هو اسم مكون التسجيل. عندما يكون هناك
المراسلات الفردية بين الملف المصدر والفئة، ستكون هذه بشكل عام هي المراسلات
اسم فئة ولكن يجب أن تفهم أنه ليس في الواقع اسم فئة، وهناك
نقطتان مفردتان هناك بدلاً من نقطتين مزدوجتين لتذكيرك بطريقة خفية نسبيًا
قم بفصل اسم مكون التسجيل عن اسم الفئة من الناحية المفاهيمية.

اتضح أنه في بعض الحالات، قد يكون من الصعب تحديد الطريقة الفعلية
يولد رسالة السجل. إذا نظرت إلى النص أعلاه، قد تتساءل أين السلسلة
"تم الاستلام 1024 بايت تبدأ من 10.1.1.2" يأتي من. يمكنك حل هذه المشكلة عن طريق استخدام OR'ing
prefix_func المستوى في NS_LOG متغيرات البيئة. حاول القيام بما يلي،

$ التصدير 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

لاحظ أن علامات الاقتباس مطلوبة نظرًا لأن الشريط الرأسي الذي نستخدمه للإشارة إلى OR
العملية هي أيضًا موصل أنبوب Unix.

الآن، إذا قمت بتشغيل البرنامج النصي، فسوف ترى أن نظام التسجيل يتأكد من أن كل
تكون الرسالة من مكون السجل المحدد مسبوقة باسم المكون.

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.417 ثانية)
UdpEchoClientApplication:UdpEchoClient()
تطبيق أودبيكوكلينت:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:إرسال ()
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
تم تحديدها على هذا النحو. أصبحت الرسالة "تم استلام 1024 بايت من 10.1.1.2" واضحة الآن
تم تحديده على أنه قادم من تطبيق عميل الصدى. يجب أن تكون الرسالة المتبقية
قادمة من تطبيق خادم صدى UDP. يمكننا تمكين هذا المكون عن طريق إدخال ملف
قائمة مفصولة بنقطتين للمكونات في متغير البيئة NS_LOG.

$ التصدير 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
UdpEchoServerApplication=level_all|prefix_func'

تحذير: سوف تحتاج إلى إزالة السطر الجديد بعد : في النص المثال أعلاه الذي
موجود فقط لأغراض تنسيق المستندات.

الآن، إذا قمت بتشغيل البرنامج النصي، فسوف ترى كافة رسائل السجل من كلا عميلي الصدى
وتطبيقات الخادم. قد ترى أن هذا يمكن أن يكون مفيدًا جدًا في تصحيح المشكلات.

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.406 ثانية)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
تطبيق أودبيكوكلينت:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:إرسال ()
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()

من المفيد أيضًا في بعض الأحيان أن تكون قادرًا على رؤية وقت المحاكاة الذي تظهر فيه رسالة السجل
تم إنشاؤه. يمكنك القيام بذلك عن طريق ORing في بت prefix_time.

$ التصدير 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time:
UdpEchoServerApplication=level_all|prefix_func|prefix_time'

مرة أخرى، سيكون عليك إزالة السطر الجديد أعلاه. إذا قمت بتشغيل البرنامج النصي الآن، فيجب عليك ذلك
انظر الإخراج التالي:

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.418 ثانية)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
تطبيق UdpEchoClient 0s:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:إرسال ()
2s UdpEchoClientApplication:Send(): تم إرسال 1024 بايت إلى 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): تم تلقي 1024 بايت من 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): صدى الحزمة
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): تم تلقي 1024 بايت من 10.1.1.2
10 ثانية UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

يمكنك أن ترى أنه تم استدعاء مُنشئ UdpEchoServer في وقت محاكاة
0 ثانية. وهذا يحدث بالفعل قبل بدء المحاكاة، ولكن الوقت قد حان
يتم عرضها على أنها صفر ثانية. وينطبق الشيء نفسه على رسالة منشئ UdpEchoClient.

أذكر أن الصفر/first.cc بدأ البرنامج النصي تطبيق خادم الصدى في ثانية واحدة
في المحاكاة. يمكنك الآن أن ترى أن StartApplication طريقة السيرفر هي
في الواقع، تم الاتصال به في ثانية واحدة. يمكنك أيضًا أن ترى أن تطبيق عميل الصدى هو
بدأت في زمن محاكاة مدته ثانيتان كما طلبنا في البرنامج النصي.

يمكنك الآن متابعة التقدم المحرز في المحاكاة من جدولة الإرسال استدعاء في
العميل الذي يدعو إرسال إلى التعامل مع القراءة رد الاتصال في تطبيق خادم الصدى. ملحوظة
أن الوقت المنقضي لإرسال الحزمة عبر رابط نقطة إلى نقطة هو 3.69
ميلي ثانية. ترى خادم الصدى يسجل رسالة تخبرك بأنه قد تردد صدى
الحزمة، وبعد تأخير آخر للقناة، ترى عميل الصدى يتلقى ملف
ردد الحزمة في التعامل مع القراءة الأسلوب.

هناك الكثير مما يحدث تحت الأغطية في هذه المحاكاة، وهو أمر لا تعرفه أنت
رؤية كذلك. يمكنك بسهولة متابعة العملية برمتها عن طريق تشغيل كافة العناصر
تسجيل المكونات في النظام. حاول ضبط NS_LOG متغير لما يلي،

$ التصدير 'NS_LOG=*=level_all|prefix_func|prefix_time'

العلامة النجمية أعلاه هي حرف بدل مكون التسجيل. سيؤدي هذا إلى تشغيل كافة
تسجيل جميع المكونات المستخدمة في المحاكاة. لن أقوم بإعادة إنتاج الإخراج
هنا (حتى كتابة هذه السطور، ينتج 1265 سطرًا من الإخراج لصدى الحزمة الواحدة) ولكن
يمكنك إعادة توجيه هذه المعلومات إلى ملف والاطلاع عليها مع المفضلة لديك
المحرر إذا أردت،

$ ./waf --runخدش/myfirst > log.out 2>&1

أنا شخصياً أستخدم هذا الإصدار المطول للغاية من التسجيل عندما يتم تقديم ملف
مشكلة وليس لدي أي فكرة أين تسير الأمور بشكل خاطئ. يمكنني متابعة التقدم المحرز في
التعليمات البرمجية بسهولة تامة دون الحاجة إلى تعيين نقاط التوقف والتنقل خلال التعليمات البرمجية في مصحح الأخطاء.
يمكنني فقط تعديل المخرجات في المحرر المفضل لدي والبحث عن الأشياء التي أتوقعها،
وأرى أشياء تحدث لا أتوقعها. عندما يكون لدي فكرة عامة عما هو
إذا حدث خطأ، فإنني أنتقل إلى مصحح الأخطاء لإجراء فحص دقيق للمشكلة.
يمكن أن يكون هذا النوع من المخرجات مفيدًا بشكل خاص عندما يقوم البرنامج النصي الخاص بك بعمل شيء ما بشكل كامل
غير متوقع. إذا كنت تنتقل باستخدام مصحح الأخطاء، فقد تفوتك رحلة غير متوقعة
بالكامل. تسجيل الرحلة يجعلها مرئية بسرعة.

إضافة تسجيل إلى لك رمز
يمكنك إضافة تسجيل جديد إلى عمليات المحاكاة الخاصة بك عن طريق إجراء مكالمات إلى مكون السجل عبر
عدة وحدات ماكرو. دعونا نفعل ذلك في myfirst.cc البرنامج النصي لدينا في خدش الدليل.

تذكر أننا قمنا بتعريف مكون التسجيل في هذا البرنامج النصي:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample")؛

أنت تعلم الآن أنه يمكنك تمكين كافة عمليات التسجيل لهذا المكون عن طريق تعيين
NS_LOG متغير البيئة على مختلف المستويات. دعونا نمضي قدما ونضيف بعض التسجيل إلى
النص. الماكرو المستخدم لإضافة رسالة سجل مستوى المعلومات هو NS_LOG_INFO. اذهب
للأمام وأضف واحدة (قبل أن نبدأ في إنشاء العقد مباشرة) تخبرك بأن البرنامج النصي
هو "إنشاء طوبولوجيا." ويتم ذلك كما في مقتطف الكود هذا،

ساعات العمل الصفر/myfirst.cc في محررك المفضل وأضف السطر،

NS_LOG_INFO ("إنشاء الهيكل")؛

قبل السطور مباشرة

عقد NodeContainer
العقد.إنشاء (2);

الآن أنشئ البرنامج النصي باستخدام waf وامسح ملف NS_LOG متغير لإيقاف سيل
التسجيل الذي قمنا بتمكينه سابقًا:

$ ./واف
$ تصدير NS_LOG=

الآن، إذا قمت بتشغيل البرنامج النصي،

$ ./waf --تشغيل الصفر/myfirst

سوف ليس شاهد رسالتك الجديدة منذ مكون التسجيل المرتبط بها
(مثال FirstScript) لم يتم تمكينه. لكي ترى رسالتك يجب عليك ذلك
تمكين مثال FirstScript مكون التسجيل بمستوى أكبر من أو يساوي
NS_LOG_INFO. إذا كنت تريد فقط رؤية هذا المستوى المحدد من التسجيل، فيمكنك تمكينه
بواسطة،

$export NS_LOG=FirstScriptExample=info

إذا قمت الآن بتشغيل البرنامج النصي، فسترى رسالة سجل "إنشاء الهيكل" الجديدة،

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.404 ثانية)
خلق الطوبولوجيا
تم إرسال 1024 بايت إلى 10.1.1.2
تم استلام 1024 بايت من 10.1.1.1
تم استلام 1024 بايت من 10.1.1.2

باستخدام أمر خط الحجج
تجاوز الترتيب السمات
هناك طريقة أخرى يمكنك من خلالها تغيير الطريقة NS-3 تتصرف البرامج النصية دون تحرير ويتم البناء عبرها
أمر خط الحجج. نحن نقدم آلية لتحليل وسيطات سطر الأوامر و
تعيين المتغيرات المحلية والعالمية تلقائيًا بناءً على تلك الوسائط.

الخطوة الأولى في استخدام نظام وسيطة سطر الأوامر هي الإعلان عن سطر الأوامر
محلل. يتم ذلك بكل بساطة (في برنامجك الرئيسي) كما في الكود التالي،

مادبا
main (int argc، char * argv [])
{


CommandLine كمد ؛
cmd ، Parse (argc ، argv) ؛


}

هذا المقتطف البسيط المكون من سطرين مفيد جدًا في حد ذاته. فإنه يفتح الباب أمام
NS-3 المتغير العالمي و السمة أنظمة. تفضل وأضف سطرين من التعليمات البرمجية إلى
هيه الصفر/myfirst.cc البرنامج النصي في بداية رئيسي. المضي قدما وبناء البرنامج النصي وتشغيله
عليه، ولكن اطلب المساعدة من البرنامج النصي بالطريقة التالية،

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

سيطلب هذا من Waf تشغيل ملف الصفر/ماي فيرست البرنامج النصي وتمرير وسيطة سطر الأوامر
--PrintHelp إلى البرنامج النصي. علامات الاقتباس مطلوبة لفرز البرنامج الذي يحصل عليه
دعوى. سوف يرى محلل سطر الأوامر الآن --PrintHelp الحجة والرد عليها،

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.413 ثانية)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): اسم وسيطة التعامل = قيمة PrintHelp =
--PrintHelp: اطبع رسالة المساعدة هذه.
--PrintGroups: طباعة قائمة المجموعات.
--PrintTypeIds: طباعة كافة معرفات النوع.
--PrintGroup=[group]: طباعة كافة معرفات المجموعة.
--PrintAttributes=[typeid]: طباعة كافة سمات typeid.
--PrintGlobals: طباعة قائمة العالميات.

دعونا نركز على --سمات الطباعة خيار. لقد أشرنا بالفعل إلى NS-3 السمة
النظام أثناء المشي من خلال first.cc النصي. نظرنا إلى السطور التالية من
الرمز،

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5 ميجا بت في الثانية"))؛
pointToPoint.SetChannelAttribute ("Delay"، StringValue ("2ms"))؛

وذكر ذلك معدل البيانات كان في الواقع السمة ل PointToPointNetDevice. دعونا
استخدم محلل وسيطة سطر الأوامر لإلقاء نظرة على السمات ل
PointToPointNetDevice. تقول قائمة المساعدة أنه يجب علينا تقديم ملف النوع. هذا
يتوافق مع اسم الفئة التي ينتمي إليها السمات ينتمي ل. في هذه الحالة
سيكون ذلك ns3::PointToPointNetDevice. دعنا نمضي قدما ونكتب،

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

سيقوم النظام بطباعة كافة السمات من هذا النوع من الأجهزة الصافية. بين ال
السمات سترى المدرجة هي،

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
معدل البيانات الافتراضي للارتباطات من نقطة إلى نقطة

هذه هي القيمة الافتراضية التي سيتم استخدامها عندما PointToPointNetDevice تم إنشاؤه في
نظام. لقد تجاوزنا هذا الافتراضي مع السمة وضع في PointToPointHelper
فوق. دعونا نستخدم القيم الافتراضية للأجهزة والقنوات من نقطة إلى نقطة
حذف SetDeviceAttribute دعوة و SetChannelAttribute مكالمة من myfirst.cc
لدينا في الدليل الصفر.

يجب أن يعلن البرنامج النصي الخاص بك الآن فقط عن PointToPointHelper ولا تفعل أي شيء طقم عمليات
كما في المثال التالي،



عقد NodeContainer
العقد.إنشاء (2);

PointToPointHelper pointToPoint;

أجهزة NetDeviceContainer؛
الأجهزة = pointToPoint.Install (العقد)؛



المضي قدمًا وإنشاء البرنامج النصي الجديد باستخدام Waf (./waff) ودعنا نعود ونمكن البعض
التسجيل من تطبيق خادم صدى UDP وتشغيل بادئة الوقت.

$ التصدير 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

إذا قمت بتشغيل البرنامج النصي، يجب أن تشاهد الآن الإخراج التالي،

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.405 ثانية)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
تم إرسال 1024 بايت إلى 10.1.1.2
2.25732s تم استلام 1024 بايت من 10.1.1.1
2.25732s حزمة صدى
تم استلام 1024 بايت من 10.1.1.2
10 ثانية UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

تذكر أنه في المرة الأخيرة التي نظرنا فيها إلى وقت المحاكاة الذي كانت فيه الحزمة
تم استلامها بواسطة خادم الصدى، وكانت في 2.00369 ثانية.

2.00369s UdpEchoServerApplication:HandleRead(): تم تلقي 1024 بايت من 10.1.1.1

الآن يتلقى الحزمة في 2.25732 ثانية. هذا لأننا أسقطنا للتو
معدل البيانات 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=5 ميجابت في الثانية
--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.417 ثانية)
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
10 ثانية UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

لاحظ أن الخادم يستقبل الحزمة مرة أخرى في 2.00369 ثانية. نستطيع
في الواقع تعيين أي من السمات المستخدمة في البرنامج النصي بهذه الطريقة. على وجه الخصوص يمكننا
تعيين UdpEchoClient السمة MaxPackets إلى قيمة أخرى غير واحدة.

كيف يمكنك أن تفعل ذلك؟ جربها. تذكر أنه عليك التعليق على المكان
نحن نتجاوز الافتراضي السمة وتعيين صراحة MaxPackets في البرنامج النصي. ثُم أنت
يجب إعادة بناء البرنامج النصي. سيكون عليك أيضًا العثور على بناء الجملة للإعداد الفعلي
قيمة السمة الافتراضية الجديدة باستخدام وسيلة مساعدة سطر الأوامر. بمجرد حصولك على هذا
اكتشفت أنك يجب أن تكون قادرًا على التحكم في عدد الحزم التي يتم تكرارها من الأمر
خط. نظرًا لأننا أشخاص لطيفون، فسنخبرك أنه يجب أن ينتهي سطر الأوامر الخاص بك بالبحث
شيء مثل،

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5 ميجابت في الثانية
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"

فيلم Hooking معلمتك اليوغا الخاصة القيم
يمكنك أيضًا إضافة الخطافات الخاصة بك إلى نظام سطر الأوامر. ويتم ذلك بكل بساطة عن طريق
يستخدم ال ادفاليو طريقة إلى محلل سطر الأوامر.

دعونا نستخدم هذه الميزة لتحديد عدد الحزم التي سيتم صدىها بشكل مختلف تمامًا
طريق. دعونا نضيف متغير محلي يسمى n الحزم إلى رئيسي وظيفة. سنقوم بالتهيئة
إلى واحد لمطابقة سلوكنا الافتراضي السابق. للسماح لمحلل سطر الأوامر بذلك
لتغيير هذه القيمة، نحتاج إلى ربط القيمة بالمحلل. نحن نفعل ذلك عن طريق إضافة مكالمة
إلى ادفاليو. المضي قدما وتغيير الصفر/myfirst.cc البرنامج النصي للبدء بـ
الكود التالي ,

مادبا
main (int argc، char * argv [])
{
uint32_t nPackets = 1;

CommandLine كمد ؛
cmd.AddValue("nPackets"، "عدد الحزم المطلوب صدى"، nPackets)؛
cmd ، Parse (argc ، argv) ؛



قم بالتمرير لأسفل إلى النقطة في البرنامج النصي حيث قمنا بتعيين MaxPackets السمة وتغييره
بحيث يتم ضبطه على المتغير n الحزم بدلا من الثابت 1 كما هو موضح أدناه.

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

الآن إذا قمت بتشغيل البرنامج النصي وتوفير --PrintHelp حجة، يجب أن ترى الجديد الخاص بك
اسم المستخدم حجة المدرجة في شاشة المساعدة.

يحاول،

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

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.403 ثانية)
--PrintHelp: اطبع رسالة المساعدة هذه.
--PrintGroups: طباعة قائمة المجموعات.
--PrintTypeIds: طباعة كافة معرفات النوع.
--PrintGroup=[group]: طباعة كافة معرفات المجموعة.
--PrintAttributes=[typeid]: طباعة كافة سمات typeid.
--PrintGlobals: طباعة قائمة العالميات.
حجج المستخدم:
--nPackets: عدد الحزم المراد صدىها

إذا كنت تريد تحديد عدد الحزم المراد صدى لها، فيمكنك الآن القيام بذلك عن طريق تعيين
--nPackets حجة في سطر الأوامر،

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

يجب أن ترى الآن

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.404 ثانية)
0s 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
10 ثانية UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

لقد قمت الآن بتكرار حزمتين. من السهل جدا، أليس كذلك؟

يمكنك أن ترى أنه إذا كنت NS-3 المستخدم، يمكنك استخدام نظام وسيطة سطر الأوامر ل
السيطرة على القيم العالمية و السمات. إذا كنت مؤلف نموذجي، يمكنك إضافة جديد
السمات لديك الأجسام وستكون متاحة تلقائيًا للإعداد من خلالك
المستخدمين من خلال نظام سطر الأوامر. إذا كنت مؤلف البرنامج النصي، يمكنك إضافة جديد
المتغيرات إلى البرامج النصية الخاصة بك وربطها بنظام سطر الأوامر دون عناء.

باستخدام هيه البحث عن المفقودين
بيت القصيد من المحاكاة هو توليد مخرجات لمزيد من الدراسة، و NS-3
نظام التتبع هو الآلية الأساسية لذلك. منذ NS-3 هو برنامج C++، قياسي
يمكن استخدام مرافق توليد المخرجات من برامج C++:

#يشمل

انت مين ()
{

std :: cout << "قيمة x هي" << x << std :: endl؛

}

يمكنك أيضًا استخدام وحدة التسجيل لإضافة بنية صغيرة إلى الحل الخاص بك. هناك
هناك العديد من المشاكل المعروفة الناتجة عن مثل هذه الأساليب ولذلك قدمنا
النظام الفرعي العام لتتبع الأحداث لمعالجة المشكلات التي اعتقدنا أنها مهمة.

الأهداف الأساسية لل NS-3 نظام التتبع هو:

· بالنسبة للمهام الأساسية، يجب أن يسمح نظام التتبع للمستخدم بإنشاء تتبع قياسي
لمصادر التتبع الشائعة، ولتخصيص الكائنات التي تنشئ التتبع؛

· يجب أن يكون المستخدمون المتوسطون قادرين على توسيع نظام التتبع لتعديل تنسيق الإخراج
تم إنشاؤها، أو لإدراج مصادر تتبع جديدة، دون تعديل جوهر الملف
محاكاة.

يمكن للمستخدمين المتقدمين تعديل جوهر المحاكاة لإضافة مصادر ومصارف تتبع جديدة.

إنّ NS-3 نظام التتبع مبني على مفاهيم مصادر التتبع المستقلة و
تتبع الأحواض، وآلية موحدة لربط المصادر بالأحواض. مصادر التتبع هي
الكيانات التي يمكنها الإشارة إلى الأحداث التي تحدث في المحاكاة وتوفير الوصول إليها
البيانات الأساسية المثيرة للاهتمام. على سبيل المثال، يمكن أن يشير مصدر التتبع إلى وقت وجود الحزمة
يتم استلامها بواسطة جهاز شبكة وتوفر الوصول إلى محتويات الحزمة للتتبع المهتم
المصارف.

مصادر التتبع ليست مفيدة في حد ذاتها، بل يجب أن تكون "متصلة" بأجزاء أخرى من المصدر
رمز يفعل شيئًا مفيدًا بالفعل بالمعلومات المقدمة من الحوض. يتعقب
تعتبر المصارف مستهلكة للأحداث والبيانات التي توفرها مصادر التتبع. على سبيل المثال،
يمكن للمرء إنشاء حوض تتبع من شأنه (عند توصيله بمصدر التتبع لـ
المثال السابق) قم بطباعة أجزاء مثيرة للاهتمام من الحزمة المستلمة.

الأساس المنطقي لهذا التقسيم الصريح هو السماح للمستخدمين بإرفاق أنواع جديدة من الأحواض
مصادر التتبع الموجودة، دون الحاجة إلى تحرير وإعادة تجميع جوهر الملف
محاكاة. وبالتالي، في المثال أعلاه، يمكن للمستخدم تحديد حوض تتبع جديد فيه
البرنامج النصي وإرفاقه بمصدر التتبع الموجود المحدد في قلب المحاكاة بواسطة
تحرير البرنامج النصي للمستخدم فقط.

في هذا البرنامج التعليمي، سنتعرف على بعض المصادر والمصارف المحددة مسبقًا ونوضح كيفية القيام بذلك
وقد يتم تخصيصها بجهد قليل من جانب المستخدم. راجع دليل ns-3 أو الأقسام الإرشادية
للحصول على معلومات حول تكوين التتبع المتقدم بما في ذلك توسيع التتبع
مساحة الاسم وإنشاء مصادر تتبع جديدة.

ASCII البحث عن المفقودين
NS-3 يوفر وظيفة مساعدة تغلف نظام التتبع منخفض المستوى لمساعدتك
مع التفاصيل المتعلقة بتكوين بعض آثار الحزم التي يمكن فهمها بسهولة. اذا أنت
تمكين هذه الوظيفة، سوف ترى الإخراج في ملفات ASCII --- ومن هنا الاسم. ل
أولئك الذين يعرفون NS-2 الإخراج، وهذا النوع من التتبع مشابه لـ خارج.tr ولدت
من خلال العديد من النصوص.

دعنا ننتقل مباشرة ونضيف بعض مخرجات تتبع ASCII إلى ملفنا الصفر/myfirst.cc
النصي. مباشرة قبل المكالمة محاكي :: تشغيل ()، أضف أسطر التعليمات البرمجية التالية:

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

كما هو الحال في العديد من الآخرين NS-3 التعابير، يستخدم هذا الرمز كائنًا مساعدًا للمساعدة في إنشاء ASCII
آثار. يحتوي السطر الثاني على استدعاءات أسلوب متداخلة. طريقة "الداخل"
كريتيفيليستريم () يستخدم لغة كائن غير مسمى لإنشاء كائن دفق ملف على
المكدس (بدون اسم كائن) وتمريره إلى الطريقة المطلوبة. سوف نذهب إلى هذا
المزيد في المستقبل، ولكن كل ما عليك معرفته في هذه المرحلة هو أنك تقوم بإنشاء ملف
كائن يمثل ملفًا يسمى "myfirst.tr" ويمرره إليه NS-3. انت تقول
NS-3 للتعامل مع مشكلات عمر الكائن الذي تم إنشاؤه وأيضًا للتعامل مع المشكلات
ناتج عن قيود غير معروفة (متعمدة) لكائنات C++ ofstream المتعلقة بالنسخ
الصانعين.

المكالمة الخارجية إلى تمكين AsciiAll()، يخبر المساعد أنك تريد تمكين ASCII
التتبع على جميع الأجهزة من نقطة إلى نقطة في المحاكاة الخاصة بك؛ وتريد (المقدمة)
تتبع المصارف لكتابة معلومات حول حركة الحزمة بتنسيق ASCII.

لمن هم على دراية NS-2، فإن الأحداث التي تم تتبعها تعادل نقاط التتبع الشائعة
التي تسجل الأحداث "+" و"-" و"d" و"r".

يمكنك الآن إنشاء البرنامج النصي وتشغيله من سطر الأوامر:

$ ./waf --تشغيل الصفر/myfirst

كما رأيت عدة مرات من قبل، سوف ترى بعض الرسائل من واف وبعد ذلك
"تم الانتهاء من البناء بنجاح" مع عدد من الرسائل من البرنامج قيد التشغيل.

عند تشغيله، سيكون البرنامج قد أنشأ ملفًا باسم myfirst.tr. بسبب الطريق
إذا كان Waf يعمل، فلن يتم إنشاء الملف في الدليل المحلي، بل يتم إنشاؤه في ملف
دليل المستوى الأعلى للمستودع بشكل افتراضي. إذا كنت تريد التحكم في مكان الآثار
يتم حفظها يمكنك استخدام --cwd خيار Waf لتحديد ذلك. نحن لم نفعل ذلك، وبالتالي
نحتاج إلى التغيير إلى دليل المستوى الأعلى في الريبو الخاص بنا وإلقاء نظرة على ASCII
ملف التتبع myfirst.tr في المحرر المفضل لديك.

توزيع أسكي آثار
هناك الكثير من المعلومات هناك في شكل كثيف جدًا، ولكن أول شيء يجب ملاحظته
هو أن هناك عددا من الخطوط المميزة في هذا الملف. قد يكون من الصعب أن نرى
هذا واضح إلا إذا قمت بتوسيع نافذتك بشكل كبير.

كل سطر في الملف يتوافق مع تتبع حدث. في هذه الحالة نحن نتتبع الأحداث
هيه نقل طابور موجودة في كل جهاز شبكة من نقطة إلى نقطة في المحاكاة. ال
قائمة انتظار الإرسال هي قائمة انتظار يتم من خلالها توجيه كل حزمة إلى قناة من نقطة إلى نقطة
يجب أن تمر. لاحظ أن كل سطر في ملف التتبع يبدأ بحرف وحيد (يحتوي على
الفضاء بعده). سيكون لهذه الشخصية المعنى التالي:

· +: حدثت عملية إدراج في قائمة انتظار الجهاز؛

· -: حدثت عملية إلغاء الانتظار في قائمة انتظار الجهاز؛

· d: تم إسقاط الحزمة، عادةً بسبب امتلاء قائمة الانتظار؛

· r: تم استلام حزمة بواسطة جهاز الشبكة.

دعونا نلقي نظرة أكثر تفصيلا على السطر الأول في ملف التتبع. سوف أكسرها
إلى أقسام (بمسافة بادئة للتوضيح) مع رقم مرجعي على الجانب الأيسر:

+
2
/NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
ns3::PppHeader (
بروتوكول نقطة إلى نقطة: IP (0x0021))
ns3::Ipv4Header (
tos 0x0 ttl 64 معرف 0 بروتوكول 17 إزاحة 0 إشارة [لا شيء]
الطول: 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 والتي نفكر بها عادةً على أنها "node
0". توجد في كل عقدة قائمة بالأجهزة التي تم تثبيتها. تظهر هذه القائمة
التالي في مساحة الاسم. يمكنك أن ترى أن حدث التتبع هذا يأتي من قائمة الأجهزة/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 معرف 0 بروتوكول 17 إزاحة 0 إشارة [لا شيء]
الطول: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
الطول: 1032 49153 > 9)
الحمولة (الحجم = 1024)

لاحظ أن عملية التتبع تتم الآن r وزاد زمن المحاكاة إلى 2.25732
ثواني. إذا كنت تتبع الخطوات التعليمية عن كثب، فهذا يعني أنك قمت بذلك
غادر معدل البيانات من أجهزة النت والقناة تأخير لتعيينها على قيمها الافتراضية.
يجب أن تكون هذه المرة مألوفة كما رأيتها من قبل في القسم السابق.

تم تغيير إدخال مساحة اسم مصدر التتبع (المرجع 02) ليعكس هذا الحدث
قادمة من العقدة 1 (/NodeList/1) ومصدر تتبع استقبال الحزمة (/ماكركس). هو - هي
يجب أن يكون من السهل جدًا عليك متابعة تقدم الحزمة من خلال الهيكل
النظر في بقية الآثار في الملف.

PCAP البحث عن المفقودين
إنّ NS-3 يمكن أيضًا استخدام مساعدي الجهاز لإنشاء ملفات التتبع في ملف .pcap شكل. ال
يرمز الاختصار pcap (الذي يُكتب عادةً بأحرف صغيرة) إلى التقاط الحزم، وهو في الواقع عبارة عن
API الذي يتضمن تعريف أ .pcap تنسيق الملف. البرنامج الأكثر شعبية الذي
يمكن قراءة هذا التنسيق وعرضه وهو Wireshark (المعروف سابقًا باسم Ethereal). مهما يكن هنا
هناك العديد من أدوات تحليل تتبع حركة المرور التي تستخدم تنسيق الحزمة هذا. نحن نشجع المستخدمين على
استغلال العديد من الأدوات المتاحة لتحليل آثار PCAP. في هذا البرنامج التعليمي، نحن
ركز على عرض آثار PCAP باستخدام tcpdump.

الكود المستخدم لتمكين تتبع pcap هو سطر واحد.

pointToPoint.EnablePcapAll ("myfirst")؛

تابع وأدخل هذا السطر من التعليمات البرمجية بعد رمز تتبع ASCII الذي أضفناه للتو
الصفر/myfirst.cc. لاحظ أننا مررنا السلسلة "myfirst" فقط، وليس
"myfirst.pcap" أو شيء مشابه. وذلك لأن المعلمة هي بادئة وليست a
اسم الملف الكامل. سيقوم المساعد بالفعل بإنشاء ملف تتبع لكل نقطة إلى نقطة
الجهاز في المحاكاة. سيتم إنشاء أسماء الملفات باستخدام البادئة، ورقم العقدة،
رقم الجهاز ولاحقة ".pcap".

في المثال النصي الخاص بنا، سنرى في النهاية الملفات المسماة "myfirst-0-0.pcap" و
"myfirst-1-0.pcap" وهي تتبعات PCAP للعقدة 0-device 0 والعقدة 1-device 0،
على التوالي.

بمجرد إضافة سطر التعليمات البرمجية لتمكين تتبع PCAP، يمكنك تشغيل البرنامج النصي في ملف
بالطريقة المعتادة:

$ ./waf --تشغيل الصفر/myfirst

إذا نظرت إلى دليل المستوى الأعلى للتوزيع الخاص بك، فيجب أن ترى الآن ثلاثة سجلات
الملفات: myfirst.tr هو ملف تتبع ASCII الذي قمنا بفحصه مسبقًا. myfirst-0-0.pcap
myfirst-1-0.pcap هي ملفات pcap الجديدة التي أنشأناها للتو.

القراءة الناتج مع com.tcpdump
أسهل ما يمكنك فعله في هذه المرحلة هو الاستخدام com.tcpdump للنظر في تمويله الملفات.

$ 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 (الجهاز العميل) الذي تمثله حزمة الصدى
تم إرسالها خلال ثانيتين إلى المحاكاة. إذا نظرت إلى التفريغ الثاني (myfirst-1-0.pcap)
يمكنك رؤية تلقي تلك الحزمة في 2.257324 ثانية. ترى الحزمة يجري
تم تكراره مرة أخرى عند 2.257324 ثانية في التفريغ الثاني، وأخيرًا، ترى الحزمة قيد التشغيل
تم استلامه مرة أخرى لدى العميل في التفريغ الأول في 2.514648 ثانية.

القراءة الناتج مع يريشارك
إذا لم تكن معتادًا على استخدام Wireshark، فهناك موقع ويب متاح يمكنك من خلاله القيام بذلك
تحميل البرامج والوثائق: http://www.wireshark.org/.

Wireshark عبارة عن واجهة مستخدم رسومية يمكن استخدامها لعرض هذه الآثار
ملفات. إذا كان Wireshark متوفرًا لديك، فيمكنك فتح كل ملف من ملفات التتبع وعرضه
المحتويات كما لو كنت قد التقطت الحزم باستخدام ملف حزمة الشم.

BUILDING علوم الهندسة اللاكمية


ابني a باص شبكة طبيعة الكابل
في هذا القسم سنقوم بتوسيع إتقاننا NS-3 أجهزة الشبكة والقنوات ل
تغطية مثال لشبكة الحافلات. NS-3 يوفر جهاز شبكة وقناة نسميها CSMA
(الناقل بمعنى الوصول المتعدد).

إنّ NS-3 يقوم جهاز CSMA بتصميم شبكة بسيطة بروح الإيثرنت. إيثرنت حقيقي
يستخدم نظام CSMA/CD (الوصول المتعدد لتحسس الناقل مع اكتشاف التصادم) مع
زيادة التراجع بشكل كبير للتنافس على وسيط النقل المشترك. ال NS-3
أجهزة CSMA ونماذج القنوات ليست سوى مجموعة فرعية من هذا.

تمامًا كما رأينا كائنات مساعدة طوبولوجية من نقطة إلى نقطة عند الإنشاء
طبولوجيا من نقطة إلى نقطة، سنرى مساعدين مكافئين لطوبولوجيا CSMA في هذا القسم.
يجب أن يبدو مظهر هؤلاء المساعدين وعملهم مألوفًا تمامًا بالنسبة لك.

نحن نقدم مثالًا للبرنامج النصي في دليل الأمثلة/البرنامج التعليمي}. هذا البرنامج النصي يعتمد على
هيه first.cc البرنامج النصي ويضيف شبكة CSMA إلى المحاكاة من نقطة إلى نقطة التي قمنا بها بالفعل
يعتبر. المضي قدما وفتح أمثلة / البرنامج التعليمي / Second.cc في محررك المفضل أنت
سوف يكون قد رأى بالفعل ما يكفي NS-3 رمز لفهم معظم ما يجري في هذا
على سبيل المثال، لكننا سنراجع النص بأكمله ونفحص بعضًا من المخرجات.

تماما كما في first.cc مثال (وفي جميع أمثلة ns-3) يبدأ الملف بـ emacs
خط الوضع وبعض GPL المعياري.

يبدأ الكود الفعلي بتحميل الوحدة النمطية التي تتضمن الملفات تمامًا كما حدث في ملف first.cc
مثال.

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

الشيء الوحيد الذي يمكن أن يكون مفيدًا بشكل مدهش هو جزء صغير من فن ASCII الذي يعرض رسمًا كاريكاتوريًا
لطوبولوجيا الشبكة التي تم إنشاؤها في المثال. ستجد "رسمًا" مشابهًا في
معظم الأمثلة لدينا.

في هذه الحالة، يمكنك أن ترى أننا سنقوم بتوسيع مثالنا من نقطة إلى نقطة (الرابط
بين العقدتين n0 وn1 أدناه) عن طريق تعليق شبكة الحافلات من الجانب الأيمن. يلاحظ
أن هذه هي طوبولوجيا الشبكة الافتراضية حيث يمكنك بالفعل تغيير عدد العقد
تم إنشاؤها على الشبكة المحلية. إذا قمت بتعيين nCsma على واحدة، فسيكون هناك إجمالي عقدتين على
LAN (قناة CSMA) --- عقدة واحدة مطلوبة وعقدة "إضافية" واحدة. بشكل افتراضي هناك ثلاثة
العقد "الإضافية" كما هو موضح أدناه:

// طوبولوجيا الشبكة الافتراضية
//
/ / 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// نقطة إلى نقطة | | | |
// ============
// لان 10.1.2.0

ثم مساحة الاسم ns-3 هي مستعمل ويتم تعريف مكون التسجيل. هذا هو كل شيء تماما كما
كان فيه first.cc، لذلك لا يوجد شيء جديد حتى الآن.

باستخدام مساحة الاسم ns3 ؛

NS_LOG_COMPONENT_DEFINE ("SecondScriptExample")؛

يبدأ البرنامج الرئيسي بتطور مختلف قليلاً. نحن نستخدم علامة مطولة ل
تحديد ما إذا كان UdpEchoClientApplication UdpEchoServerApplication تسجيل
تم تمكين المكونات. هذه العلامة الافتراضية هي صحيح (يتم تمكين مكونات التسجيل)
ولكنه يسمح لنا بإيقاف تشغيل التسجيل أثناء اختبار الانحدار لهذا المثال.

سترى بعض التعليمات البرمجية المألوفة التي ستسمح لك بتغيير عدد الأجهزة الموجودة على
شبكة CSMA عبر وسيطة سطر الأوامر. لقد فعلنا شيئًا مشابهًا عندما سمحنا لـ
عدد الحزم المرسلة للتغيير في القسم الخاص لوسائط سطر الأوامر. الاخير
يتأكد الخط من أن لديك عقدة "إضافية" واحدة على الأقل.

يتكون الكود من أشكال مختلفة لواجهة برمجة التطبيقات (API) التي تمت تغطيتها مسبقًا، لذا يجب أن تكون كذلك بالكامل
مريح مع الكود التالي في هذه المرحلة من البرنامج التعليمي.

منطقي مطول = صحيح؛
uint32_t nCsma = 3;

CommandLine كمد ؛
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 : نكسما؛

الخطوة التالية هي إنشاء عقدتين سنقوم بتوصيلهما عبر رابط نقطة إلى نقطة.
إنّ 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
وقم بتعيين الإعداد الافتراضي المرتبط السمات حتى نتمكن من إنشاء خمسة ميغابت في الثانية
جهاز الإرسال على الأجهزة التي تم إنشاؤها باستخدام المساعد وتأخير XNUMX مللي ثانية على القنوات
تم إنشاؤها بواسطة المساعد.

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5 ميجا بت في الثانية"))؛
pointToPoint.SetChannelAttribute ("Delay"، StringValue ("2ms"))؛

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

نقوم بعد ذلك بإنشاء مثيل لـ a NetDeviceContainer لتتبع أجهزة الشبكة من نقطة إلى نقطة
و نحن تثبيت الأجهزة على العقد من نقطة إلى نقطة.

لقد ذكرنا أعلاه أنك ستشاهد مساعدًا لأجهزة وقنوات CSMA، و
السطور التالية تعرفهم. ال com.CsmaHelper يعمل تماما مثل PointToPointHelper، لكن
يقوم بإنشاء وربط أجهزة وقنوات CSMA. في حالة جهاز CSMA و
زوج القنوات، لاحظ أن معدل البيانات محدد بواسطة أ قناة السمة بدلا من
جهاز السمة. وذلك لأن شبكة CSMA الحقيقية لا تسمح لأحد بالاختلاط
على سبيل المثال، أجهزة 10Base-T و100Base-T على قناة معينة. قمنا أولاً بتعيين معدل البيانات على
100 ميغابت في الثانية، ثم اضبط تأخير سرعة الضوء للقناة على 6560
نانو ثانية (يتم اختيارها بشكل عشوائي على أنها 1 نانو ثانية لكل قدم على قطعة طولها 100 متر).
لاحظ أنه يمكنك تعيين السمة باستخدام نوع البيانات الأصلي الخاص به.

CsmaHelper csma;
csma.SetChannelAttribute ("DataRate"، StringValue ("100 ميجابت في الثانية"))؛
csma.SetChannelAttribute ("Delay"، TimeValue (NanoSeconds (6560)))؛

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

تماما كما أنشأنا NetDeviceContainer للاحتفاظ بالأجهزة التي تم إنشاؤها بواسطة
PointToPointHelper نخلق NetDeviceContainer لعقد الأجهزة التي أنشأتها لدينا
com.CsmaHelper. نحن نسمي تثبيت طريقة com.CsmaHelper لتثبيت الأجهزة في
عقد com.csmaNodes NodeContainer.

لقد تم الآن إنشاء العقد والأجهزة والقنوات الخاصة بنا، لكن ليس لدينا مجموعات بروتوكولات
حاضر. تماما كما في first.cc البرنامج النصي، سوف نستخدم InternetStackHelper لتثبيت
هذه الأكوام.

مكدس InternetStackHelper؛
Stack.Install (p2pNodes.Get (0));
Stack.Install (csmaNodes);

تذكر أننا أخذنا إحدى العقد من p2pNodes الحاوية وإضافتها إلى
com.csmaNodes حاوية. وبالتالي نحتاج فقط إلى تثبيت الأكوام على الباقي p2pNodes
العقدة، وجميع العقد في com.csmaNodes حاوية لتغطية كافة العقد في
محاكاة.

تماما كما في first.cc مثال على البرنامج النصي، سوف نستخدم IPv4AddressHelper إلى
تعيين عناوين IP لواجهات أجهزتنا. أولاً نستخدم الشبكة 10.1.1.0 للإنشاء
العنوانين اللازمين لجهازي الاتصال من نقطة إلى نقطة.

عنوان Ipv4AddressHelper؛
عنوان.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 في هذه الحالة، كما هو موضح أدناه.

عنوان.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 (Seconds (1.0));
serverApps.Stop (ثواني (10.0))؛

أذكر أن com.csmaNodes NodeContainer يحتوي على إحدى العقد التي تم إنشاؤها لـ
شبكة من نقطة إلى نقطة و nCsma العقد "الإضافية". ما نريد الوصول إليه هو الأخير
العقد "الإضافية". الدخول الصفري لل com.csmaNodes ستكون الحاوية من نقطة إلى نقطة
العقدة. الطريقة السهلة للتفكير في هذا الأمر هي إذا قمنا بإنشاء عقدة CSMA "إضافية" واحدة، فستكون كذلك
سيكون في الفهرس واحد من com.csmaNodes حاوية. بالاستقراء إذا خلقنا nCsma "إضافي"
العقد الأخيرة ستكون في الفهرس nCsma. ترى هذا معروضا في تواصل من أول
سطر من التعليمات البرمجية.

تم إعداد تطبيق العميل تمامًا كما فعلنا في first.cc مثال البرنامج النصي. مرة أخرى،
نحن نقدم المطلوبة السمات إلى UdpEchoClientHelper في المنشئ (في هذه الحالة
العنوان البعيد والمنفذ). نطلب من العميل إرسال الحزم إلى الخادم الذي نريده فقط
مثبتة على آخر عقد CSMA "الإضافية". نقوم بتثبيت العميل في أقصى اليسار
عقدة من نقطة إلى نقطة تظهر في الرسم التوضيحي للطوبولوجيا.

UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma)، 9)؛
echoClient.SetAttribute ("MaxPackets"، UintegerValue (1))؛
echoClient.SetAttribute ("Interval"، TimeValue (Seconds (1.0)))؛
echoClient.SetAttribute ("PacketSize"، UintegerValue (1024))؛

ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
ClientApps.Start (ثواني (2.0))؛
ClientApps.Stop (Seconds (10.0));

وبما أننا قمنا بالفعل ببناء شبكة بينية هنا، فإننا بحاجة إلى شكل من أشكال الشبكات البينية
التوجيه. NS-3 يوفر ما نسميه التوجيه العالمي لمساعدتك. يأخذ التوجيه العالمي
الاستفادة من حقيقة أن الشبكة البينية بأكملها يمكن الوصول إليها في المحاكاة و
يمر عبر جميع العقد التي تم إنشاؤها للمحاكاة --- فهو يقوم بالعمل الشاق
إعداد التوجيه لك دون الحاجة إلى تكوين أجهزة التوجيه.

في الأساس، ما يحدث هو أن كل عقدة تتصرف كما لو كانت موجه OSPF
يتواصل بشكل فوري وبطريقة سحرية مع جميع أجهزة التوجيه الأخرى خلف الكواليس. كل عقدة
يقوم بإنشاء إعلانات الارتباط وتوصيلها مباشرة إلى مدير الطريق العالمي
والذي يستخدم هذه المعلومات العامة لإنشاء جداول التوجيه لكل عقدة. جلسة
هذا النوع من التوجيه عبارة عن بطانة واحدة:

Ipv4GlobalRoutingHelper::PopulateRoutingTables();

بعد ذلك نقوم بتمكين تتبع PCAP. السطر الأول من التعليمات البرمجية لتمكين تتبع PCAP في ملف
يجب أن يكون المساعد من نقطة إلى نقطة مألوفًا لك الآن. السطر الثاني يمكّن PCAP
التتبع في مساعد CSMA وهناك معلمة إضافية لم تواجهها بعد.

pointToPoint.EnablePcapAll ("الثانية") ،
csma.EnablePcap ("الثانية"، csmaDevices.Get (1)، صحيح)؛

شبكة CSMA هي شبكة متعددة النقاط. وهذا يعني أنه يمكن (وهناك
في هذه الحالة) نقاط نهاية متعددة على وسيط مشترك. كل نقطة من نقاط النهاية هذه لديها شبكة
الجهاز المرتبط به. هناك نوعان من البدائل الأساسية لجمع الأثر
المعلومات من مثل هذه الشبكة. إحدى الطرق هي إنشاء ملف تتبع لكل جهاز إنترنت
وتخزين فقط الحزم التي يصدرها أو يستهلكها جهاز الشبكة هذا. طريق اخر
هو اختيار أحد الأجهزة ووضعه في الوضع المختلط. هذا الجهاز الوحيد إذن
"يشم" الشبكة لجميع الحزم ويخزنها في ملف pcap واحد. هذه هي الطريقة
com.tcpdump، على سبيل المثال، يعمل. تخبر هذه المعلمة النهائية مساعد CSMA ما إذا كان سيتم ذلك أم لا
الترتيب لالتقاط الحزم في الوضع المختلط.

في هذا المثال، سنقوم باختيار أحد الأجهزة الموجودة على شبكة CSMA ونطلب منه ذلك
لإجراء شم غير شرعي للشبكة، وبالتالي محاكاة ما com.tcpdump ستفعل.
إذا كنت تستخدم جهاز Linux، فقد تفعل شيئًا مثل com.tcpdump -i eth0 للحصول على
يتعقب. في هذه الحالة، نحدد الجهاز الذي يستخدمه csmaDevices.Get(1)، والذي يحدد ملف
الجهاز الأول في الحاوية. يؤدي تعيين المعلمة النهائية إلى صحيح إلى تمكين الاختلاط
يلتقط.

يتم تشغيل القسم الأخير من التعليمات البرمجية وتنظيف المحاكاة تمامًا مثل first.cc
مثال.

محاكي :: تشغيل () ؛
جهاز محاكاة :: تدمير () ؛
0 العودة؛
}

لتشغيل هذا المثال، انسخ ملف Second.cc مثال على البرنامج النصي في دليل الصفر
واستخدم waf للبناء تمامًا كما فعلت مع ملف first.cc مثال. إذا كنت في
دليل المستوى الأعلى للمستودع الذي كتبته للتو،

أمثلة $ cp/tutorial/ Second.cc Scratch/mySecond.cc
$ ./واف

تحذير: نحن نستخدم الملف Second.cc كواحد من اختبارات الانحدار لدينا للتحقق من أنه يعمل
تمامًا كما نعتقد أنه ينبغي أن نجعل تجربتك التعليمية تجربة إيجابية.
وهذا يعني أن الملف القابل للتنفيذ المسمى ثان موجود بالفعل في المشروع. لتجنب أي
هناك ارتباك حول ما تقوم بتنفيذه، يرجى إجراء إعادة التسمية إلى mySecond.cc اقترح
في الاعلى.

إذا كنت تتابع البرنامج التعليمي دينيًا (أنت كذلك، أليس كذلك) فلا يزال لديك
مجموعة المتغيرات NS_LOG، لذا قم بمسح هذا المتغير وتشغيل البرنامج.

$ تصدير NS_LOG=
$ ./waf --تشغيل الصفر/mySecond

نظرًا لأننا قمنا بإعداد تطبيقات صدى UDP لتسجيل الدخول تمامًا كما فعلنا 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.415 ثانية)
تم إرسال 1024 بايت إلى 10.1.2.4
تم استلام 1024 بايت من 10.1.1.1
تم استلام 1024 بايت من 10.1.2.4

أذكر أن الرسالة الأولى، "أرسلت 1024 بايت إلى 10.1.2.4"، هو عميل صدى UDP
إرسال حزمة إلى الخادم. في هذه الحالة، الخادم موجود على شبكة مختلفة
(10.1.2.0). الرسالة الثانية "تم الاستلام 1024 بايت تبدأ من 10.1.1.1"، من صدى UDP
الخادم، الذي يتم إنشاؤه عندما يتلقى حزمة الصدى. الرسالة الاخيرة "تم الاستلام 1024
بايت تبدأ من 10.1.2.4"، من عميل الصدى، مما يشير إلى أنه تلقى الصدى الخاص به
العودة من الخادم.

إذا ذهبت الآن وبحثت في دليل المستوى الأعلى، فستجد ثلاثة ملفات تتبع:

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

دعونا نتوقف لحظة لننظر إلى تسمية هذه الملفات. كلهم نفس الشكل
- - .pcap. على سبيل المثال، الملف الأول في القائمة هو
ثانية-0-0.pcap وهو تتبع PCAP من العقدة صفر، الجهاز صفر. هذا ال
جهاز شبكة من نقطة إلى نقطة على العقدة صفر. الملف ثانية-1-0.pcap هو تتبع PCAP ل
الجهاز صفر على العقدة الأولى، وهو أيضًا جهاز شبكة من نقطة إلى نقطة؛ والملف ثانية-2-0.pcap is
تتبع PCAP للجهاز صفر على العقدة الثانية.

إذا رجعت إلى الرسم التوضيحي للطوبولوجيا في بداية القسم، فسوف ترى
تلك العقدة صفر هي العقدة الموجودة في أقصى يسار الارتباط من نقطة إلى نقطة والعقدة الأولى هي العقدة
يحتوي على جهاز نقطة إلى نقطة وجهاز CSMA. سترى أن العقدة الثانية هي
تم اختيار العقدة "الإضافية" الأولى على شبكة CSMA وجهازها صفر كجهاز
لالتقاط أثر الوضع المختلط.

الآن، دعونا نتبع حزمة الصدى من خلال الشبكة البينية. أولاً، قم بإجراء tcpdump لملف
ملف التتبع للعقدة في أقصى اليسار من نقطة إلى نقطة --- العقدة صفر.

$ 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

يشير السطر الأول من التفريغ إلى أن نوع الارتباط هو PPP (من نقطة إلى نقطة) وهو ما نقوم به
يتوقع. ستشاهد بعد ذلك حزمة الصدى التي تترك العقدة صفر عبر الجهاز المرتبط بـ IP
العنوان 10.1.1.1 متجه إلى عنوان IP 10.1.2.4 (عقدة CSMA الموجودة في أقصى اليمين). هذه الحزمة
سيتحرك عبر الرابط من نقطة إلى نقطة وسيتم استقباله بواسطة جهاز الشبكة من نقطة إلى نقطة
العقدة الأولى. لنلقي نظرة:

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

ينبغي أن تشاهد الآن مخرجات تتبع pcap على الجانب الآخر من الارتباط من نقطة إلى نقطة:

القراءة من الملف Second-1-0.pcap، PPP من نوع الارتباط (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، الطول 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، الطول 1024

نرى هنا أن نوع الارتباط هو أيضًا PPP كما نتوقع. ترى الحزمة من IP
العنوان 10.1.1.1 (الذي تم إرساله خلال 2.000000 ثانية) يتجه نحو عنوان IP 10.1.2.4
تظهر على هذه الواجهة الآن، داخليًا إلى هذه العقدة، سيتم إعادة توجيه الحزمة إليها
واجهة CSMA ويجب أن نراها تنبثق على هذا الجهاز متجهة إلى نهايتها
الوجهة.

تذكر أننا اخترنا العقدة 2 لتكون عقدة الشم غير الشرعية لشبكة CSMA
دعونا نلقي نظرة على Second-2-0.pcap ونرى ما إذا كان موجودًا هناك.

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

يجب أن تشاهد الآن التفريغ غير الشرعي للعقدة الثانية، الجهاز صفر:

القراءة من الملف Second-2-0.pcap، نوع الارتباط EN10MB (Ethernet)
2.007698 ARP، طلب من لديه 10.1.2.4 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.1، الطول 50
2.007710 ARP، الرد 10.1.2.4 موجود في 00:00:00:00:00:06، الطول 50
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP، الطول 1024
2.013815 ARP، طلب من لديه 10.1.2.1 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.4، الطول 50
2.013828 ARP، الرد 10.1.2.1 موجود في 00:00:00:00:00:03، الطول 50
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP، الطول 1024

كما ترى، أصبح نوع الرابط الآن "Ethernet". ومع ذلك، فقد ظهر شيء جديد. ال
احتياجات شبكة الحافلات ARP، بروتوكول تحليل العنوان. عقدة أحد يعرف أنه يحتاج إلى إرسال
الحزمة إلى عنوان 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. لاحظ أن العقدة الثانية ليست متورطة بشكل مباشر في هذا
Exchange، ولكنه يتعرف على الشبكة ويبلغ عن كل حركة المرور التي يراها.

ونرى هذا التبادل في السطور التالية،

2.007698 ARP، طلب من لديه 10.1.2.4 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.1، الطول 50
2.007710 ARP، الرد 10.1.2.4 موجود في 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، لذا يجب عليها استخدام ARP لها تمامًا كما كان على عقدة CSMA الأولى أن تفعل.

2.013815 ARP، طلب من لديه 10.1.2.1 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.4، الطول 50
2.013828 ARP، الرد 10.1.2.1 موجود في 00:00:00:00:00:03، الطول 50

ثم يرسل الخادم الصدى مرة أخرى إلى عقدة إعادة التوجيه.

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

إذا نظرنا إلى الوراء إلى العقدة الموجودة في أقصى اليمين للارتباط من نقطة إلى نقطة،

$ 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/mysec --nCsma=4"

يجب أن ترى الآن،

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.405 ثانية)
في الوقت 2s، أرسل العميل 1024 بايت إلى المنفذ 10.1.2.5 9
في الوقت المناسب، تلقى خادم 2.0118s 1024 بايت من المنفذ 10.1.1.1 رقم 49153
في الوقت المناسب، أرسل خادم 2.0118s 1024 بايت إلى المنفذ 10.1.1.1 رقم 49153
في الوقت 2.02461 تلقى العميل 1024 بايت من المنفذ 10.1.2.5 9

لاحظ أنه تم الآن نقل خادم الصدى إلى آخر عقد CSMA، وهي
10.1.2.5 بدلاً من الحالة الافتراضية، 10.1.2.4.

من الممكن ألا تكون راضيًا عن ملف التتبع الذي أنشأه أحد المارة
شبكة CSMA قد ترغب حقًا في الحصول على تتبع من جهاز واحد، وقد لا ترغب بذلك
تكون مهتمة بأي حركة مرور أخرى على الشبكة. يمكنك القيام بذلك بسهولة إلى حد ما.

دعنا نلقي نظرة على الصفر/my Second.cc وأضف هذا الكود الذي يمكننا من أن نكون أكثر
محدد. NS-3 يوفر المساعدون طرقًا تأخذ رقم العقدة ورقم الجهاز
حدود. المضي قدما واستبدال تمكينPcap المكالمات مع المكالمات أدناه.

pointToPoint.EnablePcap ("second"، p2pNodes.Get (0) -> GetId ()، 0) ؛
csma.EnablePcap ("الثانية"، csmaNodes.Get (nCsma)->GetId ()، 0، false)؛
csma.EnablePcap ("الثانية"، csmaNodes.Get (nCsma-1)->GetId ()، 0، false)؛

نحن نعلم أننا نريد إنشاء ملف pcap بالاسم الأساسي "الثاني" ونعلم أيضًا
أن الجهاز محل الاهتمام في كلتا الحالتين سيكون صفرًا، لذا فإن هذه المعلمات ليست كذلك
مثيرة للاهتمام حقا.

من أجل الحصول على رقم العقدة، لديك خياران: أولا، يتم ترقيم العقد في
زيادة الموضة بشكل رتيب بدءًا من الصفر بالترتيب الذي قمت بإنشائه
هم. إحدى الطرق للحصول على رقم العقدة هي معرفة هذا الرقم "يدويًا".
التفكير في ترتيب إنشاء العقدة. إذا ألقيت نظرة على طوبولوجيا الشبكة
في الرسم التوضيحي الموجود في بداية الملف، قمنا بهذا من أجلك ويمكنك أن ترى أن ملف
آخر عقدة CSMA ستكون رقم العقدة nCsma + 1. يمكن أن يصبح هذا النهج مزعجًا
من الصعب في عمليات المحاكاة الأكبر.

والطريقة البديلة التي نستخدمها هنا هي أن ندرك أن NodeContainers تحتوي على
مؤشرات ل NS-3 العقدة أشياء. ال العقدة الكائن لديه طريقة تسمى معرف_جيت والتي سوف
قم بإرجاع معرف تلك العقدة، وهو رقم العقدة الذي نسعى إليه. دعنا نذهب لنلقي نظرة على
دوكسيجين ل العقدة وتحديد موقع هذه الطريقة، والتي هي أبعد من ذلك في NS-3 الكود الأساسي
مما رأيناه حتى الآن؛ ولكن في بعض الأحيان يتعين عليك البحث بجد عن الأشياء المفيدة.

انتقل إلى وثائق Doxygen الخاصة بإصدارك (تذكر أنه يمكنك العثور عليها على
موقع المشروع على شبكة الإنترنت). يمكنك الوصول إلى العقدة التوثيق من خلال النظر في
علامة التبويب "الفصول" ثم قم بالتمرير لأسفل في "قائمة الفئات" حتى تجدها ns3 :: عقدة. حدد
ns3 :: عقدة وسيتم نقلك إلى الوثائق الخاصة بـ العقدة فصل. إذا كنت الآن
قم بالتمرير لأسفل إلى معرف_جيت الطريقة واختيارها، سيتم نقلك إلى التفاصيل
وثائق للطريقة. باستخدام معرف_جيت يمكن أن تحدد الطريقة أرقام العقدة
أسهل بكثير في الطبولوجيا المعقدة.

لنقم بمسح ملفات التتبع القديمة من دليل المستوى الأعلى لتجنب حدوث أي ارتباك بشأنها
ما الذي يجري،

$ rm *.pcap
$ rm *.tr

إذا قمت بإنشاء البرنامج النصي الجديد وتشغيل إعداد المحاكاة nCsma إلى شنومكس،

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

سترى الإخراج التالي:

Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
انتهى "البناء" بنجاح (0.407 ثانية)
في الوقت 2s، أرسل العميل 1024 بايت إلى المنفذ 10.1.2.101 9
في الوقت المناسب، تلقى خادم 2.0068s 1024 بايت من المنفذ 10.1.1.1 رقم 49153
في الوقت المناسب، أرسل خادم 2.0068s 1024 بايت إلى المنفذ 10.1.1.1 رقم 49153
في الوقت 2.01761 تلقى العميل 1024 بايت من المنفذ 10.1.2.101 9

لاحظ أن خادم الصدى موجود الآن على 10.1.2.101 وهو ما يتوافق مع وجود 100
عقد CSMA "الإضافية" مع خادم الصدى في العقدة الأخيرة. إذا قمت بإدراج ملفات pcap في
دليل المستوى الأعلى الذي ستراه،

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

ملف التتبع ثانية-0-0.pcap هو جهاز نقطة إلى نقطة "أقصى اليسار" وهو الصدى
مصدر الحزمة. الملف ثانية-101-0.pcap يتوافق مع جهاز CSMA الموجود في أقصى اليمين
هو المكان الذي يوجد فيه خادم الصدى. ربما لاحظت أن المعلمة النهائية على
كان الاتصال لتمكين تتبع PCAP على عقدة خادم الصدى خطأ. وهذا يعني أن التتبع
المتجمعة على تلك العقدة كانت في وضع غير مختلط.

لتوضيح الفرق بين الآثار غير المختلطة وغير المختلطة، نحن أيضا
طلب تتبعًا غير مختلط للعقدة التالية للأخيرة. المضي قدما ونلقي نظرة على
هيه com.tcpdump لـ ثانية-100-0.pcap.

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

يمكنك الآن أن ترى أن العقدة 100 هي بالفعل متفرج في تبادل الصدى. الوحيد
الحزم التي يتلقاها هي طلبات ARP التي يتم بثها إلى CSMA بأكمله
شبكة.

القراءة من الملف Second-100-0.pcap، نوع الارتباط EN10MB (Ethernet)
2.006698 ARP، طلب من لديه 10.1.2.101 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.1، الطول 50
2.013815 ARP، طلب من لديه 10.1.2.1 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.101، الطول 50

الآن نلقي نظرة على com.tcpdump لـ ثانية-101-0.pcap.

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

يمكنك الآن أن ترى أن العقدة 101 هي بالفعل المشاركة في تبادل الصدى.

القراءة من الملف Second-101-0.pcap، نوع الارتباط EN10MB (Ethernet)
2.006698 ARP، طلب من لديه 10.1.2.101 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.1، الطول 50
2.006698 ARP، الرد 10.1.2.101 موجود في 00:00:00:00:00:67، الطول 50
2.006803 IP 10.1.1.1.49153 > 10.1.2.101.9: UDP، الطول 1024
2.013803 ARP، طلب من لديه 10.1.2.1 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.101، الطول 50
2.013828 ARP، الرد 10.1.2.1 موجود في 00:00:00:00:00:03، الطول 50
2.013828 IP 10.1.2.101.9 > 10.1.1.1.49153: UDP، الطول 1024

عارضات ازياء، السمات واقع
هذا مكان مناسب للقيام برحلة صغيرة وتوضيح نقطة مهمة. ممكن
أو قد لا يكون ذلك واضحًا بالنسبة لك، ولكن عندما يستخدم أحد المحاكاة، فمن المهم أن تفعل ذلك
فهم بالضبط ما يتم تصميمه وما هو ليس كذلك. ومن المغري، على سبيل المثال، أن
فكر في أجهزة وقنوات CSMA المستخدمة في القسم السابق كما لو كانت حقيقية
أجهزة إيثرنت؛ وتوقع أن تعكس نتيجة المحاكاة بشكل مباشر ما سيحدث
في إيثرنت حقيقي. ليست هذه هي القضية.

النموذج، بحكم تعريفه، هو تجريد للواقع. إنها المسؤولية في نهاية المطاف
لمؤلف نص المحاكاة لتحديد ما يسمى بـ "نطاق الدقة" و"المجال
إمكانية تطبيق" المحاكاة ككل، وبالتالي الأجزاء المكونة لها.

في بعض الحالات مثل Csma، قد يكون من السهل إلى حد ما تحديد ما هو ليس على غرار. بواسطة
قراءة وصف النموذج (csma.h) يمكنك أن تجد أنه لا يوجد كشف الاصطدام
في نموذج CSMA وتحديد مدى قابلية تطبيقه في المحاكاة الخاصة بك أم ماذا
التحذيرات التي قد ترغب في تضمينها مع نتائجك. وفي حالات أخرى، يمكن أن يكون الأمر سهلاً للغاية
لتكوين سلوكيات قد لا تتفق مع أي واقع يمكنك الخروج وشراؤه. هو - هي
سيكون من المفيد قضاء بعض الوقت في التحقيق في بعض هذه الحالات، وكيف
يمكنك بسهولة الانحراف خارج حدود الواقع في عمليات المحاكاة الخاصة بك.

كما رأيتم، NS-3 ويوفر السمات والتي يمكن للمستخدم ضبطها بسهولة لتغيير النموذج
سلوك. النظر في اثنين من السمات ل جهاز CsmaNet: MTU
وضع التغليف. MTU تشير السمة إلى الحد الأقصى لوحدة النقل إلى
جهاز. هذا هو حجم أكبر وحدة بيانات بروتوكول (PDU) يستطيع الجهاز القيام بها
يرسل.

يبلغ حجم MTU الافتراضي 1500 بايت في ملف جهاز CsmaNet. هذا الافتراضي يتوافق مع رقم
تم العثور عليه في RFC 894، "معيار لنقل مخططات بيانات IP عبر الإيثرنت
الشبكات." الرقم مشتق فعليًا من الحد الأقصى لحجم الحزمة لـ 10Base5
شبكات (إيثرنت كاملة المواصفات) - 1518 بايت. إذا قمت بطرح تغليف DIX
الحمل الزائد لحزم Ethernet (18 بايت) سينتهي بك الأمر بأقصى حجم ممكن للبيانات
(MTU) 1500 بايت. يمكن للمرء أيضًا أن يجد أن MTU لشبكات IEEE 802.3 هو 1492
بايت. وذلك لأن تغليف LLC/SNAP يضيف ثمانية بايت إضافية من الحمل إلى
الحزمة. في كلتا الحالتين، يمكن للأجهزة الأساسية إرسال 1518 بايت فقط، ولكن البيانات
الحجم مختلف.

من أجل ضبط وضع التغليف، جهاز CsmaNet يوفر السمة تسمى
وضع التغليف والتي يمكن أن تأخذ على القيم ديكس or ذ. هذه تتوافق مع إيثرنت
وتأطير LLC/SNAP على التوالي.

إذا ترك أحد MTU عند 1500 بايت ويغير وضع التغليف إلى ذ، النتيجة
ستكون عبارة عن شبكة تحتوي على 1500 بايت من وحدات PDU مع تأطير LLC/SNAP مما يؤدي إلى
حزم من 1526 بايت، والتي قد تكون غير قانونية في العديد من الشبكات، حيث أنها يمكن أن تنقل
الحد الأقصى 1518 بايت لكل حزمة. وهذا من شأنه أن يؤدي على الأرجح إلى محاكاة ذلك
بمهارة لا تعكس الواقع الذي قد تتوقعه.

فقط لتعقيد الصورة، توجد إطارات ضخمة جدًا (1500 < MTU <= 9000 بايت) و
الإطارات فائقة الجامبو (MTU > 9000 بايت) التي لم يتم اعتمادها رسميًا بواسطة IEEE ولكنها
متوفر في بعض الشبكات عالية السرعة (Gigabit) وبطاقات NIC. يمكن للمرء أن يترك
تم ضبط وضع التغليف على ديكس، واضبط MTU السمة على جهاز CsmaNet إلى 64000 بايت
-- على الرغم من أنه مرتبط قناة CsmaChannel معدل البيانات تم ضبطه على 10 ميغابت في الثانية. هذا
من شأنه أن يصمم بشكل أساسي محول إيثرنت مصنوعًا من طراز 1980Base10 الذي تم استغلاله من قبل مصاصي الدماء في الثمانينيات
الشبكات التي تدعم مخططات البيانات الضخمة. وهذا بالتأكيد ليس شيئًا كان
لم يتم تصنيعها على الإطلاق، ومن غير المرجح أن يتم تصنيعها على الإطلاق، ولكن من السهل جدًا عليك تهيئتها.

في المثال السابق، استخدمت سطر الأوامر لإنشاء محاكاة تحتوي على 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 متى
بناء طبولوجيا من نقطة إلى نقطة، وسوف نرى ما يعادلها واي فاي مساعدين طوبولوجيا في
هذا القسم. يجب أن يبدو مظهر هؤلاء المساعدين وعملهم مألوفًا تمامًا
أنت.

نحن نقدم مثالا على البرنامج النصي في منطقتنا أمثلة / تعليمي الدليل. هذا البرنامج النصي يعتمد على
هيه Second.cc البرنامج النصي ويضيف شبكة Wifi. المضي قدما وفتح
أمثلة/البرنامج التعليمي/third.cc في محررك المفضل سوف تكون قد رأيت بالفعل ما يكفي
NS-3 رمز لفهم معظم ما يجري في هذا المثال، ولكن هناك عدد قليل من الجديد
الأشياء، لذلك سوف نراجع النص بأكمله ونفحص بعض المخرجات.

تماما كما في Second.cc مثال (وفي الكل NS-3 أمثلة) يبدأ الملف بـ emacs
خط الوضع وبعض GPL المعياري.

ألقِ نظرة على رسم ASCII (المستنسخ أدناه) والذي يُظهر طوبولوجيا الشبكة الافتراضية
بنيت في المثال. يمكنك أن ترى أننا سنقوم بتوسيع مثالنا
عن طريق تعليق شبكة لاسلكية من الجانب الأيسر. لاحظ أن هذه هي الشبكة الافتراضية
الطوبولوجيا حيث يمكنك في الواقع تغيير عدد العقد التي تم إنشاؤها على السلكية واللاسلكية
الشبكات. تماما كما في Second.cc حالة البرنامج النصي، إذا قمت بتغيير nCsma، سوف يعطيك
عدد عقد CSMA "الإضافية". وبالمثل، يمكنك تعيين nWifi للتحكم في كم S
يتم إنشاء العقد (المحطة) في المحاكاة. سيكون هناك دائما واحد AP (نقطة دخول)
عقدة على الشبكة اللاسلكية. بشكل افتراضي هناك ثلاث عقد CSMA "إضافية" وثلاثة
لاسلكي S العقد.

يبدأ الكود بتحميل الوحدة النمطية التي تتضمن الملفات تمامًا كما حدث في ملف Second.cc مثال.
هناك بعض الإضافات الجديدة المتوافقة مع وحدة Wifi وإمكانية التنقل
الوحدة التي سنناقشها أدناه.

# تضمين "ns3 / core-module.h"
# تضمين "ns3 / point-to-point-module.h"
# تضمين "ns3 / network-module.h"
#include "ns3 / applications-module.h"
#تتضمن "ns3/wifi-module.h"
#تتضمن "ns3/mobility-module.h"
#تتضمن "ns3/csma-module.h"
# تضمين "ns3 / internet-module.h"

فيما يلي الرسم التوضيحي لطوبولوجيا الشبكة:

// طوبولوجيا الشبكة الافتراضية
//
// واي فاي 10.1.3.0
// ا ف ب
// * * * *
// | | | | 10.1.1.0
// n5 n6 n7 n0 -------------- n1 n2 n3 n4
// نقطة إلى نقطة | | | |
// ============
// لان 10.1.2.0

يمكنك أن ترى أننا نضيف جهاز شبكة جديدًا إلى العقدة الموجودة على الجانب الأيسر من
ارتباط من نقطة إلى نقطة يصبح نقطة الوصول للشبكة اللاسلكية. عدد من
يتم إنشاء عقد STA اللاسلكية لملء شبكة 10.1.3.0 الجديدة كما هو موضح على اليسار
جانب من الرسم التوضيحي

بعد الرسم التوضيحي، NS-3 مساحة الاسم هي مستعمل ويتم تعريف مكون التسجيل.
يجب أن يكون كل هذا مألوفًا تمامًا الآن.

باستخدام مساحة الاسم ns3 ؛

NS_LOG_COMPONENT_DEFINE ("مثال النص الثالث")؛

يبدأ البرنامج الرئيسي تماما مثل Second.cc عن طريق إضافة بعض معلمات سطر الأوامر لـ
تمكين أو تعطيل مكونات التسجيل ولتغيير عدد الأجهزة التي تم إنشاؤها.

منطقي مطول = صحيح؛
uint32_t nCsma = 3;
uint32_t nWifi = 3;

CommandLine كمد ؛
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 وتعيين المرتبطة
الافتراضي السمات حتى نتمكن من إنشاء جهاز إرسال بسرعة XNUMX ميغابت في الثانية على الأجهزة
تم إنشاؤها باستخدام المساعد وتأخير بمقدار ميلي ثانية على القنوات التي أنشأها المساعد.
نحن ثم كامل الأجهزة الموجودة على العقد والقناة بينها.

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5 ميجا بت في الثانية"))؛
pointToPoint.SetChannelAttribute ("Delay"، StringValue ("2ms"))؛

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

بعد ذلك، نعلن آخر NodeContainer للاحتفاظ بالعقد التي ستكون جزءًا من الحافلة
شبكة (CSMA).

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

السطر التالي من التعليمات البرمجية يحصل العقدة الأولى (كما هو الحال في وجود فهرس واحد) من
حاوية العقدة من نقطة إلى نقطة وإضافتها إلى حاوية العقد التي ستحصل على CSMA
الأجهزة. ستنتهي العقدة المعنية بجهاز نقطة إلى نقطة وCSMA
جهاز. نقوم بعد ذلك بإنشاء عدد من العقد "الإضافية" التي تشكل الجزء المتبقي من CSMA
شبكة.

نقوم بعد ذلك بإنشاء مثيل لـ a com.CsmaHelper وتعيين لها السمات كما فعلنا في المثال السابق.
نقوم بإنشاء ملف NetDeviceContainer لتتبع أجهزة شبكة CSMA التي تم إنشاؤها ثم نقوم بذلك
تثبيت أجهزة CSMA على العقد المحددة.

CsmaHelper csma;
csma.SetChannelAttribute ("DataRate"، StringValue ("100 ميجابت في الثانية"))؛
csma.SetChannelAttribute ("Delay"، TimeValue (NanoSeconds (6560)))؛

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

بعد ذلك، سنقوم بإنشاء العقد التي ستكون جزءًا من شبكة Wifi. نحن
سنقوم بإنشاء عدد من عقد "المحطة" كما هو محدد بواسطة وسيطة سطر الأوامر، و
سنستخدم العقدة "أقصى اليسار" للارتباط من نقطة إلى نقطة كعقدة لـ
نقطة دخول.

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

يقوم الجزء التالي من التعليمات البرمجية ببناء أجهزة wifi وقناة الاتصال البيني بينها
عقد wifi هذه. أولاً، نقوم بتكوين PHY ومساعدي القنوات:

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

للتبسيط، يستخدم هذا الكود تكوين طبقة PHY الافتراضية ونماذج القنوات
والتي تم توثيقها في وثائق API Doxygen لـ
YansWifiChannelHelper::Default YansWifiPhyHelper::Default طُرق. مرة واحدة هذه الكائنات
يتم إنشاؤها، نقوم بإنشاء كائن قناة وربطه بمدير كائن طبقة PHY الخاص بنا
للتأكد من أن كافة كائنات طبقة PHY التي تم إنشاؤها بواسطة YansWifiPhyHelper مشاركة
نفس القناة الأساسية، أي أنها تشترك في نفس الوسيط اللاسلكي ويمكنها ذلك
التواصل والتدخل:

phy.SetChannel (channel.Create ());

بمجرد تكوين مساعد PHY، يمكننا التركيز على طبقة MAC. هنا نختار العمل
مع أجهزة MAC غير التابعة لـ Qos، لذلك نستخدم كائن NqosWifiMacHelper لتعيين معلمات MAC.

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

NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();

إنّ SetRemoteStationManager تخبر الطريقة المساعد بنوع خوارزمية التحكم في المعدل
يستخدم. هنا، يطلب من المساعد استخدام خوارزمية AARF --- التفاصيل بالطبع،
متوفر في دوكسيجين.

بعد ذلك، نقوم بتكوين نوع MAC، وهو SSID لشبكة البنية التحتية التي نريدها
الإعداد والتأكد من أن محطاتنا لا تقوم بإجراء فحص نشط:

Ssid ssid = Ssid ("ns-3-ssid")؛
mac.SetType ("ns3::StaWifiMac"،
"Ssid"، قيمة Ssid (SSID)،
"ActiveProbing"، قيمة منطقية (خطأ))؛

يقوم هذا الرمز أولاً بإنشاء كائن معرف مجموعة الخدمة (SSID) 802.11 الذي سيتم استخدامه
لتعيين قيمة "Ssid" السمة تنفيذ طبقة MAC. على وجه الخصوص
يتم تحديد نوع طبقة MAC التي سيتم إنشاؤها بواسطة المساعد بواسطة السمة باعتباره من
النوع "ns3::StaWifiMac". استخدام NqosWifiMacHelper سيضمن أن
"جودة الخدمة المدعومة" السمة لكائنات MAC التي تم إنشاؤها تم تعيينها على خطأ. مزيج من هذه
يعني التكوينان أن مثيل MAC الذي تم إنشاؤه بعد ذلك سيكون غير مرتبط بجودة الخدمة وغير AP
محطة (STA) في بنية أساسية BSS (أي BSS مع نقطة وصول). وأخيرا، فإن
"الفحص النشط" السمة تم ضبطه على خطأ. وهذا يعني أن طلبات التحقيق لن تكون
تم إرسالها بواسطة أجهزة 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 الذي تم تكوينه كنقطة وصول، مع ملحق
نوع المساعد الذي يشير إلى أن "QosSupported" السمة يجب ضبطه على خطأ - تعطيل
دعم جودة الخدمة بنمط 802.11e/WMM عند نقاط الوصول التي تم إنشاؤها.

تنشئ الأسطر التالية نقطة وصول واحدة تشترك في نفس مجموعة مستوى PHY السمات
القناة) كالمحطات:

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

الآن، سنقوم بإضافة نماذج التنقل. نريد أن تكون عقد STA متنقلة ومتجولة
داخل المربع المحيط، ونريد أن نجعل عقدة AP ثابتة. نحن نستخدم ال
MobilityHelper لجعل هذا سهلا بالنسبة لنا. أولاً، نقوم بإنشاء مثيل أ MobilityHelper موضوع
وتعيين بعض السمات التحكم في وظيفة "مخصص الموضع".

التنقل

التنقل.SetPositionAllocator ("ns3::GridPositionAllocator"،
"مينكس"، قيمة مزدوجة (0.0)،
"ميني"، قيمة مزدوجة (0.0)،
"DeltaX" ، DoubleValue (5.0) ،
"DeltaY" ، DoubleValue (10.0) ،
"GridWidth" ، UintegerValue (3) ،
"LayoutType" ، StringValue ("RowFirst")) ؛

يخبر هذا الرمز مساعد التنقل باستخدام شبكة ثنائية الأبعاد لوضع الملف في البداية
عقد STA. لا تتردد في استكشاف Doxygen للفصل ns3::GridPositionAllocator لمعرفة
بالضبط ما يجري القيام به.

لقد قمنا بترتيب عقدنا على شبكة أولية، ولكن علينا الآن أن نخبرها بكيفية التحرك.
نختار RandomWalk2dMobilityModel الذي تتحرك فيه العقد في اتجاه عشوائي عند
سرعة عشوائية داخل المربع المحيط.

التنقل.SetMobilityModel ("ns3::RandomWalk2dMobilityModel"،
"الحدود"، قيمة المستطيل (المستطيل (-50، 50، -50، 50)))؛

نحن الآن نقول ل MobilityHelper لتثبيت نماذج التنقل على عقد STA.

التنقل. التثبيت (wifiStaNodes)؛

نريد أن تظل نقطة الوصول في وضع ثابت أثناء المحاكاة. نحن
يمكنك تحقيق ذلك عن طريق تعيين نموذج التنقل لهذه العقدة ليكون
ns3::ConstantPositionMobilityModel:

التنقل.SetMobilityModel("ns3::ConstantPositionMobilityModel");
التنقل. التثبيت (wifiApNode)؛

لدينا الآن عقدنا وأجهزتنا وقنواتنا التي تم إنشاؤها ونماذج التنقل المختارة لـ
عقد Wifi، لكن ليس لدينا أي مجموعات بروتوكولات موجودة. تماما كما فعلنا سابقا في كثير من الأحيان
مرات، سوف نستخدم 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 ونقطة الوصول على الشبكة اللاسلكية.

عنوان Ipv4AddressHelper؛

عنوان.SetBase ("10.1.1.0"، "255.255.255.0")؛
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = Address.Assign (p2pDevices);

عنوان.SetBase ("10.1.2.0"، "255.255.255.0")؛
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = Address.Assign (csmaDevices);

عنوان.SetBase ("10.1.3.0"، "255.255.255.0")؛
عنوان.تخصيص (staDevices)؛
عنوان.تخصيص (apDevices)؛

لقد وضعنا خادم الصدى على العقدة "أقصى اليمين" في الرسم التوضيحي في بداية الملف
ملف. لقد فعلنا هذا من قبل.

UdpEchoServerHelper echoServer (9);

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

ونضع عميل الصدى على آخر عقدة STA قمنا بإنشائها، ونوجهه إلى الخادم قيد التشغيل
شبكة CSMA لقد شهدنا أيضًا عمليات مماثلة من قبل.

UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma)، 9)؛
echoClient.SetAttribute ("MaxPackets"، UintegerValue (1))؛
echoClient.SetAttribute ("Interval"، TimeValue (Seconds (1.0)))؛
echoClient.SetAttribute ("PacketSize"، UintegerValue (1024))؛

ApplicationContainer clientApps =
echoClient.Install (wifiStaNodes.Get (nWifi - 1));
ClientApps.Start (ثواني (2.0))؛
ClientApps.Stop (Seconds (10.0));

وبما أننا قمنا ببناء شبكة بينية هنا، فنحن بحاجة إلى تمكين توجيه الشبكة البينية أيضًا
فعلنا في Second.cc مثال البرنامج النصي.

Ipv4GlobalRoutingHelper::PopulateRoutingTables();

الشيء الوحيد الذي يمكن أن يفاجئ بعض المستخدمين هو حقيقة المحاكاة التي أنشأناها للتو
لن تتوقف أبدًا "بشكل طبيعي". وذلك لأننا طلبنا من نقطة الوصول اللاسلكية
توليد منارات. وسوف تولد منارات إلى الأبد، وهذا سوف يؤدي إلى محاكاة
تتم جدولة الأحداث في المستقبل إلى أجل غير مسمى، لذلك يجب أن نطلب من جهاز المحاكاة أن يتوقف
على الرغم من أنه قد يكون لديه أحداث إنشاء منارة مجدولة. السطر التالي من التعليمات البرمجية
يخبر جهاز المحاكاة بالتوقف حتى لا نحاكي المنارات إلى الأبد وندخل إلى ما هو موجود
في الأساس حلقة لا نهاية لها.

محاكي::توقف (ثواني (10.0))؛

نقوم بإنشاء ما يكفي من التتبع لتغطية الشبكات الثلاث:

pointToPoint.EnablePcapAll ("الثالث")؛
phy.EnablePcap ("الثالث"، apDevices.Get (0))؛
csma.EnablePcap ("ثالث"، csmaDevices.Get (0)، true) ؛

ستبدأ هذه الأسطر الثلاثة من التعليمات البرمجية في تتبع PCAP على كلا العقدتين من نقطة إلى نقطة
بمثابة العمود الفقري لدينا، وسوف يبدأ تتبع الوضع غير الشرعي (المراقبة) على شبكة واي فاي،
وسيبدأ تتبعًا غير شرعي على شبكة CSMA. وهذا سوف يتيح لنا رؤية كل
حركة المرور مع الحد الأدنى لعدد ملفات التتبع.

أخيرًا، نقوم بالفعل بتشغيل المحاكاة وتنظيف البرنامج ثم الخروج منه.

محاكي :: تشغيل () ؛
جهاز محاكاة :: تدمير () ؛
0 العودة؛
}

لتشغيل هذا المثال، عليك نسخ ملف الثالث.cc مثال على البرنامج النصي في
اخدش الدليل واستخدم Waf للإنشاء تمامًا كما فعلت مع ملف Second.cc مثال. اذا أنت
موجودة في دليل المستوى الأعلى للمستودع الذي ستكتبه،

أمثلة $ cp/tutorial/third.ccخدش/mythird.cc
$ ./واف
$ ./waf --تشغيل الصفر/mythird

مرة أخرى، نظرًا لأننا قمنا بإعداد تطبيقات صدى UDP تمامًا كما فعلنا في ملف 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.407 ثانية)
في الوقت 2s، أرسل العميل 1024 بايت إلى المنفذ 10.1.2.4 9
في الوقت المناسب، تلقى خادم 2.01796s 1024 بايت من المنفذ 10.1.3.3 رقم 49153
في الوقت المناسب، أرسل خادم 2.01796s 1024 بايت إلى المنفذ 10.1.3.3 رقم 49153
في الوقت 2.03364 تلقى العميل 1024 بايت من المنفذ 10.1.2.4 9

أذكر أن الرسالة الأولى، أرسلت 1024 بايت إلى 10.1.2.4"، هو عميل صدى UDP
إرسال حزمة إلى الخادم. في هذه الحالة، يكون العميل متصلاً بالشبكة اللاسلكية
(10.1.3.0). الرسالة الثانية "تم الاستلام 1024 بايت تبدأ من 10.1.3.3"، من صدى UDP
الخادم، الذي يتم إنشاؤه عندما يتلقى حزمة الصدى. الرسالة الاخيرة "تم الاستلام 1024
بايت تبدأ من 10.1.2.4"، من عميل الصدى، مما يشير إلى أنه تلقى الصدى الخاص به
العودة من الخادم.

إذا ذهبت الآن وبحثت في دليل المستوى الأعلى، فستجد أربعة ملفات تتبع من
هذه المحاكاة، اثنان من العقدة صفر واثنان من العقدة الأولى:

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

يتوافق الملف "third-0-0.pcap" مع جهاز نقطة إلى نقطة على العقدة صفر -
الجانب الأيسر من "العمود الفقري". الملف "third-1-0.pcap" يتوافق مع نقطة إلى نقطة
الجهاز على العقدة الأولى - الجانب الأيمن من "العمود الفقري". سيكون الملف "الثالث-0-1.pcap".
التتبع المختلط (وضع الشاشة) من شبكة Wifi والملف "third-1-1.pcap"
سيكون التتبع غير الشرعي من شبكة CSMA. هل يمكنك التحقق من ذلك عن طريق الفحص
الرمز؟

نظرًا لوجود عميل الصدى على شبكة Wifi، فلنبدأ من هناك. دعونا نلقي نظرة على
تتبع غير شرعي (وضع الشاشة) التقطناه على تلك الشبكة.

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

من المفترض أن تشاهد بعض المحتويات التي تشبه شبكة wifi والتي لم تشاهدها هنا من قبل:

القراءة من الملف الثالث-0-1.pcap، نوع الرابط IEEE802_11 (802.11)
0.000025 منارة (ns-3-ssid) [6.0*9.0 12.0 18.0 24.0 36.0 48.0 54.0 ميجابت] IBSS
0.000308 طلب مساعد (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 استجابة مساعد مساعدة(0) :: ناجح
0.000546 Acknowledgment RA:00:00:00:00:00:0a
0.000721 طلب مساعد (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 ميجابت]
0.000737 Acknowledgment RA:00:00:00:00:00:07
0.000824 استجابة مساعد مساعدة(0) :: ناجح
0.000968 Acknowledgment RA:00:00:00:00:00:0a
0.001134 طلب مساعد (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 ميجابت]
0.001150 Acknowledgment RA:00:00:00:00:00:09
0.001273 استجابة مساعد مساعدة(0) :: ناجح
0.001417 Acknowledgment RA:00:00:00:00:00:0a
0.102400 منارة (ns-3-ssid) [6.0*9.0 12.0 18.0 24.0 36.0 48.0 54.0 ميجابت] IBSS
0.204800 منارة (ns-3-ssid) [6.0*9.0 12.0 18.0 24.0 36.0 48.0 54.0 ميجابت] IBSS
0.307200 منارة (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

مرة أخرى، يجب أن تشاهد بعض المحتويات المألوفة:

القراءة من الملف الثالث-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

مرة أخرى، يجب أن تشاهد بعض المحتويات المألوفة:

القراءة من الملف الثالث-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

يجب أن تشاهد بعض المحتويات ذات المظهر المألوف:

القراءة من الملف الثالث 1-1.pcap، نوع الرابط EN10MB (إيثرنت)
2.017837 ARP، طلب من لديه 10.1.2.4 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.1، الطول 50
2.017861 ARP، الرد 10.1.2.4 موجود في 00:00:00:00:00:06، الطول 50
2.017861 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP، الطول 1024
2.022966 ARP، طلب من لديه 10.1.2.1 (ff:ff:ff:ff:ff:ff) أخبر 10.1.2.4، الطول 50
2.022966 ARP، الرد 10.1.2.1 موجود في 00:00:00:00:00:03، الطول 50
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP، الطول 1024

وينبغي أن يكون مفهوما بسهولة. إذا نسيت، ارجع وانظر إلى المناقشة
in Second.cc. هذا هو نفس التسلسل.

الآن، قضينا الكثير من الوقت في إعداد نماذج التنقل للشبكة اللاسلكية، وهكذا
سيكون من العار الانتهاء من ذلك دون إظهار أن عقد STA تتحرك بالفعل
حولها أثناء المحاكاة. دعونا نفعل ذلك عن طريق الربط في MobilityModel الدورة
تغيير مصدر التتبع. هذه مجرد نظرة خاطفة على قسم التتبع التفصيلي
قادم، ولكن يبدو أن هذا مكان جميل جدًا للحصول على مثال فيه.

كما هو مذكور في قسم "التبديل والتبديل ns-3"، فإن NS-3 ينقسم نظام التتبع إلى تتبع
المصادر وأحواض التتبع، ونوفر وظائف للربط بين الاثنين. سوف نستخدم
يقوم نموذج التنقل المحدد مسبقًا بتغيير مصدر التتبع لإنشاء أحداث التتبع. نحن
سوف تحتاج إلى كتابة مصدر تتبع للاتصال بهذا المصدر الذي سيعرض بعض الجمال
المعلومات بالنسبة لنا. على الرغم من سمعتها بأنها صعبة، إلا أنها في الحقيقة بسيطة للغاية.
قبل البرنامج الرئيسي لل الصفر/mythird.cc البرنامج النصي (أي بعد
NS_LOG_COMPONENT_DEFINE بيان)، أضف الوظيفة التالية:

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

يقوم هذا الرمز فقط بسحب معلومات الموقع من نموذج التنقل ودون قيد أو شرط
يسجل موضع x و y للعقدة. سنقوم بترتيب هذه الوظيفة
يتم استدعاؤه في كل مرة تقوم فيها العقدة اللاسلكية مع عميل الصدى بتغيير موضعها. نحن نفعل هذا
يستخدم ال التكوين::اتصال وظيفة. أضف أسطر التعليمات البرمجية التالية إلى البرنامج النصي فقط
أمام محاكي :: تشغيل مكالمة.

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

التكوين::Connect (oss.str ()، MakeCallback (&CourseChange));

ما نقوم به هنا هو إنشاء سلسلة تحتوي على مسار مساحة اسم التتبع للحدث
الذي نريد الاتصال به. أولاً، يتعين علينا معرفة العقدة التي نريد استخدامها
هيه معرف_جيت الطريقة كما شرحت سابقا . في حالة الرقم الافتراضي لـ CSMA و
العقد اللاسلكية، وتبين أن هذه هي العقدة السابعة ومسار مساحة اسم التتبع إلى
سيبدو نموذج التنقل،

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

استنادا إلى المناقشة في قسم التتبع، قد تستنتج أن مسار التتبع هذا
يشير إلى العقدة السابعة في NodeList العالمية. ويحدد ما يسمى
كائن مجمع من النوع ns3 :: MobilityModel. تشير بادئة علامة الدولار إلى أن
يتم تجميع MobilityModel إلى العقدة السابعة. العنصر الأخير من المسار يعني أننا
يتم ربطهم بحدث "CourseChange" لهذا النموذج.

نقوم بإجراء اتصال بين مصدر التتبع في العقدة السابعة مع مصدر التتبع الخاص بنا عن طريق الاتصال
التكوين::اتصال وتمرير مسار مساحة الاسم هذا. وبمجرد الانتهاء من ذلك، تتغير كل دورة
سيتم ربط الحدث الموجود على العقدة السابعة بمصرف التتبع الخاص بنا، والذي سيقوم بدوره بطباعة ملف
مركز جديد.

إذا قمت الآن بتشغيل المحاكاة، فسوف ترى تغييرات المقرر الدراسي معروضة فور حدوثها.

انتهى "البناء" بنجاح (5.989 ثانية)
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10, y = 0
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.3841, y = 0.923277
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2049, y = 1.90708
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.8136, y = 1.11368
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.8452, y = 2.11318
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.9797, y = 3.10409
في الوقت 2s، أرسل العميل 1024 بايت إلى المنفذ 10.1.2.4 9
في الوقت المناسب، تلقى خادم 2.01796s 1024 بايت من المنفذ 10.1.3.3 رقم 49153
في الوقت المناسب، أرسل خادم 2.01796s 1024 بايت إلى المنفذ 10.1.3.3 رقم 49153
في الوقت 2.03364 تلقى العميل 1024 بايت من المنفذ 10.1.2.4 9
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.3273, y = 4.04175
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.013, y = 4.76955
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.4317, y = 5.67771
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.4607, y = 5.91681
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.0155, y = 6.74878
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.0076, y = 6.62336
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.6285, y = 5.698
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.32, y = 4.97559
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.1134, y = 3.99715
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.8359, y = 4.68851
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.5953, y = 3.71789
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.7595, y = 4.26688
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.7629, y = 4.34913
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.2292, y = 5.19485
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2344, y = 5.09394
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.3601, y = 4.60846
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.40025, y = 4.32795
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.14292, y = 4.99761
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.08299, y = 5.99581
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.26068, y = 5.42677
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.35917, y = 6.42191
/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.66805, y = 7.14466
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.71414, y = 6.84456
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.42489, y = 7.80181

اقتفاء أثر


خلفيّة
كما هو مذكور في UsingTracingSystem، فإن الهدف الأساسي من تشغيل ملف NS-3 المحاكاة هي
توليد المخرجات للدراسة. لديك استراتيجيتين أساسيتين للحصول على المخرجات منهما NS-3:
باستخدام آليات الإخراج المجمعة العامة المحددة مسبقًا وتحليل محتواها لاستخراجها
معلومات مثيرة للاهتمام؛ أو بطريقة أو بأخرى تطوير آلية الإخراج التي تنقل بالضبط
(وربما فقط) المعلومات المطلوبة.

يتمتع استخدام آليات الإخراج المجمعة المحددة مسبقًا بميزة عدم الحاجة إلى إجراء أي تغييرات عليها
NS-3، ولكن قد يتطلب الأمر كتابة نصوص برمجية لتحليل البيانات محل الاهتمام وتصفيتها. غالباً،
PCAP أو NS_LOG يتم جمع رسائل الإخراج أثناء تشغيل المحاكاة وتشغيلها بشكل منفصل
من خلال البرامج النصية التي تستخدم البقرى, عطش or AWK لتحليل الرسائل وتقليلها وتحويلها
البيانات إلى نموذج يمكن التحكم فيه. يجب كتابة البرامج للقيام بالتحويل، لذلك هذا
لا يأتي مجانا. NS_LOG لا يعتبر الإخراج جزءا من NS-3 API، ويمكن
التغيير دون سابق إنذار بين الإصدارات. فضلاً عن ذلك، NS_LOG الإخراج متاح فقط في
يتم إنشاء تصحيح الأخطاء، لذا فإن الاعتماد عليه يفرض عقوبة على الأداء. وبطبيعة الحال، إذا
المعلومات ذات الأهمية غير موجودة في أي من آليات الإخراج المحددة مسبقًا
فشل النهج.

إذا كنت بحاجة إلى إضافة بعض المعلومات إلى الآليات المجمعة المحددة مسبقًا، فيمكن ذلك
بالتأكيد يجب القيام به؛ وإذا كنت تستخدم واحدة من NS-3 الآليات، قد تتم إضافة التعليمات البرمجية الخاصة بك
كمساهمة.

NS-3 يوفر آلية أخرى، تسمى التتبع، والتي تتجنب بعض المشاكل الكامنة
في آليات الإخراج السائبة. ولها العديد من المزايا الهامة. أولا، يمكنك
قم بتقليل كمية البيانات التي يتعين عليك إدارتها من خلال تتبع الأحداث التي تهمك فقط
(بالنسبة لعمليات المحاكاة الكبيرة، يمكن أن يؤدي تفريغ كل شيء على القرص للمعالجة اللاحقة إلى إنشاء عمليات إدخال/إخراج
الاختناقات). ثانيًا، إذا كنت تستخدم هذه الطريقة، فيمكنك التحكم في تنسيق الإخراج
مباشرة حتى تتجنب خطوة ما بعد المعالجة عطش, AWK, بيرل or الثعبان نصوص. لو
حسب رغبتك، يمكن تنسيق مخرجاتك مباشرة في نموذج مقبول بواسطة gnuplot
مثال (انظر أيضًا GnuplotHelper). يمكنك إضافة خطافات في القلب والتي يمكن بعد ذلك
يمكن الوصول إليها من قبل مستخدمين آخرين، ولكنها لن تنتج أي معلومات ما لم يطلب ذلك صراحة
القيام بذلك. ولهذه الأسباب نعتقد أن NS-3 نظام التتبع هو أفضل وسيلة للحصول على
المعلومات من المحاكاة وبالتالي فهي أيضًا إحدى أهم الآليات
لفهم في NS-3.

كليل الأدوات
هناك العديد من الطرق للحصول على المعلومات من البرنامج. الطريقة الأكثر مباشرة هي
لطباعة المعلومات مباشرة إلى الإخراج القياسي، كما في:

#يشمل

باطل
بعض الوظائف (باطلة)
{
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 بأعلى رقم تسلسلي غير مثبت
إذا (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // تجاهل في حالة عدم وجود علامة ACK
}


لتسجيل حالة عدم وجود ACK، يمكنك إضافة حالة جديدة NS_LOG_LOGIC في ال if جسم البيان:

/** معالجة ACK المستلم حديثًا */
باطل
TcpSocketBase::ReceivedAck (Ptr الحزمة، const TcpHeader وtcpHeader)
{
NS_LOG_FUNCTION (هذا << tcpHeader)؛

// تم استلام ACK. قارن رقم ACK بأعلى رقم تسلسلي غير مثبت
إذا (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // تجاهل في حالة عدم وجود علامة ACK
NS_LOG_LOGIC ("TcpSocketBase " << هذا << " لا يوجد علامة ACK")؛
}


قد يبدو هذا بسيطًا ومرضيًا إلى حد ما للوهلة الأولى، ولكن هناك شيء يجب مراعاته
أنك سوف تكتب التعليمات البرمجية لإضافتها NS_LOG البيانات وسيكون عليك أيضًا الكتابة
الكود (كما في البقرى, عطش or AWK البرامج النصية) لتحليل إخراج السجل من أجل عزل ملفك
معلومة. هذا لأنه على الرغم من أن لديك بعض التحكم في ما يتم إخراجه بواسطة ملف
نظام التسجيل، لديك فقط التحكم وصولاً إلى مستوى مكون السجل، وهو عادةً ما يكون
ملف التعليمات البرمجية المصدر بأكمله.

إذا كنت تقوم بإضافة تعليمات برمجية إلى وحدة موجودة، فسيتعين عليك أيضًا التعايش مع المخرجات
التي وجدها كل مطور آخر مثيرة للاهتمام. قد تجد أنه من أجل الحصول على
كمية صغيرة من المعلومات التي تحتاجها، قد تضطر إلى الخوض في كميات هائلة من المعلومات
رسائل غريبة لا تهمك. قد تضطر إلى حفظ سجل ضخم
الملفات إلى القرص ومعالجتها وصولاً إلى بضعة أسطر عندما تريد القيام بأي شيء.

لأنه لا توجد ضمانات في NS-3 حول استقرار NS_LOG الإخراج، يمكنك أيضا
اكتشف أن أجزاء مخرجات السجل التي تعتمد عليها تختفي أو تتغير بينها
إطلاق. إذا كنت تعتمد على بنية الإخراج، فقد تجد رسائل أخرى
تمت إضافتها أو حذفها مما قد يؤثر على كود التحليل الخاص بك.

وفي الختام NS_LOG الإخراج متاح فقط في إصدارات تصحيح الأخطاء، ولا يمكنك الحصول على إخراج السجل منه
الإصدارات المحسنة، والتي تعمل بسرعة مضاعفة تقريبًا. يعتمد على NS_LOG يفرض الأداء
ضربة جزاء.

لهذه الأسباب، فإننا نعتبر المطبوعات الأمراض المنقولة جنسيا :: كوت NS_LOG أن تكون الرسائل سريعة و
طرق قذرة للحصول على مزيد من المعلومات NS-3ولكنها غير مناسبة للعمل الجاد.

من المرغوب فيه أن يكون لديك منشأة مستقرة تستخدم واجهات برمجة التطبيقات (APIs) المستقرة التي تسمح للشخص بالوصول إليها
النظام الأساسي والحصول على المعلومات المطلوبة فقط. من المرغوب فيه أن تكون قادرًا على القيام به
هذا دون الحاجة إلى تغيير وإعادة ترجمة النظام الأساسي. والأفضل من ذلك سيكون أ
النظام الذي يقوم بإعلام رمز المستخدم عند تغيير عنصر محل اهتمام أو حدث مثير للاهتمام
حدث ذلك حتى لا يضطر المستخدم إلى البحث بنشاط في النظام بحثًا عنه
الأشياء.

إنّ NS-3 تم تصميم نظام التتبع للعمل على طول هذه الخطوط ومتكامل بشكل جيد مع
السمة و التكوين الأنظمة الفرعية تسمح بسيناريوهات استخدام بسيطة نسبيًا.

نظرة عامة
إنّ NS-3 نظام التتبع مبني على مفاهيم مصادر التتبع المستقلة و
تتبع الأحواض، بالإضافة إلى آلية موحدة لربط المصادر بالأحواض.

مصادر التتبع هي الكيانات التي يمكنها الإشارة إلى الأحداث التي تحدث في محاكاة وتقديمها
الوصول إلى البيانات الأساسية المثيرة للاهتمام. على سبيل المثال ، يمكن أن يشير مصدر التتبع عندما يكون ملف
يتم استلام الحزمة بواسطة جهاز شبكة وتوفر الوصول إلى محتويات الحزمة لـ
أثر المصارف المهتمة. قد يشير مصدر التتبع أيضًا إلى حالة مثيرة للاهتمام
التغيير يحدث في النموذج. على سبيل المثال ، نافذة الازدحام لنموذج TCP هي أولية
مرشح لمصدر التتبع. في كل مرة تتغير نافذة الازدحام التتبع المتصل
يتم إخطار المصارف بالقيمة القديمة والجديدة.

مصادر التتبع ليست مفيدة في حد ذاتها ؛ يجب أن تكون متصلة بأجزاء أخرى من التعليمات البرمجية
تفعل شيئًا مفيدًا بالفعل مع المعلومات المقدمة من المصدر. ال
الكيانات التي تستهلك معلومات التتبع تسمى أحواض التتبع. مصادر التتبع
مولدات البيانات وأحواض التتبع هم المستهلكون. هذا التقسيم الصريح يسمح بمساحة كبيرة
أعداد من مصادر التتبع المنتشرة حول النظام في الأماكن التي يصممها المؤلفون النموذجيون
نعتقد قد يكون مفيدا. يؤدي إدخال مصادر التتبع إلى تنفيذ عملية تنفيذ صغيرة جدًا
تكاليف غير مباشرة.

يمكن أن يكون هناك صفر أو أكثر من المستهلكين لأحداث التتبع التي تم إنشاؤها بواسطة مصدر التتبع. يمكن للمرء
فكر في مصدر التتبع كنوع من رابط المعلومات من نقطة إلى عدة نقاط. الرمز الخاص بك
البحث عن أحداث التتبع من جزء معين من التعليمات البرمجية الأساسية يمكن أن يتعايش معها بسعادة
رمز آخر يفعل شيئًا مختلفًا تمامًا عن نفس المعلومات.

وما لم يقوم المستخدم بتوصيل مصدر التتبع بأحد هذه المصادر، فلن يتم إخراج أي شيء. باستخدام
نظام التتبع، الذي تحصل عليه أنت والأشخاص الآخرون المتصلون بنفس مصدر التتبع
بالضبط ما يريدون وما يريدون فقط من النظام. لا أحد منكم
التأثير على أي مستخدم آخر عن طريق تغيير المعلومات التي يخرجها النظام. اذا أنت
إذا قمت بإضافة مصدر تتبع، فإن عملك كمواطن صالح مفتوح المصدر قد يسمح للآخرين
المستخدمين لتوفير أدوات مساعدة جديدة ربما تكون مفيدة جدًا بشكل عام، دون إنشاء أي منها
التغييرات في NS-3 الأساسية.

الاشارات مثال
لنأخذ بضع دقائق ونستعرض مثالًا بسيطًا للتتبع. سنحتاج
خلفية صغيرة عن عمليات الاسترجاعات لفهم ما يحدث في المثال، لذلك نحن
يجب أن تأخذ منعطفًا صغيرًا على الفور.

الاسترجاعات
الهدف من نظام رد الاتصال في NS-3 هو السماح لقطعة واحدة من التعليمات البرمجية باستدعاء وظيفة
(أو الطريقة في C++) دون أي تبعية محددة بين الوحدات. وهذا يعني في نهاية المطاف
أنت بحاجة إلى نوع من المراوغة - فأنت تتعامل مع عنوان الوظيفة المطلوبة على أنه a
عامل. يسمى هذا المتغير متغير المؤشر إلى الوظيفة. العلاقة
بين الوظيفة والمؤشر إلى الوظيفة لا يختلف حقًا عن الكائن و
مؤشر إلى كائن.

في لغة C ، يكون المثال الأساسي لمؤشر إلى وظيفة هو أ
مؤشر إلى وظيفة إرجاع عدد صحيح (PFI). للحصول على PFI أخذ واحدة مادبا المعلمة، هذا
يمكن الإعلان عنها مثل،

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

(لكن اقرأ C++-الأسئلة الشائعة القسم 33 قبل كتابة رمز مثل هذا!) ما تحصل عليه من هذا
هو متغير اسمه ببساطة الرابطة تمت تهيئته إلى القيمة 0. إذا كنت تريد ذلك
تهيئة هذا المؤشر إلى شيء ذي معنى، يجب أن يكون لديك وظيفة مع
التوقيع المطابق. في هذه الحالة، يمكنك توفير دالة تبدو كما يلي:

int MyFunction (int arg) {}

إذا كان لديك هذا الهدف، فيمكنك تهيئة المتغير للإشارة إلى وظيفتك:

pfi = وظيفتي ؛

يمكنك بعد ذلك الاتصال بـ MyFunction بشكل غير مباشر باستخدام الشكل الأكثر إيحاءًا للمكالمة:

نتيجة int = (* pfi) (1234) ؛

هذا موحي لأنه يبدو أنك تقوم بإلغاء الإشارة إلى مؤشر الوظيفة فقط
كما لو كنت ترغب في عدم الإشارة إلى أي مؤشر. ومع ذلك ، عادةً ما يستفيد الأشخاص من
حقيقة أن المترجم يعرف ما يجري وسيستخدم صيغة أقصر:

نتيجة int = pfi (1234) ؛

يبدو أنك تتصل بوظيفة مسماة الرابطة، ولكن المترجم ذكي بما فيه الكفاية للقيام بذلك
تعرف على الاتصال من خلال المتغير الرابطة بشكل غير مباشر إلى الوظيفة MyFunction.

من الناحية النظرية، هذه هي الطريقة التي يعمل بها نظام التتبع تقريبًا. في الأساس، أثر
بالوعة is رد الاتصال. عندما يعبر مصدر التتبع عن اهتمامه بتلقي أحداث التتبع، فإنه
يضيف نفسه كرد اتصال إلى قائمة عمليات الاسترجاعات التي يحتفظ بها مصدر التتبع داخليًا.
عندما يحدث حدث مثير للاهتمام، يستدعي مصدر التتبع الخاص به المشغل أو العامل(...) توفير
صفر أو أكثر من الحجج. ال المشغل أو العامل(...) يتجول في نهاية المطاف إلى أسفل في النظام و
يفعل شيئًا يشبه بشكل ملحوظ المكالمة غير المباشرة التي رأيتها للتو، حيث يقدم صفرًا أو أكثر
المعلمات، تماما كما الدعوة إلى الرابطة أعلاه مرر معلمة واحدة إلى الوظيفة المستهدفة
MyFunction.

والفرق المهم الذي يضيفه نظام التتبع هو أنه بالنسبة لكل مصدر تتبع هناك
هي قائمة داخلية لعمليات الاسترجاعات. بدلاً من مجرد إجراء مكالمة واحدة غير مباشرة، يمكنك التتبع
قد يستدعي المصدر عمليات رد اتصال متعددة. عندما يعبر بالوعة التتبع عن اهتمامه بـ
الإخطارات من مصدر التتبع، فهي في الأساس تقوم فقط بترتيب إضافة وظيفتها الخاصة إليها
قائمة رد الاتصال.

إذا كنت مهتمًا بمزيد من التفاصيل حول كيفية ترتيب ذلك فعليًا NS-3، يشعر
حرية الاطلاع على قسم رد الاتصال في NS-3 دليل.

تجول: الرابع.cc
لقد قدمنا ​​بعض التعليمات البرمجية لتنفيذ ما هو في الواقع أبسط مثال على التتبع
التي يمكن تجميعها. يمكنك العثور على هذا الرمز في دليل البرنامج التعليمي باسم الرابع.cc.
دعونا نسير من خلال ذلك:

/ * - * - الوضع: C ++ ؛ نمط ملف c: "gnu" ؛ وضع علامات الجدولة البادئة: لا شيء ؛ - * - * /
/*
* هذا البرنامج مجاني ؛ يمكنك إعادة توزيعه و / أو تعديله
* بموجب شروط رخصة جنو العمومية الإصدار 2 كـ
* نشرته مؤسسة البرمجيات الحرة ؛
*
* يتم توزيع هذا البرنامج على أمل أن يكون مفيدا ،
* ولكن بدون أي ضمان ؛ حتى بدون الضمان الضمني لـ
* القابلية للتسويق أو الملاءمة لغرض معين. انظر
* رخصة جنو العمومية لمزيد من التفاصيل.
*
* يجب أن تكون قد تلقيت نسخة من رخصة جنو العمومية العامة
* مع هذا البرنامج ؛ إذا لم يكن كذلك ، فاكتب إلى البرمجيات الحرة
* Foundation، Inc.، 59 Temple Place، Suite 330، Boston، MA 02111-1307 USA
*/

# تضمين "ns3 / object.h"
# تضمين "ns3 / uinteger.h"
#تتضمن "ns3/traced-value.h"
# تضمين "ns3 / trace-source-accessor.h"

#يشمل

باستخدام مساحة الاسم ns3 ؛

يجب أن تكون معظم هذه التعليمات البرمجية مألوفة لك تمامًا. كما ذكرنا أعلاه، نظام التتبع
يستخدم أنظمة الكائنات والسمات بشكل مكثف، لذا ستحتاج إلى تضمينها.
يتضمن الأولان أعلاه تقديم الإعلانات الخاصة بهذه الأنظمة بشكل صريح. أنت
يمكننا استخدام رأس الوحدة الأساسية للحصول على كل شيء مرة واحدة، لكننا نقوم بالتضمين
بوضوح هنا لتوضيح مدى بساطة كل هذا حقًا.

الملف، تتبع القيمة يجلب الإعلانات المطلوبة لتتبع البيانات التي
يطيع دلالات القيمة. بشكل عام، دلالات القيمة تعني فقط أنه يمكنك اجتياز
الكائن نفسه حوله، بدلاً من تمرير عنوان الكائن. ما هذا كله حقا
يعني أنك سوف تكون قادرًا على تتبع جميع التغييرات التي تم إجراؤها على TracedValue بشكل حقيقي
طريقة بسيطة.

نظرًا لأن نظام التتبع يتكامل مع السمات ، وتعمل السمات مع الكائنات ،
يجب أن يكون هناك NS-3 هدف لمصدر التتبع للعيش فيه. مقتطف التعليمات البرمجية التالي
يعلن ويحدد كائنًا بسيطًا يمكننا العمل معه.

فئة MyObject: الكائن العام
{
الجمهور:
TypeId ثابت GetTypeId (باطل)
{
ثابت TypeId tid = TypeId ("MyObject")
.SetParent (Object :: GetTypeId ())
.AddConstructor ()
.AddTraceSource ("MyInteger"،
"قيمة عدد صحيح للتتبع." ،
MakeTraceSourceAccessor (&MyObject::m_myInt)،
"ns3::Traced::Value::Int32Callback")
;
عودة المد
}

كائني () {}
TracedValue m_myInt;
};

السطرين المهمين من التعليمات البرمجية أعلاه، فيما يتعلق بالتتبع هما .AddTraceSource
و TracedValue إعلان عن m_myInt.

إنّ .AddTraceSource يوفر "الخطافات" المستخدمة لتوصيل مصدر التتبع بـ
العالم الخارجي من خلال نظام التكوين. الوسيطة الأولى هي اسم لهذا التتبع
المصدر، مما يجعله مرئيًا في نظام التكوين. الوسيطة الثانية هي سلسلة تعليمات.
انظر الآن إلى الحجة الثالثة، في الواقع ركز على حجة من الحجة الثالثة:
&MyObject::m_myInt. هذه هي TracedValue التي تتم إضافتها إلى الفصل؛ إنها
دائمًا عضو بيانات الفصل. (الحجة الأخيرة هي اسم أ typedef و ل
نوع TracedValue، كسلسلة. يتم استخدام هذا لإنشاء وثائق للصحيح
توقيع وظيفة رد الاتصال، وهو مفيد بشكل خاص للأنواع الأكثر عمومية من
عمليات الاسترجاعات.)

إنّ قيمة التتبع<> يوفر الإعلان البنية التحتية التي تدفع رد الاتصال
عملية. في أي وقت يتم فيه تغيير القيمة الأساسية، ستوفر آلية TracedValue
كل من القيمة القديمة والجديدة لهذا المتغير، في هذه الحالة int32_t قيمة. الأثر
سوف تحتاج وظيفة الحوض الخاصة بـ TracedValue إلى التوقيع

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

يجب أن تحتوي جميع أحواض التتبع التي تربط مصدر التتبع هذا على هذا التوقيع. سنناقش أدناه
كيف يمكنك تحديد توقيع رد الاتصال المطلوب في حالات أخرى.

بالتأكيد، الاستمرار من خلال الرابع.cc نحن نرى:

باطل
IntTrace (int32_t oldValue، int32_t newValue)
{
std :: cout << "Traced" << oldValue << "إلى" << newValue << std :: endl؛
}

هذا هو تعريف حوض التتبع المطابق. وهو يتوافق مباشرة مع رد الاتصال
توقيع الوظيفة. بمجرد توصيلها، سيتم استدعاء هذه الوظيفة كلما
TracedValue التغييرات.

لقد رأينا الآن مصدر التتبع وحوض التتبع. ما تبقى هو رمز للاتصال
المصدر إلى الحوض، وهو ما يحدث في رئيسي:

مادبا
main (int argc، char * argv [])
{
Ptr myObject = CreateObject () ؛
myObject-> TraceConnectWithoutContext ("MyInteger" ، MakeCallback (& ​​IntTrace)) ؛

myObject-> m_myInt = 1234 ؛
}

هنا نقوم أولاً بإنشاء مثيل MyObject الذي يوجد فيه مصدر التتبع.

الخطوة التالية هي TraceConnectWithoutContext، يشكل الاتصال بين التتبع
المصدر ومغسلة التتبع. الوسيطة الأولى هي مجرد اسم مصدر التتبع "MyInteger"
رأينا أعلاه. لاحظ ال إجعل الإتصال وظيفة القالب. هذه الوظيفة تفعل السحر
المطلوبة لإنشاء الأساسية NS-3 كائن رد الاتصال وربطه بالوظيفة
انتتريس. تتبع الاتصال يجعل الارتباط بين وظيفتك المقدمة و
زائد المشغل أو العامل() في المتغير المتتبع المشار إليه بواسطة السمة "MyInteger".
بعد إجراء هذا الاقتران، سيقوم مصدر التتبع "بإطلاق" رد الاتصال الذي قمت بتوفيره
وظيفة.

إن الكود الذي يجعل كل هذا يحدث، بالطبع، ليس تافهًا، لكن الجوهر هو ذلك
أنت تقوم بالترتيب لشيء يشبه تمامًا فاي () المثال أعلاه ليتم استدعاؤه
بواسطة مصدر التتبع. إعلان ال TracedValue m_myInt; في الكائن
يؤدي في حد ذاته السحر المطلوب لتوفير عوامل التعيين المثقلة التي ستفعل ذلك
استخدم ال المشغل أو العامل() لاستدعاء رد الاتصال فعليًا باستخدام المعلمات المطلوبة. ال
.AddTraceSource ينفذ السحر لتوصيل رد الاتصال بنظام التكوين، و
TraceConnectWithoutContext ينفذ السحر لتوصيل وظيفتك بالتتبع
المصدر، والذي يتم تحديده بواسطة اسم السمة.

دعونا نتجاهل الجزء المتعلق بالسياق في الوقت الحالي.

وأخيرا، السطر الذي يعين قيمة ل m_myInt:

myObject-> m_myInt = 1234 ؛

يجب تفسيره على أنه استدعاء لـ عامل التشغيل = على متغير العضو m_myInt مع
العدد الصحيح 1234 مرت كمعلمة.

منذ m_myInt هو TracedValue، تم تعريف هذا العامل لتنفيذ رد اتصال
تُرجع فارغة وتأخذ قيمتين صحيحتين كمعلمات --- قيمة قديمة وقيمة جديدة
للعدد الصحيح في السؤال. هذا هو بالضبط التوقيع الوظيفي لرد الاتصال
الوظيفة التي قدمناها --- انتتريس.

للتلخيص ، مصدر التتبع هو ، في جوهره ، متغير يحتوي على قائمة من عمليات الاسترجاعات. أ
مصدر التتبع هو دالة تستخدم كهدف لرد الاتصال. نوع السمة والكائن
تُستخدم أنظمة المعلومات لتوفير طريقة لربط مصادر التتبع بأحواض التتبع.
إن فعل "الضرب" على مصدر التتبع هو تنفيذ عامل تشغيل على مصدر التتبع الذي
حرائق الاسترجاعات. ينتج عن هذا عمليات الاسترجاعات الخاصة بمصدر التتبع الذين يسجلون الاهتمام بـ
يتم استدعاء المصدر باستخدام المعلمات المقدمة من المصدر.

إذا قمت الآن بإنشاء هذا المثال وتشغيله،

$ ./waf --التشغيل الرابع

سترى الإخراج من انتتريس يتم تنفيذ الوظيفة بمجرد وجود مصدر التتبع
يضرب:

تتبع من 0 إلى 1234

عندما قمنا بتنفيذ الكود myObject->m_myInt = 1234.، أطلق مصدر التتبع و
يتم توفير القيم السابقة واللاحقة تلقائيًا إلى حوض التتبع. الوظيفة
انتتريس ثم طبع هذا على الإخراج القياسي.

التواصل مع التكوين
إنّ TraceConnectWithoutContext المكالمة الموضحة أعلاه في المثال البسيط هي في الواقع جدًا
نادرا ما تستخدم في النظام. بشكل نموذجي ، فإن ملف التكوين يتم استخدام النظام الفرعي لتحديد التتبع
مصدر في النظام باستخدام ما يسمى التكوين مسار. وقد رأينا مثالاً على ذلك في
القسم السابق حيث قمنا بربط حدث "CourseChange" عندما كنا نجربه
الثالث.cc.

تذكر أننا قمنا بتحديد مصدر تتبع لطباعة معلومات تغيير المسار من التنقل
نماذج من المحاكاة لدينا. يجب أن يكون الآن أكثر وضوحًا بالنسبة لك ما هي هذه الوظيفة
عمل:

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

عندما قمنا بتوصيل مصدر التتبع "CourseChange" بمصرف التتبع أعلاه، استخدمنا ملف
مسار التكوين لتحديد المصدر عندما قمنا بترتيب اتصال بين المحدد مسبقا
مصدر التتبع ومغسلة التتبع الجديدة:

std::ostringstream oss;
نظام التشغيل << "/NodeList/"
<< wifiStaNodes.Get (nWifi - 1)->GetId ()
<< "/$ns3::MobilityModel/CourseChange";

التكوين::Connect (oss.str ()، MakeCallback (&CourseChange));

دعونا نحاول أن نفهم بعض الشيء ما يعتبر أحيانًا رمزًا غامضًا نسبيًا.
ولأغراض المناقشة، افترض أن رقم العقدة الذي تم إرجاعه بواسطة ملف معرف() is
"7". في هذه الحالة، المسار أعلاه هو

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

يجب أن يكون الجزء الأخير من مسار التكوين عبارة عن السمة ل هدف. في الواقع، إذا كان لديك
مؤشر إلى هدف الذي يحتوي على "CourseChange" السمة مفيد، يمكنك كتابة هذا
تماما كما فعلنا في المثال السابق. أنت تعلم الآن أننا نقوم عادةً بالتخزين
مؤشرات لدينا العقد في NodeContainer. في ال الثالث.cc على سبيل المثال، العقد ذات الاهتمام
يتم تخزينها في wifiStaNodes NodeContainer. في الواقع، أثناء وضع المسار معًا،
استخدمنا هذه الحاوية للحصول على Ptr الذي كنا نسميه معرف(). كان باستطاعتنا ان
استخدم هذا Ptr للاتصال بطريقة الاتصال مباشرة:

بي تي آر theObject = wifiStaNodes.Get (nWifi - 1);
theObject->TraceConnectWithoutContext ("CourseChange"، MakeCallback (&CourseChange));

في مجلة الثالث.cc على سبيل المثال، أردنا بالفعل تسليم "سياق" إضافي
باستخدام معلمات رد الاتصال (والتي سيتم شرحها أدناه) حتى نتمكن بالفعل من استخدام
الكود المعادل التالي:

بي تي آر theObject = wifiStaNodes.Get (nWifi - 1);
theObject->TraceConnect ("CourseChange"، MakeCallback (&CourseChange));

وتبين أن الكود الداخلي ل التكوين :: ConnectWithoutContext التكوين::اتصال
في الواقع العثور على بي تي آر والاتصال بالمناسب تتبع الاتصال الطريقة على الأقل
.

إنّ التكوين تأخذ الوظائف مسارًا يمثل سلسلة من هدف مؤشرات. كل شريحة
من المسار يتوافق مع سمة الكائن. الجزء الأخير هو سمة
الفائدة، ويجب كتابة المقاطع السابقة لاحتواء الكائنات أو العثور عليها. ال التكوين الكود
يوزع هذا المسار و"يسير فيه" حتى يصل إلى الجزء الأخير من المسار. بعد ذلك
يفسر الجزء الأخير على أنه السمة على آخر كائن تم العثور عليه أثناء المشي
طريق. ال التكوين وظائف ثم استدعاء المناسب تتبع الاتصال or
TraceConnectWithoutContext الطريقة على الكائن النهائي. دعونا نرى ما سيحدث بعد قليل
مزيد من التفاصيل عند السير على المسار أعلاه.

يشير الحرف "/" البادئة في المسار إلى ما يسمى مساحة الاسم. واحد من
مساحات الأسماء المحددة مسبقًا في نظام التكوين هي "NodeList" وهي قائمة تضم جميع ملفات
العقد في المحاكاة. تتم الإشارة إلى العناصر الموجودة في القائمة بواسطة مؤشرات في القائمة ، لذلك
يشير "/NodeList/7" إلى العقدة الثامنة في قائمة العقد التي تم إنشاؤها أثناء المحاكاة
(تبدأ مؤشرات الاستدعاء عند 0 '). هذه مرجع is في الواقع a ``بتر ` وهكذا أ
فئة فرعية من ns3 :: الكائن.

كما هو موضح في قسم نموذج الكائن في NS-3 دليل، ونحن نستفيد منها على نطاق واسع
تجميع الكائنات. هذا يسمح لنا بتكوين ارتباط بين الكائنات المختلفة
دون بناء شجرة وراثة معقدة أو تحديد الأشياء التي ستكون جزءًا منها مسبقًا
من عقدة. يمكن الوصول إلى كل كائن في التجميع من الكائنات الأخرى.

في مثالنا، يبدأ مقطع المسار التالي الذي يتم السير فيه بالحرف "$". هذا
يشير إلى نظام التكوين أن المقطع هو اسم نوع الكائن، لذلك أ
GETOBJECT يجب إجراء المكالمة للبحث عن هذا النوع. وتبين أن MobilityHelper
المستخدمة في الثالث.cc يرتب لتجميع، أو ربط، نموذج التنقل لكل من
لاسلكي العقد. عندما تقوم بإضافة "$" فإنك تطلب كائنًا آخر يحتوي على
من المفترض أنه تم تجميعها مسبقًا. يمكنك التفكير في هذا على أنه تبديل المؤشرات من
الأصلي بي تي آر كما هو محدد بواسطة "/NodeList/7" لنموذج التنقل المرتبط به ---
وهو من النوع ns3 :: MobilityModel. إذا كنت على دراية GETOBJECTلقد سألنا
النظام للقيام بما يلي:

بي تي آر MobilityModel = العقدة->GetObject ()

نحن الآن في آخر كائن في المسار، لذلك نوجه انتباهنا إلى سمات
هذا الكائن. ال MobilityModel تحدد الفئة سمة تسمى "CourseChange". أنت تستطيع
انظر هذا من خلال النظر في التعليمات البرمجية المصدر في src/mobility/model/mobility-model.cc
ابحث عن "CourseChange" في محررك المفضل. يجب أن تجد

.AddTraceSource ("CourseChange"،
"تغيرت قيمة الموضع و/أو متجه السرعة"،
MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace)،
"ns3::MobilityModel::CourseChangeCallback")

والتي يجب أن تبدو مألوفة جدًا في هذه المرحلة.

إذا كنت تبحث عن الإعلان المقابل للمتغير المتتبع الأساسي في
نموذج التنقل.h وسوف تجد

تتبع الاتصال > m_courseChangeTrace;

إعلان النوع تتبع الاتصال يحدد m_courseChangeTrace كقائمة خاصة
عمليات الاسترجاعات التي يمكن ربطها باستخدام وظائف التكوين الموضحة أعلاه. ال typedef و لـ
يتم تعريف توقيع وظيفة رد الاتصال أيضًا في ملف الرأس:

typedef void (* CourseChangeCallback)(Ptr * نموذج)؛

إنّ MobilityModel تم تصميم الفئة لتكون فئة أساسية توفر واجهة مشتركة لـ
جميع الفئات الفرعية المحددة. إذا قمت بالبحث حتى نهاية الملف، فسوف ترى ملف
الطريقة المحددة تسمى NotifyCourseChange():

باطل
MobilityModel::NotifyCourseChange (باطل) ثابت
{
m_courseChangeTrace(this);
}

سوف تستدعي الفئات المشتقة هذه الطريقة عندما تقوم بتغيير الدورة التدريبية لدعمها
اقتفاء أثر. تستدعي هذه الطريقة المشغل أو العامل() على الكامنة m_courseChangeTrace، التي
سيقوم بدوره باستدعاء جميع عمليات الاسترجاعات المسجلة، واستدعاء كافة أحواض التتبع التي
لديك مصلحة مسجلة في مصدر التتبع عن طريق استدعاء دالة التكوين.

لذا ، في الثالث.cc المثال الذي نظرنا إليه، كلما تم إجراء تغيير في الدورة التدريبية في أحد
RandomWalk2dMobilityModel المثيلات المثبتة، سيكون هناك NotifyCourseChange() دعوة
الذي يدعو إلى MobilityModel الطبقة الأساسية. كما رأينا أعلاه، وهذا يستدعي المشغل أو العامل()
on m_courseChangeTrace، والذي بدوره يستدعي أي أحواض تتبع مسجلة. في المثال،
كان الرمز الوحيد الذي يسجل الاهتمام هو الرمز الذي يوفر مسار التكوين.
ولذلك، فإن تغيير المسار الوظيفة التي تم ربطها من العقدة رقم سبعة ستكون
تم استدعاء رد الاتصال فقط.

القطعة الأخيرة من اللغز هي "السياق". تذكر أننا رأينا الناتج يبحث
شيء مثل ما يلي من الثالث.cc:

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

الجزء الأول من الإخراج هو السياق. إنه ببساطة الطريق الذي من خلاله
حدد رمز التكوين مصدر التتبع. في الحالة التي نظرنا إليها يمكن أن يكون هناك
أي عدد من مصادر التتبع في النظام يتوافق مع أي عدد من العقد
نماذج التنقل. يجب أن تكون هناك طريقة ما لتحديد مصدر التتبع الموجود بالفعل
الذي أطلق رد الاتصال. الطريقة السهلة هي التواصل مع التكوين::اتصال، في حين أن
of التكوين :: ConnectWithoutContext.

العثور على مصادر
السؤال الأول الذي يطرح حتماً على المستخدمين الجدد لنظام التتبع هو، "تمام،
I علم أن هناك يجب be تتبع تقارير عن مصادر العطور بدون العلبة in هيه محاكاة الأساسية، لكن كيف do I جد خارج ماذا
تتبع تقارير عن مصادر العطور بدون العلبة . متاح إلى أنا؟"

السؤال الثاني هو "تمام، I وجدت a تتبع مصدر، كيف do I الشكل خارج هيه التكوين مسار
إلى تستخدم متى I طريقة التنفيذ إلى هو - هي؟"

السؤال الثالث هو "تمام، I وجدت a تتبع مصدر هيه التكوين مسار، كيف do I الشكل
خارج ماذا هيه عائد أعلى نوع رسمي الحجج of my رد وظيفة حاجة إلى يكون؟"

والسؤال الرابع هو "تمام، I كتبته أن الكل in حصلت لا يصدق غريب خطأ
رسالة، ماذا in هيه العالم هل it يقصد؟"

وسوف نتناول كل واحد من هذه على حدة.

متوفرة مصادر
حسنا، I علم أن هناك يجب be تتبع تقارير عن مصادر العطور بدون العلبة in هيه محاكاة الأساسية، لكن كيف do I جد
خارج ماذا تتبع تقارير عن مصادر العطور بدون العلبة . متاح إلى لي؟

إجابة السؤال الأول تجدها في NS-3 وثائق واجهة برمجة التطبيقات. إذا ذهبت إلى
موقع المشروع على شبكة الإنترنت, NS-3 تنفيذ المشاريع ، ستجد رابطًا إلى "الوثائق" في شريط التنقل
حاجِز. إذا قمت بتحديد هذا الرابط، سيتم نقلك إلى صفحة الوثائق لدينا. هناك
رابط إلى "أحدث إصدار" والذي سينقلك إلى الوثائق الخاصة بأحدث إصدار ثابت
الافراج عن NS-3. إذا قمت بتحديد الرابط "وثائق API"، فسيتم نقلك إلى
NS-3 صفحة وثائق API.

في الشريط الجانبي، يجب أن تشاهد التسلسل الهرمي الذي يبدأ

· م.س-3

· ns-3 التوثيق

· جميع مصادر التتبع

· جميع الصفات

· جميع القيم العالمية

القائمة التي تهمنا هنا هي "All TraceSources". المضي قدما واختيار هذا الرابط.
سترى، ربما ليس من المستغرب جدًا، قائمة بجميع مصادر التتبع المتاحة
in NS-3.

على سبيل المثال، قم بالتمرير لأسفل إلى ns3 :: MobilityModel. سوف تجد إدخال ل

CourseChange: تم تغيير قيمة الموضع و/أو متجه السرعة

يجب أن تتعرف على هذا باعتباره مصدر التتبع الذي استخدمناه في ملف الثالث.cc مثال. يطلع
هذه القائمة ستكون مفيدة.

التكوين مسارات
حسنا، I وجدت a تتبع مصدر، كيف do I الشكل خارج هيه التكوين مسار إلى تستخدم متى I طريقة التنفيذ إلى
ذلك؟

إذا كنت تعرف الكائن الذي تهتم به، فانتقل إلى قسم "الوصف التفصيلي" لـ
سوف يسرد الفصل جميع مصادر التتبع المتاحة. على سبيل المثال، بدءًا من قائمة "الكل".
TraceSources،" انقر فوق ns3 :: MobilityModel الرابط الذي سوف يأخذك إلى
وثائق MobilityModel فصل. يوجد في أعلى الصفحة تقريبًا سطر واحد
وصف مختصر للفصل، ينتهي بالرابط "المزيد...". انقر على هذا الرابط للتخطي
ملخص واجهة برمجة التطبيقات (API) وانتقل إلى "الوصف التفصيلي" للفئة. عند نهاية ال
سيكون الوصف (حتى) ثلاث قوائم:

· التكوين مسارات: قائمة مسارات التكوين النموذجية لهذه الفئة.

· السمات: قائمة بجميع السمات التي توفرها هذه الفئة.

· تتبع المصادر: قائمة بجميع TraceSources المتاحة من هذا الفصل.

أولاً سنناقش مسارات التكوين.

لنفترض أنك عثرت للتو على مصدر التتبع "CourseChange" في ملف "All
TraceSources" وتريد معرفة كيفية الاتصال بها. أنت تعلم أنك كذلك
باستخدام (مرة أخرى، من الثالث.cc مثال) أ ns3::RandomWalk2dMobilityModel. ذلك إما
انقر فوق اسم الفئة في قائمة "All TraceSources"، أو ابحث عن
ns3::RandomWalk2dMobilityModel في "قائمة الفئات". وفي كلتا الحالتين يجب أن تبحث الآن
في صفحة "ns3::RandomWalk2dMobilityModel Class Reference".

إذا قمت الآن بالتمرير لأسفل إلى قسم "الوصف التفصيلي"، بعد قائمة الملخصات
أساليب وسمات الفصل الدراسي (أو انقر فقط على الرابط "المزيد..." في نهاية الفصل الدراسي
وصف مختصر في أعلى الصفحة) ستشاهد الوثائق الشاملة للملف
فصل. مع الاستمرار في التمرير لأسفل، ابحث عن قائمة "مسارات التكوين":
التكوين مسارات

ns3::RandomWalk2dMobilityModel يمكن الوصول إليه من خلال المسارات التالية مع
التكوين :: مجموعة التكوين::اتصال:

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

تخبرك الوثائق بكيفية الوصول إلى RandomWalk2dMobilityModel هدف. يقارن
السلسلة أعلاه مع السلسلة التي استخدمناها بالفعل في رمز المثال:

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

الفرق يرجع إلى حقيقة أن اثنين GETOBJECT يتم تضمين المكالمات في السلسلة الموجودة
في الوثائق. الأول، ل $ns3::MobilityModel سوف الاستعلام عن التجميع ل
الطبقة الأساسية. والثاني ضمنا GETOBJECT يدعو إلى $ns3::RandomWalk2dMobilityModel,
يتم استخدامه لإلقاء الفئة الأساسية على فئة التنفيذ الملموسة. وثائق
يظهر لك كلا من هذه العمليات. اتضح أن مصدر التتبع الفعلي أنت
تم العثور على البحث عنه في الفئة الأساسية.

انظر إلى الأسفل في قسم "الوصف التفصيلي" للحصول على قائمة مصادر التتبع.
سوف تجد
لم يتم تعريف TraceSources لهذا النوع.

تتبع المصادر تعريف in أصل فئة ``ns3::MobilityModel``

· تغيير المسار: تم تغيير قيمة الموضع و/أو متجه السرعة.

توقيع رد الاتصال: ns3::MobilityModel::CourseChangeCallback

هذا هو بالضبط ما تحتاج إلى معرفته. تم العثور على المصدر التتبع للاهتمام في
ns3 :: MobilityModel (الذي كنت تعرفه على أي حال). الشيء المثير للاهتمام هو هذا الجزء من واجهة برمجة التطبيقات
تخبرك الوثائق أنك لست بحاجة إلى هذا التمثيل الإضافي في مسار التكوين أعلاه
انتقل إلى الفئة المحددة، نظرًا لأن مصدر التتبع موجود بالفعل في الفئة الأساسية.
ولذلك الإضافية GETOBJECT غير مطلوب ويمكنك ببساطة استخدام المسار:

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

والذي يتطابق تمامًا مع مسار المثال:

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

وكجانب، هناك طريقة أخرى للعثور على مسار التكوين وهي البقرى حول في NS-3 مصدر برنامج
لشخص قد اكتشف ذلك بالفعل. يجب أن تحاول دائمًا تقليد شخص آخر
رمز العمل قبل البدء في كتابة الكود الخاص بك. جرب شيئًا مثل:

$ العثور على . -الاسم '*.cc' | xargs grep CourseChange | اتصال جريب

وقد تجد إجابتك مع رمز العمل. على سبيل المثال، في هذه الحالة،
src/mobility/examples/main-random-topology.cc لديه شيء في انتظارك لاستخدامه:

التكوين::الاتصال ("/NodeList/*/$ns3::MobilityModel/CourseChange"،
MakeCallback (&CourseChange));

سنعود إلى هذا المثال بعد قليل.

أن نتواصل معك التوقيعات
حسنا، I وجدت a تتبع مصدر هيه التكوين مسار، كيف do I الشكل خارج ماذا هيه عائد أعلى نوع
رسمي الحجج of my رد وظيفة حاجة إلى يكون؟

أسهل طريقة هي فحص توقيع رد الاتصال typedef و، والذي ورد في
"توقيع رد الاتصال" لمصدر التتبع في "الوصف التفصيلي" للفئة، مثل
هو مبين أعلاه.

تكرار إدخال مصدر التتبع "CourseChange" من ns3::RandomWalk2dMobilityModel we
يملك:

· تغيير المسار: تم تغيير قيمة الموضع و/أو متجه السرعة.

توقيع رد الاتصال: ns3::MobilityModel::CourseChangeCallback

يتم إعطاء توقيع رد الاتصال كرابط إلى الجهة ذات الصلة typedef وحيث نجد
typedef و باطل (* دورة تغيير رد الاتصال)(const الأمراض المنقولة جنسيا :: سلسلة سياق الكلام، بي تي آر
نموذج التنقل> * نموذج)؛

تتبع الاتصال التوقيع على إشعارات تغيير الدورة التدريبية.

إذا كان رد الاتصال متصلاً باستخدام ConnectWithoutContext حذف ال سياق الكلام حجة من
التوقيع.

المعلمات:
[في] السياق سلسلة السياق التي يوفرها مصدر التتبع.
[في] نموذج MobilityModel الذي يغير المسار.

كما هو مذكور أعلاه، لرؤية هذا قيد الاستخدام البقرى حول في NS-3 قاعدة التعليمات البرمجية على سبيل المثال. المثال
أعلاه، من src/mobility/examples/main-random-topology.cc، يربط "CourseChange"
مصدر التتبع إلى تغيير المسار الوظيفة في نفس الملف:

الفراغ ثابت
CourseChange (std::string context، Ptr نموذج)
{

}

لاحظ أن هذه الوظيفة:

· يأخذ وسيطة سلسلة "السياق"، والتي سنصفها في دقيقة واحدة. (إذا كان رد الاتصال
يتم توصيله باستخدام ConnectWithoutContext وظيفة سياق الكلام ستكون الحجة
تم حذفه.)

· لديه MobilityModel يتم توفيرها كوسيطة أخيرة (أو الوسيطة الوحيدة if
ConnectWithoutContext يستخدم).

· عائدات باطل.

إذا، بالصدفة، لم يتم توثيق توقيع رد الاتصال، ولا توجد أمثلة لذلك
العمل من خلال تحديد توقيع وظيفة رد الاتصال الصحيح يمكن أن يكون أمرًا صعبًا
معرفة في الواقع من التعليمات البرمجية المصدر.

قبل الشروع في شرح التعليمات البرمجية، سأكون لطيفًا وأخبرك بطريقة بسيطة
لمعرفة ذلك: ستكون قيمة الإرجاع لرد الاتصال الخاص بك دائمًا باطل. الرسمية
قائمة المعلمات ل تتبع الاتصال يمكن العثور عليها من قائمة معلمات القالب في ملف
تصريح. تذكر أنه في مثالنا الحالي، هذا موجود نموذج التنقل.hحيث نحن
لقد وجدت سابقا:

تتبع الاتصال > m_courseChangeTrace;

توجد مراسلات فردية بين قائمة معلمات القالب في ملف
الإعلان والوسائط الرسمية لوظيفة رد الاتصال. هنا، هناك واحد
معلمة القالب، وهي بي تي آر نموذج التنقل>. هذا يخبرك أنك بحاجة إلى
الدالة التي ترجع الفراغ وتأخذ بي تي آر نموذج التنقل>. على سبيل المثال:

باطل
تغيير الدورة (Ptr نموذج)
{

}

هذا كل ما تحتاجه إذا كنت تريد ذلك التكوين :: ConnectWithoutContext. إذا كنت تريد السياق،
تحتاج إلى التكوين::اتصال ثم استخدم وظيفة رد الاتصال التي تأخذ سياق سلسلة
وسيطات القالب:

باطل
CourseChange (const std::string context، Ptr نموذج)
{

}

إذا كنت تريد التأكد من أن الخاص بك دورة تغيير رد الاتصال الوظيفة مرئية فقط في جهازك
الملف المحلي، يمكنك إضافة الكلمة الأساسية ساكن وتوصل إلى:

الفراغ ثابت
CourseChange (const std::string path, Ptr نموذج)
{

}

وهو بالضبط ما استخدمناه في الثالث.cc مثال.

تطبيق
هذا القسم اختياري تمامًا. ستكون الرحلة وعرةً، خاصة بالنسبة لهؤلاء
غير مطلع على تفاصيل القوالب. ومع ذلك، إذا تجاوزت هذا، سيكون لديك
مقبض جيد جدًا على الكثير من NS-3 التعابير منخفضة المستوى.

لذا، مرة أخرى، دعونا نتعرف على توقيع وظيفة رد الاتصال المطلوب لـ
مصدر التتبع "CourseChange". سيكون هذا مؤلمًا، لكن ما عليك سوى القيام بذلك
مرة واحدة. بعد الانتهاء من هذا، سوف تكون قادرًا على مجرد إلقاء نظرة على تتبع الاتصال
فهمته.

أول شيء نحتاج إلى النظر إليه هو الإعلان عن مصدر التتبع. أذكر ذلك
في هذا نموذج التنقل.hحيث وجدنا سابقاً:

تتبع الاتصال > m_courseChangeTrace;

هذا الإعلان هو لقالب. معلمة القالب موجودة داخل الأقواس الزاوية،
لذلك نحن مهتمون حقا بمعرفة ما هو ذلك تتبع الاتصال<> يكون. اذا كنت تمتلك
ليس لدي أدنى فكرة عن مكان العثور على هذا، البقرى هو صديقك

من المحتمل أن نكون مهتمين بنوع من الإعلان في NS-3 المصدر، إذن
أول تغيير في SRC الدليل. إذن، نحن نعلم أن هذا الإعلان سيتعين عليه القيام بذلك
يكون في نوع من ملف الرأس، لذلك فقط البقرى لذلك باستخدام:

$ العثور على . -الاسم '*.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 ...

وتبين أن كل هذا يأتي من ملف الرأس تتبع رد الاتصال. h الذي يبدو
واعدة جدا. يمكنك بعد ذلك إلقاء نظرة على نموذج التنقل.h ونرى أن هناك خط
مما يؤكد هذا الحدس:

#تتضمن "ns3/traced-callback.h"

بالطبع، كان بإمكانك أن تنظر إلى هذا من الاتجاه الآخر وتبدأ بالنظر إليه
يتضمن في نموذج التنقل.h وملاحظة تضمين تتبع رد الاتصال. h
استنتاج أن هذا يجب أن يكون الملف الذي تريده.

وفي كلتا الحالتين، فإن الخطوة التالية هي إلقاء نظرة src/core/model/traced-callback.h in
المحرر المفضل لديك لمعرفة ما يحدث.

سترى تعليقًا في أعلى الملف والذي من المفترض أن يكون مريحًا:
يحتوي ns3::TracedCallback على نفس واجهة برمجة التطبيقات تقريبًا مثل ns3::Callback العادي ولكن
بدلاً من إعادة توجيه المكالمات إلى وظيفة واحدة (كما يفعل عادةً ns3::Callback)،
يقوم بإعادة توجيه المكالمات إلى سلسلة من ns3::Callback.

يجب أن يبدو هذا مألوفًا جدًا ويتيح لك معرفة أنك على الطريق الصحيح.

ستجده بعد هذا التعليق

نموذج
اسم الكتابة T3 = فارغ، اسم الكتابة T4 = فارغ،
اسم الكتابة T5 = فارغ، اسم الكتابة T6 = فارغ،
اسم الكتابة T7 = فارغ، اسم الكتابة T8 = فارغ>
فئة TracedCallback
{


يخبرك هذا أن TracedCallback عبارة عن فئة نموذجية. لديها ثمانية نوع ممكن
المعلمات مع القيم الافتراضية. ارجع وقارن هذا مع التصريح الذي أنت عليه
محاولا أن أفهم:

تتبع الاتصال > m_courseChangeTrace;

إنّ أكتب اسم T1 في إعلان الفئة النموذجية يتوافق مع بي تي آر
نموذج التنقل> في الإعلان أعلاه. يتم ترك جميع معلمات النوع الأخرى كما هي
الإعدادات الافتراضية. إن النظر إلى المُنشئ لا يخبرك كثيرًا حقًا. المكان الوحيد الذي
لقد رأيت اتصالاً تم إجراؤه بين وظيفة رد الاتصال الخاصة بك ونظام التتبع
في ال التواصل ConnectWithoutContext المهام. إذا قمت بالتمرير لأسفل، فسترى أ
ConnectWithoutContext الطريقة هنا :

نموذج
اسم الكتابة T3، اسم الكتابة T4،
اسم الكتابة T5، اسم الكتابة T6،
اسم الكتابة T7، اسم الكتابة 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 مع بي تي آر نموذج التنقل>.

باطل
تتبع الاتصال ::ConnectWithoutContext ... cb
{
أتصل مرة أخرى > سي بي؛
cb.Assign (رد الاتصال);
m_callbackList.push_back (cb);
}

يمكنك الآن رؤية تنفيذ كل ما تحدثنا عنه. الرمز
ينشئ رد اتصال من النوع الصحيح ويعين وظيفتك له. هذا ال
ما يعادل الرابطة = MyFunction ناقشنا في بداية هذا القسم. الرمز
ثم يضيف رد الاتصال إلى قائمة ردود الاتصال لهذا المصدر. الشيء الوحيد المتبقي هو
لننظر إلى تعريف رد الاتصال. باستخدام نفس البقرى خدعة كما اعتدنا أن نجد
تتبع الاتصال، ستتمكن من العثور على هذا الملف ./core/callback.h هو الذي نحن
بحاجة للنظر في.

إذا نظرت إلى أسفل الملف، سترى الكثير من الأشياء التي ربما تكون غير مفهومة تقريبًا
رمز القالب. ستصل في النهاية إلى بعض وثائق واجهة برمجة التطبيقات (API) الخاصة برد الاتصال
فئة القالب، بالرغم من ذلك. لحسن الحظ، هناك بعض اللغة الإنجليزية:
أن نتواصل معك فئة القالب.

يطبق قالب الفصل هذا نمط تصميم Functor. يتم استخدامه للإعلان عن
نوع أ أن نتواصل معك :

· تمثل وسيطة القالب غير الاختيارية الأولى نوع الإرجاع الخاص بالرد.

· تمثل وسائط القالب المتبقية (اختيارية) نوع القالب اللاحق
الحجج إلى رد الاتصال.

· يتم دعم ما يصل إلى تسع وسائط.

نحن نحاول معرفة ما

أتصل مرة أخرى > سي بي؛

يعني التصريح. الآن نحن في وضع يسمح لنا أن نفهم أن الأول (غير اختياري)
حجة القالب, باطليمثل نوع الإرجاع لرد الاتصال. الثاني
(اختياري) وسيطة القالب، بي تي آر نموذج التنقل> يمثل النوع الأول
حجة لرد الاتصال.

رد الاتصال المعني هو وظيفتك لتلقي أحداث التتبع. من هذا يمكنك
استنتج أنك بحاجة إلى دالة ترجع باطل ويأخذ بي تي آر نموذج التنقل>.
على سبيل المثال،

باطل
دورة تغيير الاتصال (Ptr نموذج)
{

}

هذا كل ما تحتاجه إذا كنت تريد ذلك التكوين :: ConnectWithoutContext. إذا كنت تريد السياق،
تحتاج إلى التكوين::اتصال واستخدم وظيفة رد الاتصال التي تأخذ سياق سلسلة. هذا
هو لأن التواصل ستوفر لك الوظيفة السياق. انك سوف تحتاج:

باطل
CourseChangeCallback (std::string context, Ptr نموذج)
{

}

إذا كنت تريد التأكد من أن الخاص بك دورة تغيير رد الاتصال مرئي فقط في ملفك المحلي،
يمكنك إضافة الكلمة الرئيسية ساكن وتوصل إلى:

الفراغ ثابت
CourseChangeCallback (std::string path, Ptr نموذج)
{

}

وهو بالضبط ما استخدمناه في الثالث.cc مثال. ربما يجب عليك الآن العودة و
أعد قراءة القسم السابق (خذ كلمتي من أجلها).

إذا كنت مهتمًا بمعرفة مزيد من التفاصيل فيما يتعلق بتنفيذ عمليات الاسترجاعات، فلا تتردد
لإلقاء نظرة على NS-3 يدوي. وهي واحدة من التركيبات الأكثر استخدامًا في
الأجزاء ذات المستوى المنخفض من NS-3. وهو، في رأيي، شيء أنيق للغاية.

TracedValues
في وقت سابق من هذا القسم، قدمنا ​​​​جزءًا بسيطًا من التعليمات البرمجية التي تستخدم ملف
TracedValue لتوضيح أساسيات كود التتبع. لقد تجاهلنا للتو
ما هي قيمة TracedValue وكيفية العثور على نوع الإرجاع والوسائط الرسمية له
رد الاتصال.

كما ذكرنا الملف تتبع القيمة يجلب الإقرارات المطلوبة للتتبع
من البيانات التي تخضع لدلالات القيمة. بشكل عام، دلالات القيمة تعني فقط أنك تستطيع ذلك
تمرير الكائن نفسه، بدلاً من تمرير عنوان الكائن. نحن نمتد
يتضمن هذا المتطلب المجموعة الكاملة من عوامل تشغيل نمط المهمة الموجودة
محددة مسبقًا لأنواع البيانات القديمة (POD):

┌────────────────────────────┬───── ────────┐
عامل التشغيل = (المهمة) │ │
├────────────────────────────┼───── ────────┤
المشغل*=المشغل/=
├────────────────────────────┼───── ────────┤
عامل التشغيل+=المشغل-=
├────────────────────────────┼───── ────────┤
المشغل++ (كلا البادئة و │ │
│postfix) │ │
├────────────────────────────┼───── ────────┤
المشغل أو العامل-- (كلا البادئة و │ │
│postfix) │ │
├────────────────────────────┼───── ────────┤
عامل <<=عامل>>=
├────────────────────────────┼───── ────────┤
المشغل&=المشغل|=
├────────────────────────────┼───── ────────┤
عامل التشغيل%=المشغل ^=
└────────────────────────────┴───── ────────┘

ما يعنيه كل هذا حقًا هو أنك ستتمكن من تتبع جميع التغييرات التي تم إجراؤها باستخدام تلك التغييرات
عوامل التشغيل إلى كائن C++ الذي له دلالات قيمة.

إنّ قيمة التتبع<> يوفر الإعلان الذي رأيناه أعلاه البنية التحتية التي تزيد من تحميل
المشغلين المذكورين أعلاه ويحركون عملية رد الاتصال. عند استخدام أي من المشغلين
أعلاه مع أ TracedValue وسوف توفر كل من القيمة القديمة والجديدة لهذا المتغير،
في هذه الحالة int32_t قيمة. بالتفتيش على TracedValue إعلان، ونحن نعرف
سوف تحتوي وظيفة بالوعة التتبع على وسيطات (مقدار ثابت int32_t القيمة القديمة, CONST int32_t قيمة جديدة).
نوع الإرجاع لـ أ TracedValue وظيفة رد الاتصال هي دائما باطل، لذلك المتوقع
سيكون توقيع رد الاتصال:

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

إنّ .AddTraceSource في ال GetTypeId توفر الطريقة "الخطافات" المستخدمة لتوصيل
تتبع المصدر إلى العالم الخارجي من خلال نظام التكوين. لقد ناقشنا بالفعل
agruments الثلاثة الأولى ل AddTraceSource: اسم السمة لنظام التكوين، مساعدة
السلسلة وعنوان عضو بيانات فئة TracedValue.

وسيطة السلسلة النهائية، "ns3::Traced::Value::Int32" في المثال، هي اسم
typedef و لتوقيع وظيفة رد الاتصال. نحن بحاجة إلى تحديد هذه التوقيعات،
وإعطاء اسم النوع المؤهل بالكامل ل AddTraceSource، لذا فإن وثائق واجهة برمجة التطبيقات (API) يمكنها ذلك
ربط مصدر التتبع بتوقيع الوظيفة. بالنسبة لـ TracedValue، التوقيع هو
واضح؛ بالنسبة إلى TracedCallbacks، رأينا بالفعل أن مستندات واجهة برمجة التطبيقات (API) تساعد حقًا.

لابيلا ريال مثال
لنقم بمثال مأخوذ من أحد أشهر الكتب حول TCP. "" تي سي بي / آي بي
المصور، المجلد الأول: البروتوكولات،" بقلم دبليو ريتشارد ستيفنز هو كتاب كلاسيكي. لقد انقلبت للتو
فتح الكتاب وركض عبر قطعة أرض جميلة لكل من نافذة الازدحام والتسلسل
الأرقام مقابل الوقت في الصفحة 366. يسمي ستيفنز هذا، "الشكل 21.10. قيمة cwnd و
أرسل الرقم التسلسلي أثناء إرسال البيانات." دعنا نعيد إنشاء الجزء cwnd
من تلك المؤامرة في NS-3 باستخدام نظام التتبع و غنوبلوت.

متوفرة مصادر
أول شيء يجب التفكير فيه هو كيف نريد الحصول على البيانات. ما هو أننا
بحاجة لتتبع؟ لذلك دعونا نراجع قائمة "جميع مصادر التتبع" لمعرفة ما يتعين علينا العمل عليه
مع. أذكر أن هذا موجود في NS-3 وثائق واجهة برمجة التطبيقات. إذا قمت بالتمرير خلال
القائمة، ستجد في النهاية:
ns3::TcpNewReno

· CongestionWindow: نافذة ازدحام اتصال TCP

· SlowStartThreshold: عتبة البدء البطيء لـ TCP (بايت)

اتضح أن NS-3 يعيش تنفيذ TCP (في الغالب) في الملف
src/internet/model/tcp-socket-base.cc أثناء وجود متغيرات التحكم في الازدحام في ملفات مثل
as src/internet/model/tcp-newreno.cc. إذا كنت لا تعرف هذا a بداهة، يمكنك استخدام ال
العودية البقرى الخدعة:

$ العثور على . -الاسم '*.cc' | xargs grep -i tcp

ستجد صفحة تلو الأخرى لمثيلات برنامج التعاون الفني التي توجهك إلى هذا الملف.

إحضار وثائق الفصل لـ TcpNewReno والانتقال إلى قائمة
سوف تجد TraceSources
تتبع المصادر

· CongestionWindow: نافذة ازدحام اتصال TCP

توقيع رد الاتصال: ns3::Traced::Value::Uint322Callback

النقر على رد الاتصال typedef و الرابط الذي نرى فيه التوقيع الذي تعرفه الآن:

typedef void(* ns3::Traced::Value::Int32Callback)(const int32_t oldValue، const int32_t newValue)

يجب أن تفهم الآن هذا الرمز بالكامل. إذا كان لدينا مؤشر إلى TcpNewReno,
نستطيع تتبع الاتصال إلى مصدر التتبع "CongestionWindow" إذا قدمنا ​​ملفًا مناسبًا
هدف رد الاتصال. هذا هو نفس نوع مصدر التتبع الذي رأيناه في المثال البسيط
في بداية هذا القسم، إلا أننا نتحدث عنه uint32_t بدلا من
int32_t. ونحن نعلم أنه يتعين علينا توفير وظيفة رد الاتصال بهذا التوقيع.

العثور على أمثلة
من الأفضل دائمًا محاولة العثور على كود عمل يمكنك تعديله بدلاً من ذلك
من البدء من الصفر. لذا فإن أول أمر في العمل الآن هو العثور على بعض التعليمات البرمجية التي
يربط بالفعل مصدر التتبع "CongestionWindow" ويرى ما إذا كان بإمكاننا تعديله. كل عادة،
البقرى صديقك:

$ العثور على . -الاسم '*.cc' | xargs grep CongestionWindow

سيشير هذا إلى اثنين من المرشحين الواعدين: أمثلة/tcp/tcp-large-transfer.cc
src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc.

لم نقم بزيارة أي من أكواد الاختبار بعد، لذلك دعونا نلقي نظرة هناك. سوف تفعلها
عادةً ما تجد أن كود الاختبار ضئيل إلى حد ما، لذلك ربما يكون هذا رهانًا جيدًا جدًا.
ساعات العمل src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc في محررك المفضل وابحث عنه
"نافذة الازدحام". سوف تجد،

ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow"،
MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, this));

يجب أن يبدو هذا مألوفًا جدًا بالنسبة لك. لقد ذكرنا أعلاه أنه إذا كان لدينا مؤشر إلى
TcpNewReno، نستطيع تتبع الاتصال إلى مصدر التتبع "CongestionWindow". هذا هو بالضبط
ما لدينا هنا؛ لذلك اتضح أن هذا السطر من التعليمات البرمجية يفعل بالضبط ما نريده.
دعنا نمضي قدمًا ونستخرج الكود الذي نحتاجه من هذه الوظيفة (Ns3TcpCwndTestCase1::DoRun
(فارغ)). إذا نظرت إلى هذه الوظيفة، ستجد أنها تبدو وكأنها NS-3
النصي. اتضح أن هذا هو بالضبط ما هو عليه. وهو برنامج نصي يتم تشغيله بواسطة الاختبار
الإطار، حتى نتمكن فقط من سحبه ولفه فيه رئيسي بدلا من في دور. بدلاً
بدلاً من السير خلال هذا، خطوة بخطوة، قدمنا ​​الملف الناتج عن النقل
هذا الاختبار يعود إلى مواطن NS-3 النصي -- أمثلة/البرنامج التعليمي/fifth.cc.

التفاعل أثر مصادر
إنّ Fifth.cc يوضح المثال قاعدة مهمة للغاية يجب أن تفهمها
قبل استخدام أي نوع من مصادر التتبع: يجب عليك التأكد من أن هدف أ
التكوين::اتصال الأمر موجود قبل محاولة استخدامه. وهذا لا يختلف عن القول
يجب إنشاء مثيل للكائن قبل محاولة الاتصال به. على الرغم من أن هذا قد يبدو واضحا
عندما يتم ذكره بهذه الطريقة، فإنه يعرقل العديد من الأشخاص الذين يحاولون استخدام النظام للمرة الأولى
مرة.

دعونا نعود إلى الأساسيات للحظة. هناك ثلاث مراحل تنفيذ أساسية موجودة
أي وقت NS-3 النصي. تسمى المرحلة الأولى أحيانًا "وقت التكوين" أو "الإعداد".
الوقت "، ويوجد خلال الفترة التي رئيسي وظيفة البرنامج النصي الخاص بك قيد التشغيل، ولكن
قبل محاكي :: تشغيل يسمى. تسمى المرحلة الثانية أحيانًا "وقت المحاكاة"
وموجود خلال الفترة الزمنية عندما محاكي :: تشغيل تنفذ أحداثها بنشاط.
وبعد الانتهاء من تنفيذ المحاكاة، محاكي :: تشغيل سوف تعود السيطرة مرة أخرى إلى
هيه رئيسي وظيفة. عندما يحدث هذا، يدخل البرنامج النصي ما يمكن أن يسمى "Teardown
المرحلة،" وهي عندما يتم تفكيك الهياكل والكائنات التي تم إنشاؤها أثناء الإعداد و
صدر.

ولعل الخطأ الأكثر شيوعًا عند محاولة استخدام نظام التتبع هو افتراض ذلك
الكيانات التي تم إنشاؤها بشكل ديناميكي أثناء محاكاة الوقت متوفرة أثناء التكوين
وقت. على وجه الخصوص، أ NS-3 البريزة هو كائن ديناميكي غالبًا ما يتم إنشاؤه بواسطة التطبيقات إلى
التواصل بين العقد. و NS-3 التطبيق يحتوي دائمًا على "وقت البدء" و"التوقف".
"الوقت" المرتبط به. في الغالبية العظمى من الحالات، التطبيق لن تحاول
لإنشاء كائن ديناميكي حتى StartApplication يتم استدعاء الطريقة في بعض "Start
الوقت". وذلك للتأكد من تكوين المحاكاة بالكامل قبل التطبيق
يحاول القيام بأي شيء (ماذا سيحدث إذا حاول الاتصال بعقدة غير موجودة
حتى الآن خلال وقت التكوين؟). ونتيجة لذلك، خلال مرحلة التكوين لا يمكنك ذلك
قم بتوصيل مصدر التتبع بمصرف التتبع إذا تم إنشاء أحدهما ديناميكيًا أثناء
محاكاة.

الحلان لهذا اللغز هما

1. قم بإنشاء حدث محاكاة يتم تشغيله بعد إنشاء الكائن الديناميكي وربطه
تتبع عند تنفيذ هذا الحدث؛ أو

2. قم بإنشاء الكائن الديناميكي في وقت التكوين، ثم قم بربطه ثم تسليم الكائن إليه
النظام الذي سيتم استخدامه أثناء وقت المحاكاة.

لقد اتخذنا النهج الثاني في Fifth.cc مثال. هذا القرار يتطلب منا أن نخلق
هيه اسم التطبيق التطبيق، والغرض كله هو اتخاذ البريزة كمعامل.

تجول: Fifth.cc
الآن، دعونا نلقي نظرة على مثال البرنامج الذي أنشأناه من خلال تشريح الازدحام
اختبار النافذة. يفتح أمثلة/البرنامج التعليمي/fifth.cc في محررك المفضل يجب أن ترى
بعض التعليمات البرمجية المألوفة المظهر:

/ * - * - الوضع: C ++ ؛ نمط ملف c: "gnu" ؛ وضع علامات الجدولة البادئة: لا شيء ؛ - * - * /
/*
* هذا البرنامج مجاني ؛ يمكنك إعادة توزيعه و / أو تعديله
* بموجب شروط رخصة جنو العمومية الإصدار 2 كـ
* نشرته مؤسسة البرمجيات الحرة ؛
*
* يتم توزيع هذا البرنامج على أمل أن يكون مفيدا ،
* ولكن بدون أي ضمان ؛ حتى بدون الضمان الضمني لـ
* القابلية للتسويق أو الملاءمة لغرض معين. انظر
* رخصة جنو العمومية لمزيد من التفاصيل.
*
* يجب أن تكون قد تلقيت نسخة من رخصة جنو العمومية العامة
* مع هذا البرنامج ؛ إذا لم يكن كذلك ، فاكتب إلى البرمجيات الحرة
* المؤسسة، إنكلود.، 59 تيمبل بليس، جناح 330، بوسطن، MA 02111-1307 الولايات المتحدة الأمريكية
*/

#يشمل
# تضمين "ns3 / core-module.h"
# تضمين "ns3 / network-module.h"
# تضمين "ns3 / internet-module.h"
# تضمين "ns3 / point-to-point-module.h"
#include "ns3 / applications-module.h"

باستخدام مساحة الاسم ns3 ؛

NS_LOG_COMPONENT_DEFINE ("مثال النص الخامس")؛

لقد تم تغطية كل هذا، لذلك لن نعيد صياغته. الأسطر التالية من المصدر هي
رسم توضيحي للشبكة وتعليق يتناول المشكلة الموضحة أعلاه البريزة.

// ========================================================================================= ========================================
//
// العقدة 0 العقدة 1
// ++----------------++++----------------
// | ns-3 TCP | | ns-3 TCP |
// ++----------------++++----------------
// | 10.1.1.1 | | 10.1.1.2 |
// ++----------------++++----------------
// | من نقطة إلى نقطة | | من نقطة إلى نقطة |
// ++----------------++++----------------
// | |
// +---------------------+
// 5 ميجابت في الثانية، 2 مللي ثانية
//
//
// نريد إلقاء نظرة على التغييرات في نافذة ازدحام ns-3 TCP. نحن نحتاج
// لزيادة التدفق وربط سمة CongestionWindow بالمقبس
// المرسل. عادةً ما يستخدم المرء تطبيق التشغيل والإيقاف لإنشاء ملف
// التدفق، ولكن هذا به بعض المشاكل. أولاً، مقبس التشغيل والإيقاف
// لم يتم إنشاء التطبيق حتى وقت بدء التطبيق، لذلك لن نقوم بذلك
// قادر على ربط المقبس (الآن) في وقت التكوين. ثانيا، حتى لو كنا
// يمكن ترتيب مكالمة بعد وقت البدء، والمأخذ ليس عامًا، لذلك نحن
// لم أستطع الوصول إليه.
//
// لذا، يمكننا إعداد نسخة بسيطة من تطبيق التشغيل والإيقاف الذي يفعل ما
// نحن نريد. على الجانب الإيجابي، لا نحتاج إلى كل التعقيد الذي تتسم به عملية التشغيل والإيقاف
// طلب. على الجانب السلبي، ليس لدينا مساعد، لذا علينا الحصول عليه
// أكثر قليلاً منخرطًا في التفاصيل، لكن هذا تافه.
//
// لذا أولاً، نقوم بإنشاء مأخذ توصيل ونجري اتصال التتبع عليه؛ ثم نمر
// هذا المقبس في مُنشئ تطبيقنا البسيط الذي قمنا به بعد ذلك
// التثبيت في العقدة المصدر.
// ========================================================================================= ========================================
//

وينبغي أن يكون هذا أيضًا واضحًا بذاته.

الجزء التالي هو إعلان اسم التطبيق التطبيق التي وضعناها معًا للسماح
هيه البريزة ليتم إنشاؤها في وقت التكوين.

فئة MyApp: التطبيق العام
{
الجمهور:

تطبيقي ()؛
الظاهري ~MyApp();

إعداد باطل (Ptr المقبس، عنوان العنوان، uint32_t حجم الحزمة،
uint32_t nPackets، DataRate dataRate)؛

خاص:
StartApplication باطلة افتراضية (باطلة)؛
StopApplication باطل افتراضي (باطل)؛

باطلة جدولة (باطلة)؛
باطلة SendPacket (باطلة)؛

بي تي آر m_socket;
العنوان م_بير؛
uint32_t m_packetSize;
uint32_t m_nPackets;
DataRate m_dataRate;
معرف الحدث m_sendEvent;
منطقي m_running؛
uint32_t m_packetsSent;
};

يمكنك أن ترى أن هذه الفئة ترث من NS-3 التطبيق فصل. نلقي نظرة على
src/network/model/application.h إذا كنت مهتمًا بما هو موروث. ال اسم التطبيق
الطبقة ملزمة بتجاوز StartApplication StopApplication طُرق. هؤلاء
يتم استدعاء الأساليب تلقائيًا عندما اسم التطبيق مطلوب لبدء وإيقاف إرسال البيانات
أثناء المحاكاة.

البدء / التوقف التطبيقات
من المفيد قضاء بعض الوقت في شرح كيفية بدء الأحداث فعليًا في
نظام. هذا تفسير آخر عميق إلى حد ما، ويمكن تجاهله إذا لم تكن كذلك
التخطيط للمغامرة في أعماق النظام. ومع ذلك فهو مفيد في ذلك
تتناول المناقشة كيفية عمل بعض الأجزاء المهمة جدًا NS-3 العمل ويكشف بعض
التعابير الهامة. إذا كنت تخطط لتنفيذ نماذج جديدة، فمن المحتمل أنك تريد ذلك
فهم هذا القسم.

الطريقة الأكثر شيوعًا لبدء ضخ الأحداث هي البدء التطبيق. ويتم ذلك كما
نتيجة للخطوط المألوفة التالية (نأمل) لـ NS-3 النصي:

تطبيقات حاوية التطبيقات = ...
apps.Start (ثواني (1.0))؛
apps.Stop (ثواني (10.0))؛

رمز حاوية التطبيق (انظر src/network/helper/application-container.h إذا كنت كذلك
مهتم) حلقات من خلال التطبيقات والمكالمات الواردة،

التطبيق->SetStartTime (startTime)؛

نتيجة لل التطبيقات.ابدأ دعوة و

التطبيق->SetStopTime (stopTime)؛

نتيجة لل apps.Stop مكالمة.

النتيجة النهائية لهذه المكالمات هي أننا نريد الحصول على جهاز المحاكاة تلقائيًا
إجراء مكالمات إلى موقعنا التطبيقات لإخبارهم متى يبدأون ويتوقفون. في حالة
اسم التطبيق، يرث من الطبقة التطبيق ويتجاوز StartApplicationو
StopApplication. هذه هي الوظائف التي سيتم استدعاؤها بواسطة جهاز المحاكاة في
وقت مناسب. في حالة اسم التطبيق سوف تجد ذلك MyApp::StartApplication هل
الأولي مأزقو التواصل على المقبس، ثم يبدأ تدفق البيانات عن طريق الاتصال
MyApp::SendPacket. MyApp::StopApplication يتوقف عن توليد الحزم عن طريق إلغاء أي منها
أحداث الإرسال المعلقة ثم تقوم بإغلاق المقبس.

واحدة من الأشياء الجميلة حول NS-3 هو أنه يمكنك تجاهل التنفيذ تمامًا
تفاصيل عن كيفية التطبيق يتم استدعاؤه "تلقائيًا" بواسطة جهاز المحاكاة على اليمين
وقت. ولكن منذ أن غامرنا بالفعل بالعمق NS-3 بالفعل، دعونا نذهب لذلك.

إذا نظرتم src/network/model/application.cc ستجد أن SetStartTime طريقة
ل التطبيق فقط يقوم بتعيين متغير العضو m_startTime و SetStopTime طريقة
مجموعات فقط m_stopTime. ومن هناك، ومن دون بعض التلميحات، من المحتمل أن ينتهي المسار.

إن المفتاح لاستعادة المسار مرة أخرى هو معرفة أن هناك قائمة عالمية بجميع العناصر
العقد في النظام. كلما قمت بإنشاء عقدة في المحاكاة، سيظهر مؤشر لتلك العقدة
يضاف إلى العالمية NodeList.

الق نظرة على src/network/model/node-list.cc والبحث عن قائمة العقد::إضافة. الجمهور
يستدعي التنفيذ الثابت تطبيقًا خاصًا يسمى NodeListPriv::إضافة. هذا
هو رمز شائع نسبيًا في NS-3. لذلك، نلقي نظرة على NodeListPriv::إضافة. ها أنت
سوف نجد،

Simulator::ScheduleWithContext (index, TimeStep (0), &Node::Initialize,node);

يخبرك هذا أنه كلما تم إنشاء عقدة في المحاكاة، يتم إجراء مكالمة كأثر جانبي
إلى تلك العقدة تهيئة تمت جدولة الطريقة لك والتي تحدث في الوقت صفر. لا
قرأت الكثير في هذا الاسم، حتى الآن. هذا لا يعني أن العقدة ستبدأ في العمل
أي شيء، يمكن تفسيره على أنه مكالمة إعلامية إلى العقدة لإخبارها بأن
لقد بدأت المحاكاة، وليست دعوة للعمل لإخبار العقدة بالبدء في القيام بشيء ما.

وبالتالي، قائمة العقد::إضافة يقوم بجدولة مكالمة بشكل غير مباشر إلى عقدة :: تهيئة في الوقت صفر لتقديم المشورة أ
العقدة الجديدة التي بدأت فيها المحاكاة. إذا نظرت في src/network/model/node.h لصحتك!
ومع ذلك، لن تجد طريقة تسمى عقدة :: تهيئة. وتبين أن
تهيئة الطريقة موروثة من الفصل هدف. كافة الكائنات في النظام يمكن أن تكون
يتم إعلامك عند بدء المحاكاة، والكائنات من الفئة Node هي مجرد نوع واحد منها
شاء.

الق نظرة على src/core/model/object.cc التالي وابحث عنه الكائن::تهيئة. هذا الرمز
ليست واضحة كما كنت قد توقعت منذ ذلك الحين NS-3 الأجسام تقنية
تجميع. الكود في الكائن::تهيئة ثم حلقات من خلال كافة الكائنات التي
تم تجميعها معًا وتستدعيها قم بالتهيئة طريقة. هذه لغة أخرى
وهذا أمر شائع جدًا في NS-3، يُطلق عليه أحيانًا "نمط تصميم القالب".: عام
طريقة واجهة برمجة التطبيقات (API) غير الافتراضية، والتي تظل ثابتة عبر عمليات التنفيذ، والتي تستدعي
طريقة التنفيذ الافتراضية الخاصة الموروثة والمنفذة بواسطة الفئات الفرعية.
الأسماء عادة ما تكون مثل اسم الأسلوب لواجهة برمجة التطبيقات العامة و DoMethodName لـ
واجهة برمجة التطبيقات الخاصة.

هذا يخبرنا أنه يجب علينا البحث عن العقدة::DoInitialize الطريقة في
src/network/model/node.cc للطريقة التي سوف نواصل طريقنا. إذا قمت بتحديد موقع
الكود، ستجد طريقة للتكرار عبر جميع الأجهزة الموجودة في العقدة ثم
جميع التطبيقات الموجودة في Node Calling الجهاز-> تهيئة التطبيق->التهيئة
على التوالي.

ربما تعرف بالفعل تلك الفصول الجهاز التطبيق كلاهما يرث من الفصل هدف
وبالتالي فإن الخطوة التالية ستكون النظر إلى ما سيحدث ومتى التطبيق::قم بالتهيئة is
مُسَمًّى. نلقي نظرة على src/network/model/application.cc وسوف تجد:

باطل
التطبيق::DoInitialize (باطل)
{
m_startEvent = Simulator::Schedule (m_startTime, &Application::StartApplication, this);
إذا (m_stopTime!= TimeStep (0))
{
m_stopEvent = Simulator::Schedule (m_stopTime, &Application::StopApplication, this);
}
الكائن::DoInitialize ();
}

وهنا وصلنا أخيرًا إلى نهاية المسار. إذا كنت قد أبقيت كل شيء في نصابه الصحيح، عندما
تنفيذ NS-3 التطبيق، يرث تطبيقك الجديد من الفصل التطبيق. أنت
تجاوز ال StartApplication StopApplication الأساليب وتوفير الآليات اللازمة لذلك
بدء وإيقاف تدفق البيانات من جهازك الجديد التطبيق. عندما تكون العقدة
تم إنشاؤها في المحاكاة، يتم إضافتها إلى العالمية NodeList. عملية إضافة عقدة إلى
NodeList يؤدي إلى جدولة حدث محاكاة للوقت صفر الذي يستدعي
عقدة :: تهيئة طريقة العقدة المضافة حديثًا التي سيتم استدعاؤها عند بدء المحاكاة.
نظرًا لأن العقدة ترث من هدف، وهذا يدعو الكائن::تهيئة الطريقة على العقدة
والذي بدوره يدعو قم بالتهيئة الأساليب على كافة الأجسام المجمعة إلى
العقدة (فكر في نماذج التنقل). منذ العقدة هدف تم تجاوزه قم بالتهيئة، أن
يتم استدعاء الطريقة عند بدء المحاكاة. ال العقدة::DoInitialize تستدعي الطريقة
تهيئة أساليب جميع التطبيقات على العقدة. منذ التطبيقات هم أيضا
الأجسام، هذه تسبب التطبيق::قم بالتهيئة ليتم استدعاؤها. متى
التطبيق::قم بالتهيئة يُطلق عليه أنه يقوم بجدولة الأحداث لـ StartApplication
StopApplication يدعو التطبيق. تم تصميم هذه المكالمات لبدء وإيقاف
تدفق البيانات من التطبيق

لقد كانت هذه رحلة أخرى طويلة إلى حد ما، ولكن يجب القيام بها مرة واحدة فقط، وأنت الآن
فهم قطعة أخرى عميقة جدًا NS-3.

إنّ اسم التطبيق التطبيق
إنّ اسم التطبيق التطبيق يحتاج إلى منشئ ومدمر بالطبع:

MyApp::MyApp ()
: m_socket (0)،
م_النظير ()،
m_packetSize (0)،
m_nالحزم (0)،
m_dataRate (0)،
m_sendEvent ()،
m_running (خطأ)،
m_packetsSent (0)
{
}

MyApp::~MyApp()
{
m_socket = 0;
}

إن وجود الجزء التالي من التعليمات البرمجية هو السبب الرئيسي وراء كتابتنا لهذا التطبيق in
المكان الأول.

باطل
MyApp::الإعداد (Ptr المقبس، عنوان العنوان، uint32_t حجم الحزمة،
uint32_t nPackets، DataRate dataRate)
{
m_socket = المقبس;
m_peer = عنوان؛
m_packetSize = packetSize;
m_nPackets = nPackets;
m_dataRate = dataRate;
}

يجب أن يكون هذا الرمز واضحًا بذاته. نحن نقوم فقط بتهيئة متغيرات الأعضاء.
الشيء المهم من منظور التتبع هو بي تي آر مقبس الذي نحن
اللازمة لتوفير للتطبيق أثناء وقت التكوين. أذكر أننا ذاهبون
لإنشاء البريزة ك TcpSocket (الذي يتم تنفيذه بواسطة TcpNewReno) وربطها
مصدر التتبع "CongestionWindow" قبل تمريره إلى ملف اقامة الأسلوب.

باطل
MyApp::StartApplication (باطل)
{
m_running = true;
m_packetsSent = 0;
m_socket->ربط ()؛
m_socket->الاتصال (m_peer);
إرسال الحزمة ()؛
}

الكود أعلاه هو التنفيذ المُتجاوز التطبيق::بدء التطبيق هذا سيكون
يتم استدعاؤها تلقائيًا بواسطة جهاز المحاكاة لبدء تشغيلنا التطبيق تشغيل في المكان المناسب
وقت. يمكنك أن ترى أنه يفعل البريزة مأزق عملية. إذا كنت على دراية
لا ينبغي أن يكون هذا مفاجئًا. يقوم بالأعمال المطلوبة على المستوى المحلي
جانب الاتصال تمامًا كما قد تتوقع. الأتى التواصل سوف تفعل ما هو
المطلوبة لتأسيس اتصال مع TCP في العنوان m_peer. ينبغي أن يكون واضحا الآن
لماذا نحتاج إلى تأجيل الكثير من هذا إلى وقت المحاكاة، منذ التواصل سوف تحتاج
شبكة تعمل بكامل طاقتها لإكمال. بعد التواصلأطلقت حملة التطبيق ثم يبدأ
إنشاء أحداث محاكاة عن طريق الاتصال SendPacket.

يشرح الجزء التالي من التعليمات البرمجية لـ التطبيق كيفية التوقف عن إنشاء أحداث المحاكاة.

باطل
MyApp::StopApplication (باطل)
{
m_running = false;

إذا (m_sendEvent.IsRunning ())
{
محاكي::إلغاء (m_sendEvent);
}

إذا (m_socket)
{
m_socket->Close ();
}
}

في كل مرة يتم جدولة حدث محاكاة، يتم الحدث/الفعالية أنشئ. إذا كان الحدث/الفعالية معلق
التنفيذ أو التنفيذ وطريقته يجري سيعود صحيح. في هذا الكود إذا
يجري() يعود صحيحا، ونحن إلغاء الحدث الذي يزيله من حدث المحاكاة
طابور. ومن خلال القيام بذلك، فإننا نكسر سلسلة الأحداث التي التطبيق يستخدم للحفاظ على
ارسال لها الحزم و التطبيق يذهب هادئا. بعد أن هدأنا التطبيق we
اغلاق المقبس الذي يمزق اتصال TCP.

يتم حذف المقبس بالفعل في أداة التدمير عندما يتم حذف m_socket = 0 يتم تنفيذ. هذا
يزيل المرجع الأخير إلى Ptr الأساسي الذي يسبب تدمير
هذا الكائن الذي سيتم استدعاؤه.

أذكر ذلك StartApplication تسمى SendPacket لبدء سلسلة الأحداث التي تصف
هيه التطبيق السلوك.

باطل
MyApp::SendPacket (باطل)
{
بي تي آر الحزمة = إنشاء (m_packetSize);
m_socket->إرسال (حزمة)؛

إذا (++m_packetsSent <m_nPackets)
{
جدولة تكساس ()؛
}
}

هنا ترى ذلك SendPacket يفعل ذلك تماما. يخلق أ رزمة ومن ثم يفعل إرسال
والذي، إذا كنت تعرف بيركلي سوكيتس، فمن المحتمل أن يكون هذا هو ما كنت تتوقع رؤيته.

إنها مسؤولية التطبيق للحفاظ على جدولة سلسلة الأحداث، وبالتالي فإن
نداء السطور التالية جدولTx لجدولة حدث إرسال آخر (أ SendPacket) حتى ال
التطبيق تقرر أنها أرسلت ما يكفي.

باطل
MyApp::ScheduleTx (باطل)
{
إذا (م_تشغيل)
{
الوقت التالي (بالثواني (m_packetSize * 8 / static_cast (m_dataRate.GetBitRate ()))));
m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this);
}
}

هنا ترى ذلك جدولTx يفعل ذلك بالضبط. إذا التطبيق قيد التشغيل (إذا
StopApplication لم يتم استدعاؤه) فإنه سيتم جدولة حدث جديد، والذي يدعو SendPacket
مرة أخرى. سوف يكتشف قارئ التنبيه شيئًا يؤدي أيضًا إلى وصول المستخدمين الجدد. معدل البيانات
ل التطبيق هذا فقط. لا علاقة له بمعدل البيانات الأساسي
قناة. وهذا هو المعدل الذي التطبيق تنتج بت. لا يأخذ في الاعتبار
قم بحساب أي حمل إضافي للبروتوكولات أو القنوات المختلفة التي يستخدمها لنقل البيانات
بيانات. إذا قمت بتعيين معدل البيانات ل التطبيق إلى نفس معدل البيانات الأساسية الخاصة بك
قناة سوف تحصل في نهاية المطاف على تجاوز سعة المخزن المؤقت.

أثر المصارف
الهدف الأساسي من هذا التمرين هو الحصول على عمليات رد اتصال من TCP تشير إلى
تم تحديث نافذة الازدحام. الجزء التالي من التعليمات البرمجية ينفذ ما يقابله
بالوعة التتبع:

الفراغ ثابت
CwndChange (uint32_t oldCwnd، uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
}

يجب أن يكون هذا مألوفًا لك الآن، لذلك لن نتناول التفاصيل. هذه الوظيفة
ما عليك سوى تسجيل وقت المحاكاة الحالي والقيمة الجديدة لنافذة الازدحام كل مرة
الوقت يتم تغييره. ربما يمكنك أن تتخيل أنه يمكنك تحميل الإخراج الناتج
في برنامج رسومات (gnuplot أو Excel) وشاهد على الفور رسمًا بيانيًا جميلاً لـ
سلوك نافذة الازدحام مع مرور الوقت.

أضفنا مخزن تتبع جديدًا لإظهار مكان إسقاط الحزم. سنقوم بإضافة خطأ
نموذجًا لهذا الكود أيضًا، لذلك أردنا أن نوضح هذا العمل.

الفراغ ثابت
آر إكس دروب (بي تي آر ع)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
}

سيتم توصيل مصدر التتبع هذا بمصدر التتبع "PhyRxDrop" من نقطة إلى نقطة
NetDevice. يتم تشغيل مصدر التتبع هذا عند إسقاط الحزمة بواسطة الطبقة المادية لملف
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 لهذا المتغير العضو، سوف تفعل ذلك
تجد أنه تم الإعلان عنه كـ تتبع الاتصال الحزمة> >. هذا يجب أن يخبرك
أن هدف رد الاتصال يجب أن يكون دالة تُرجع باطلة وتأخذ دالة واحدة
المعلمة وهي أ بي تي آر الحزمة> (على افتراض أننا نستخدم ConnectWithoutContext) -- فقط
ما لدينا أعلاه.

الرئيسية البرنامج
يجب أن يكون الكود التالي مألوفًا لك الآن:

مادبا
main (int argc، char * argv [])
{
عقد NodeContainer
العقد.إنشاء (2);

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate"، StringValue ("5 ميجا بت في الثانية"))؛
pointToPoint.SetChannelAttribute ("Delay"، StringValue ("2ms"))؛

أجهزة NetDeviceContainer؛
الأجهزة = pointToPoint.Install (العقد)؛

يؤدي هذا إلى إنشاء عقدتين بقناة نقطة إلى نقطة بينهما، تمامًا كما هو موضح في الصورة
الرسم التوضيحي في بداية الملف.

تُظهر الأسطر القليلة التالية من التعليمات البرمجية شيئًا جديدًا. إذا قمنا بتتبع الاتصال الذي يتصرف
تمامًا، سننتهي بنافذة ازدحام متزايدة بشكل رتيب. لرؤية أي
سلوك مثير للاهتمام، نريد حقًا تقديم أخطاء الارتباط التي ستؤدي إلى إسقاط الحزم،
تسبب ACKs مكررة وتؤدي إلى سلوكيات أكثر إثارة للاهتمام لنافذة الازدحام.

NS-3 ويوفر ErrorModel الأشياء التي يمكن أن تعلق عليها القنوات. نحن نستخدم
RateErrorModel مما يسمح لنا بإدخال الأخطاء في ملف قناة في وقت معين معدل.

بي تي آر em = CreateObject ()؛
em->SetAttribute ("ErrorRate"، DoubleValue (0.00001))؛
devices.Get (1)->SetAttribute ("ReceiveErrorModel"، PointerValue (em))؛

الكود أعلاه ينشئ مثيلًا لـ a RateErrorModel الكائن، وقمنا بتعيين "ErrorRate" السمة
إلى القيمة المطلوبة. ثم نقوم بتعيين مثيل الناتجة RateErrorModel كما الخطأ
النموذج المستخدم من نقطة إلى نقطة NetDevice. وهذا سيعطينا بعض عمليات إعادة الإرسال و
جعل مؤامرة لدينا أكثر إثارة للاهتمام قليلا.

مكدس InternetStackHelper؛
مكدس التثبيت (العقد) ؛

عنوان Ipv4AddressHelper؛
عنوان.SetBase ("10.1.1.0"، "255.255.255.252")؛
Ipv4InterfaceContainer واجهات = عنوان.تعيين (الأجهزة)؛

يجب أن يكون الرمز أعلاه مألوفًا. يقوم بتثبيت مكدسات الإنترنت على العقدتين و
ينشئ واجهات ويعين عناوين IP للأجهزة من نقطة إلى نقطة.

نظرًا لأننا نستخدم TCP، فنحن بحاجة إلى شيء ما على العقدة الوجهة لاستقبال TCP
الاتصالات والبيانات. ال PacketSink التطبيق يشيع استخدامه في NS-3 من أجل هذا
غرض.

uint16_tsinkPort = 8080;
عنوان حوض العنوان (InetSocketAddress(interfaces.GetAddress (1),sinkPort));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory"،
InetSocketAddress (Ipv4Address::GetAny(),sinkPort));
ApplicationContainer SinkApps = packetSinkHelper.Install (nodes.Get (1));
SinkApps.Start (Seconds (0.));
SinkApps.Stop (ثواني (20.))؛

يجب أن يكون كل هذا مألوفًا، باستثناء،

PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory"،
InetSocketAddress (Ipv4Address::GetAny(),sinkPort));

يقوم هذا الرمز بإنشاء مثيل لـ PacketSinkHelper ويخبره بإنشاء مآخذ توصيل باستخدام الفصل
ns3::TcpSocketFactory. تطبق هذه الفئة نمط تصميم يسمى "مصنع الكائنات"
وهي آلية شائعة الاستخدام لتحديد فئة تستخدم لإنشاء كائنات في ملف
طريقة مجردة. هنا، بدلاً من الاضطرار إلى إنشاء الكائنات نفسها، يمكنك توفير
PacketSinkHelper سلسلة تحدد أ النوع السلسلة المستخدمة لإنشاء كائن
ويمكن بعد ذلك استخدامها لإنشاء مثيلات للكائنات التي أنشأها المصنع.

المعلمة المتبقية تخبر التطبيق العنوان والمنفذ الذي ينبغي مأزق إلى.

سيقوم السطران التاليان من التعليمات البرمجية بإنشاء المقبس وتوصيل مصدر التتبع.

بي تي آر ns3TcpSocket = المقبس::CreateSocket (العقد.Get (0)،
TcpSocketFactory::GetTypeId());
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow"،
MakeCallback (&CwndChange));

يستدعي البيان الأول وظيفة العضو الثابت المقبس::إنشاءSocket ويوفر أ
عقدة وصريحة النوع لمصنع الكائن المستخدم لإنشاء المقبس. هذا ال
مستوى اتصال أقل قليلاً من مستوى المكالمة PacketSinkHelper استدعاء أعلاه، ويستخدم C++ صريحة
اكتب بدلاً من واحد يشار إليه بسلسلة. وإلا فهو نفس المفهوم
شيء.

بمجرد TcpSocket يتم إنشاؤه وإرفاقه بالعقدة، يمكننا استخدامه
TraceConnectWithoutContext لتوصيل مصدر التتبع CongestionWindow بمصرف التتبع الخاص بنا.

تذكر أننا قمنا بترميز التطبيق حتى نتمكن من اتخاذ ذلك البريزة لقد صنعنا للتو (أثناء
وقت التكوين) واستخدامه في وقت المحاكاة. علينا الآن إنشاء مثيل لذلك
التطبيق. لم نواجه أي مشكلة في إنشاء مساعد لإدارة ملف التطبيق so
سيتعين علينا إنشاؤه وتثبيته "يدويًا". هذا في الواقع سهل للغاية:

بي تي آر التطبيق = إنشاء كائن ()؛
التطبيق->الإعداد (ns3TcpSocket,sinkAddress, 1040, 1000, DataRate ("1Mbps"));
العقدة.Get (0)->AddApplication (التطبيق)؛
التطبيق->ابدأ (الثواني (1.));
التطبيق->إيقاف (ثواني (20.))؛

السطر الأول يخلق هدف من النوع اسم التطبيق -- ملكنا التطبيق. السطر الثاني يحكي
هيه التطبيق ماذا البريزة للاستخدام، والعنوان الذي تريد الاتصال به، وكم البيانات التي سيتم إرسالها إليه
كل حدث إرسال، وعدد أحداث الإرسال المطلوب إنشاؤها ومعدل إنتاج البيانات
من تلك الأحداث.

بعد ذلك، نقوم بإضافة يدوياً اسم التطبيق التطبيق إلى العقدة المصدر واستدعاء صراحةً
آبدأ قلة النوم الأساليب على التطبيق لإخباره متى يبدأ ويتوقف عن القيام بذلك
شيء.

نحن بحاجة إلى إجراء الاتصال فعليًا من نقطة إلى نقطة المتلقي NetDevice حدث إسقاط
الى آر إكس دروب معاودة الاتصال الآن.

devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));

يجب أن يكون واضحًا الآن أننا نحصل على إشارة إلى الاستلام العقدة NetDevice
من حاويته وتوصيل مصدر التتبع المحدد بواسطة السمة "PhyRxDrop".
هذا الجهاز إلى بالوعة التتبع آر إكس دروب.

أخيرًا، نطلب من جهاز المحاكاة أن يتجاوز أيًا منها التطبيقات وتوقف عن المعالجة
الأحداث في 20 ثانية في المحاكاة.

محاكي::توقف (ثانية(20)) ؛
محاكي :: تشغيل () ؛
جهاز محاكاة :: تدمير () ؛

0 العودة؛
}

أذكر ذلك في أقرب وقت محاكي :: تشغيل يتم استدعاء، وينتهي وقت التكوين، والمحاكاة
يبدأ الوقت. جميع الأعمال التي قمنا بتنسيقها من خلال إنشاء التطبيق وتعليمها
كيفية الاتصال وإرسال البيانات يحدث بالفعل أثناء استدعاء الوظيفة هذا.

في أقرب وقت محاكي :: تشغيل يعود، اكتملت المحاكاة وندخل في عملية التفكيك
مرحلة. في هذه الحالة، محاكاة::تدمير يعتني بالتفاصيل الدموية ونعود للتو
رمز النجاح بعد اكتماله.

الركض Fifth.cc
منذ أن قدمنا ​​الملف Fifth.cc بالنسبة لك، إذا قمت ببناء التوزيع الخاص بك (في
وضع التصحيح لأنه يستخدم NS_LOG - تذكر أن الإصدارات المحسنة تعمل على تحسينها NS_LOG) هو - هي
سوف يكون في انتظاركم للتشغيل.

$ ./waf --التشغيل الخامس
Waf: إدخال الدليل `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
Waf: مغادرة الدليل `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
انتهى "البناء" بنجاح (0.684 ثانية)
1 536
1.0093 1072
1.01528 1608
1.02167 2144

1.11319 8040
1.12151 8576
1.12983 9112
آر إكس دروب عند 1.13696


ربما يمكنك أن ترى على الفور الجانب السلبي لاستخدام المطبوعات من أي نوع في آثارك.
نحصل على رسائل waf الدخيلة هذه مطبوعة في جميع أنحاء معلوماتنا المثيرة للاهتمام
مع تلك الرسائل RxDrop. سنقوم بمعالجة ذلك قريبًا، لكنني متأكد من أنك لا تستطيع الانتظار لترى
نتائج كل هذا العمل. دعونا نعيد توجيه هذا الإخراج إلى ملف يسمى cwnd.dat:

$ ./waf --run الخامس > cwnd.dat 2>&1

الآن قم بتحرير "cwnd.dat" في المحرر المفضل لديك وقم بإزالة حالة إنشاء waf وإفلاتها
الأسطر، مع ترك البيانات التي تم تتبعها فقط (يمكنك أيضًا التعليق على ملف
TraceConnectWithoutContext("PhyRxDrop"، إجعل الإتصال (&RxDrop)); في البرنامج النصي للتخلص
من المطبوعات المتساقطة بنفس السهولة.

يمكنك الآن تشغيل gnuplot (إذا كان مثبتًا لديك) وإخباره بإنشاء بعض العناصر الجميلة
الصور:

$ غنوبلوت
gnuplot> تعيين حجم png الطرفية 640,480،XNUMX
gnuplot> قم بتعيين الإخراج "cwnd.png"
gnuplot> رسم "cwnd.dat" باستخدام عنوان 1:2 "نافذة الازدحام" مع نقاط الخطوط
gnuplot> خروج

يجب أن يكون لديك الآن رسم بياني لنافذة الازدحام مقابل الوقت الموجود في الملف
"cwnd.png" التحميل = "lazy" الذي يبدو كما يلي:
[صورة]

باستخدام المستوى المتوسط المساعدون
في القسم السابق، أظهرنا كيفية ربط مصدر التتبع والحصول عليه
معلومات مثيرة للاهتمام من المحاكاة. ربما تتذكر أننا اتصلنا
تسجيل الدخول إلى الإخراج القياسي باستخدام الأمراض المنقولة جنسيا :: كوت "أداة حادة" في وقت سابق من هذا بكثير
الفصل. لقد كتبنا أيضًا عن مدى صعوبة تحليل مخرجات السجل بالترتيب
لعزل المعلومات المثيرة للاهتمام. ربما خطر ببالك أننا أنفقنا الكثير للتو
من الوقت في تنفيذ مثال يعرض جميع المشكلات التي نهدف إلى إصلاحها
هيه NS-3 نظام التتبع! ستكون على حق. لكن تحمل معنا. لم ننتهي بعد.

أحد أهم الأشياء التي نريد القيام بها هو أن تكون لدينا القدرة على ذلك بسهولة
التحكم في كمية المخرجات الخارجة من المحاكاة؛ ونحن نريد أيضا حفظ تلك
البيانات إلى ملف حتى نتمكن من الرجوع إليها لاحقًا. يمكننا استخدام مساعدي التتبع من المستوى المتوسط
المقدمة في NS-3 للقيام بذلك فقط وإكمال الصورة.

نحن نقدم برنامجًا نصيًا يكتب أحداث التغيير والإسقاط cwnd التي تم تطويرها في المثال
Fifth.cc إلى القرص في ملفات منفصلة. يتم تخزين تغييرات cwnd كملف ASCII مفصول بعلامات جدولة
يتم تخزين الملف وأحداث الإفلات في ملف PCAP. التغييرات لتحقيق ذلك هي
صغيرة جدا.

تجول: six.cc
دعونا نلقي نظرة على التغييرات المطلوبة للانتقال من Fifth.cc إلى six.cc. فتح
أمثلة/البرنامج التعليمي/sixth.cc في محررك المفضل يمكنك رؤية التغيير الأول من خلال
البحث عن CwndChange. ستجد أننا قمنا بتغيير التوقيعات الخاصة بالتتبع
المصارف وأضفت سطرًا واحدًا إلى كل حوض يكتب المعلومات المتتبعة إلى ملف
تيار يمثل ملف.

الفراغ ثابت
كوندتشانج (بتر الدفق، uint32_t oldCwnd، uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}

الفراغ ثابت
آر إكس دروب (بي تي آر الملف، بي تي آر ع)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
file->Write(Simulator::Now(), p);
}

لقد أضفنا معلمة "دفق" إلى ملف CwndChange تتبع بالوعة. هذا هو الكائن الذي
يحمل (يبقيه على قيد الحياة بأمان) دفق إخراج C++. وتبين أن هذا أمر بسيط للغاية
كائن، ولكنه يدير مشكلات مدى الحياة للتيار ويحل مشكلة حتى
يواجه مستخدمو C++ ذوي الخبرة. وتبين أن منشئ نسخة ل الأمراض المنقولة جنسيا::ostream
تم وضع علامة خاصة. هذا يعني ذاك الأمراض المنقولة جنسيا::ostreams لا تطيع دلالات القيمة ولا تستطيع ذلك
يمكن استخدامها في أي آلية تتطلب نسخ الدفق. وهذا يشمل NS-3
نظام رد الاتصال، والذي كما تتذكر، يتطلب كائنات تخضع لدلالات القيمة.
لاحظ أيضًا أننا أضفنا السطر التالي في CwndChange تتبع بالوعة
التنفيذ:

*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;

سيكون هذا رمزًا مألوفًا جدًا إذا قمت باستبداله * تيار->احصل على تيار () مع الأمراض المنقولة جنسيا :: كوت، كما
في:

std::cout << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;

وهذا يوضح أن بي تي آر هو في الحقيقة مجرد حمل أ
الأمراض المنقولة جنسيا::ofstream بالنسبة لك، ويمكنك استخدامه هنا مثل أي دفق إخراج آخر.

ويحدث وضع مماثل في آر إكس دروب باستثناء أن الكائن الذي يتم تمريره (أ
بي تي آر) يمثل ملف PCAP. هناك بطانة واحدة في بالوعة التتبع
اكتب طابعًا زمنيًا وسيتم إسقاط محتويات الحزمة إلى ملف PCAP:

file->Write(Simulator::Now(), p);

بالطبع، إذا كان لدينا كائنات تمثل الملفين، فسنحتاج إلى إنشائهما في مكان ما
ويتسبب أيضًا في تمريرها إلى أحواض التتبع. إذا نظرت في رئيسي وظيفة،
ستجد رمزًا جديدًا للقيام بذلك:

asciiTraceHelper asciiTraceHelper;
بي تي آر تيار = asciiTraceHelper.CreateFileStream ("sixth.cwnd")؛
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow"، MakeBoundCallback (&CwndChange،stream));



PcapHelper pcapHelper;
بي تي آر file = pcapHelper.CreateFile ("sixth.pcap"، std::ios::out، PcapHelper::DLT_PPP)؛
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));

في القسم الأول من مقتطف التعليمات البرمجية أعلاه، نقوم بإنشاء ملف تتبع ASCII،
إنشاء كائن مسؤول عن إدارته واستخدام متغير رد الاتصال
وظيفة الإنشاء لترتيب تمرير الكائن إلى الحوض. لدينا تتبع ASCII
يوفر المساعدون مجموعة غنية من الوظائف لتسهيل استخدام الملفات النصية (ASCII). نحن
سأقوم فقط بتوضيح استخدام وظيفة إنشاء دفق الملفات هنا.

إنّ إنشاء ملف دفق ستقوم الوظيفة بشكل أساسي بإنشاء مثيل لـ a الأمراض المنقولة جنسيا::ofstream كائن و
إنشاء ملف جديد (أو اقتطاع ملف موجود). هذا الأمراض المنقولة جنسيا::ofstream يتم تعبئتها في
NS-3 كائن لإدارة مدى الحياة وحل مشكلة مُنشئ النسخ.

ثم نأخذ هذا NS-3 الكائن الذي يمثل الملف وتمريره إليه MakeBoundCallback().
تقوم هذه الوظيفة بإنشاء رد اتصال تمامًا مثل إجراء رد اتصال ()، لكنه "يربط" قيمة جديدة بـ
رد الاتصال. تتم إضافة هذه القيمة كوسيطة أولى إلى رد الاتصال قبل أن تتم إضافتها
اتصل.

أساسا، MakeBoundCallback(&CwndChange, تدفق) يؤدي مصدر التتبع إلى إضافة ملف
معلمة "دفق" إضافية في مقدمة قائمة المعلمات الرسمية قبل الاستدعاء
رد الاتصال. يؤدي هذا إلى تغيير التوقيع المطلوب لـ CwndChange تغرق لتتناسب مع واحد
الموضح أعلاه، والذي يتضمن المعلمة "الإضافية". بي تي آر مجرى.

في القسم الثاني من التعليمات البرمجية في المقتطف أعلاه، نقوم بإنشاء مثيل لـ PcapHelper للقيام
نفس الشيء بالنسبة لملف تتبع PCAP الخاص بنا والذي فعلناه مع ملف AsciiTraceHelper. خط
الرمز،

بي تي آر الملف = 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) المناسب لأجهزة wifi. يتم تعريف هذه
in src / network / helper / trace-helper.h إذا كنت مهتمًا برؤية القائمة. ال
الإدخالات الموجودة في القائمة تتطابق مع تلك الموجودة في bpf.h لكننا نكررها لتجنب مصدر PCAP
الاعتماد.

A NS-3 يتم إرجاع الكائن الذي يمثل ملف PCAP من CreateFile وتستخدم في حدود
رد الاتصال تمامًا كما كان في حالة ASCII.

انعطاف مهم: من المهم ملاحظة أنه على الرغم من وجود هذين الكائنين
أعلن بطرق مشابهة جدا،

بي تي آر ملف ...
بي تي آر تدفق ...

الكائنات الأساسية مختلفة تمامًا. على سبيل المثال، بي تي آر هو
مؤشر ذكي ل NS-3 الكائن الذي هو شيء ثقيل الوزن إلى حد ما يدعم
سمات ومتكاملة في نظام التكوين. ال بي تي آر، على
من ناحية أخرى، يعد مؤشرًا ذكيًا لكائن مُعد مرجعيًا وخفيف الوزن جدًا
شيء. تذكر أن تنظر إلى الكائن الذي تشير إليه قبل إجراء أي افتراضات
حول "الصلاحيات" التي قد يمتلكها هذا الكائن.

على سبيل المثال ، ألق نظرة على src/network/utils/pcap-file-wrapper.h في التوزيع و
تنويه،

فئة PcapFileWrapper: كائن عام

تلك الفئة PcapFileWrapper هو NS-3 الكائن بحكم الميراث. ثم انظر
src/network/model/output-stream-wrapper.h ولاحظ،

فئة OutputStreamWrapper: public
SimpleRefCount

أن هذا الكائن ليس NS-3 الكائن على الإطلاق، هو "مجرد" كائن C++ الذي يحدث له
دعم العد المرجعي التدخلي.

النقطة هنا هي أنه فقط لأنك تقرأ بي تي آر لا يعني بالضرورة
أن شيء هو NS-3 الكائن الذي يمكنك تعليقه NS-3 الصفات مثلا.

والآن نعود إلى المثال. إذا قمت بإنشاء هذا المثال وتشغيله،

$ ./waf --التشغيل السادس

سترى نفس الرسائل تظهر عندما قمت بتشغيل "الخامس"، ولكن سيظهر ملفان جديدان
تظهر في دليل المستوى الأعلى الخاص بك NS-3 التوزيع.

six.cwnd six.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، فيمكنك مشاهدته باستخدامه com.tcpdump.

القراءة من الملف six.pcap، PPP من نوع الارتباط (PPP)
1.136956 IP 10.1.1.1.49153 > 10.1.1.2.8080: الأعلام [.]، seq 17177:17681، ack 1، الفوز 32768، الخيارات [TS val 1133 ecr 1127,eol]، الطول 504
1.403196 IP 10.1.1.1.49153 > 10.1.1.2.8080: الأعلام [.]، seq 33280:33784، ack 1، الفوز 32768، الخيارات [TS val 1399 ecr 1394,eol]، الطول 504

7.426220 IP 10.1.1.1.49153 > 10.1.1.2.8080: الأعلام [.]، seq 785704:786240، ack 1، الفوز 32768، الخيارات [TS val 7423 ecr 7421,eol]، الطول 536
9.630693 IP 10.1.1.1.49153 > 10.1.1.2.8080: الأعلام [.]، seq 882688:883224، ack 1، الفوز 32768، الخيارات [TS val 9620 ecr 9618,eol]، الطول 536

لديك ملف PCAP يحتوي على الحزم التي تم إسقاطها في المحاكاة. لا يوجد
الحزم الأخرى موجودة في الملف ولا يوجد شيء آخر لإضفاء الحياة
صعوبة.

لقد كانت رحلة طويلة، لكننا الآن في مرحلة حيث يمكننا أن نقدر ما حدث NS-3
نظام التتبع. لقد قمنا بسحب الأحداث المهمة من منتصف تنفيذ TCP
وبرنامج تشغيل الجهاز. قمنا بتخزين تلك الأحداث مباشرة في ملفات قابلة للاستخدام ومعروفة بشكل شائع
أدوات. لقد فعلنا ذلك دون تعديل أي من التعليمات البرمجية الأساسية المعنية، وقد فعلنا ذلك في
18 سطرًا فقط من التعليمات البرمجية:

الفراغ ثابت
كوندتشانج (بتر الدفق، uint32_t oldCwnd، uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}



asciiTraceHelper asciiTraceHelper;
بي تي آر تيار = asciiTraceHelper.CreateFileStream ("sixth.cwnd")؛
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow"، MakeBoundCallback (&CwndChange،stream));



الفراغ ثابت
آر إكس دروب (بي تي آر الملف، بي تي آر ع)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
file->Write(Simulator::Now(), p);
}



PcapHelper pcapHelper;
بي تي آر file = pcapHelper.CreateFile ("sixth.pcap"، "w"، PcapHelper::DLT_PPP)؛
devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));

أثر المساعدون
إنّ NS-3 يوفر مساعدو التتبع بيئة غنية لتكوين واختيار مختلف
تتبع الأحداث وكتابتها في الملفات. في الأقسام السابقة، في المقام الأول
بناء الطوبولوجيات، لقد رأينا عدة أنواع من أساليب مساعد التتبع المصممة
للاستخدام داخل المساعدين الآخرين (الجهاز).

ربما تتذكر رؤية بعض هذه الاختلافات:

pointToPoint.EnablePcapAll ("الثانية") ،
pointToPoint.EnablePcap ("second"، p2pNodes.Get (0) -> GetId ()، 0) ؛
csma.EnablePcap ("ثالث"، csmaDevices.Get (0)، true) ؛
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr")) ؛

ما قد لا يكون واضحًا ، مع ذلك ، هو أن هناك نموذجًا ثابتًا لجميع
الطرق ذات الصلة بالتتبع الموجودة في النظام. سنأخذ الآن بعض الوقت ونلقي نظرة
في "الصورة الكبيرة".

توجد حاليًا حالتا استخدام أساسيتان لمساعدي التتبع في NS-3: مساعدين الجهاز
ومساعدي البروتوكول. يبحث مساعدو الأجهزة في مشكلة تحديد الآثار
يجب تمكينه من خلال زوج (العقدة، الجهاز). على سبيل المثال، قد ترغب في تحديد
يجب تمكين تتبع PCAP على جهاز معين على عقدة معينة. هذا
يتبع من NS-3 النموذج المفاهيمي للجهاز، وكذلك النماذج المفاهيمية لل
مختلف مساعدي الأجهزة. بعد ذلك بشكل طبيعي، تتبع الملفات التي تم إنشاؤها ملف
- - اصطلاح التسمية.

ينظر مساعدو البروتوكول في مشكلة تحديد الآثار التي يجب تمكينها من خلالها
زوج من البروتوكول والواجهة. هذا يتبع من NS-3 مكدس البروتوكول المفاهيمي
النموذج، وكذلك النماذج المفاهيمية لمساعدي مكدس الإنترنت. بطبيعة الحال، التتبع
يجب أن تتبع الملفات أ - - اصطلاح التسمية.

وبالتالي فإن مساعدي التتبع يقعون بشكل طبيعي في تصنيف ثنائي الأبعاد. هناك
الخواص الدقيقة التي تمنع الفئات الأربع من التصرف بشكل متماثل ، لكننا نسعى جاهدين لتحقيق ذلك
اجعلهم جميعًا يعملون بشكل مشابه قدر الإمكان ؛ وكلما أمكن هناك نظائر ل
جميع الطرق في جميع الفئات.

┌──────────────┬───────────┐
│ │ PCAP │ ASCII │
└──────────────┴──────┴───────┘

│ مساعد الجهاز │ │ │
├──────────────┼──────┼───────┤
│مساعد البروتوكول │ │ │
└──────────────┴──────┴───────┘

نحن نستخدم نهجا يسمى أ mixin لإضافة وظائف التتبع لفئات المساعدة لدينا. أ
mixin هي فئة توفر الوظائف عندما ترثها فئة فرعية.
لا يعتبر الميراث من mixin شكلاً من أشكال التخصص ولكنه في الحقيقة وسيلة لتحقيق ذلك
جمع الوظائف.

دعونا نلقي نظرة سريعة على كل هذه الحالات الأربع وكل منها مزيج.

الجهاز المساعدون
PCAP
الهدف من هؤلاء المساعدين هو تسهيل إضافة وسيلة تتبع PCAP متسقة إلى ملف
NS-3 جهاز. نريد أن تعمل جميع النكهات المختلفة لتتبع PCAP بنفس الطريقة
جميع الأجهزة ، لذلك يتم توريث طرق هؤلاء المساعدين بواسطة مساعدي الجهاز. إلق نظرة
at src / network / helper / trace-helper.h إذا كنت تريد متابعة المناقشة أثناء النظر في
كود حقيقي.

الفصل PcapHelperForDevice هو mixin يوفر وظائف عالية المستوى لاستخدام
تتبع PCAP في NS-3 جهاز. يجب أن ينفذ كل جهاز طريقة افتراضية واحدة
ورثت من هذه الطبقة.

الفراغ الظاهري EnablePcapInternal (std::string بادئة، Ptr nd, bool promiscous, bool صريحاسم الملف) = 0;

يعكس توقيع هذه الطريقة وجهة النظر المتمحورة حول الجهاز للوضع في هذا الصدد
مستوى. جميع الأساليب العامة الموروثة من الطبقة PcapUserHelperForDevice قلل الى
استدعاء طريقة التنفيذ المعتمدة على الجهاز الفردي. على سبيل المثال ، أدنى مستوى
طريقة PCAP،

EnablePcap باطلة (بادئة std :: string ، Ptr الثانية ، منطقية مختلطة = خطأ ، منطقية صريحة = خطأ) ؛

سيستدعي تنفيذ الجهاز لـ تمكينPcapInternal مباشرة. جميع PCAP العامة الأخرى
تعتمد أساليب التتبع على هذا التنفيذ لتوفير مستوى مستخدم إضافي
وظائف. ما يعنيه هذا للمستخدم هو أن جميع مساعدي الجهاز في النظام سيفعلون ذلك
توفر كافة أساليب تتبع PCAP؛ وستعمل جميع هذه الأساليب بنفس الطريقة
عبر الأجهزة إذا كان الجهاز يطبق تمكينPcapInternal بشكل صحيح.

طرق
EnablePcap باطلة (بادئة std :: string ، Ptr الثانية ، منطقية مختلطة = خطأ ، منطقية صريحة = خطأ) ؛
EnablePcap باطل (std :: string بادئة ، std :: string ، ndName ، bool مختلط = false ، bool صريح صريح = خطأ) ؛
void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscous = false);
void EnablePcap (std::string prefix, NodeContainer n, bool promiscous = false);
void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t devicesid, bool promiscous = false);
EnablePcapAll void (بادئة std :: string ، bool promiscuous = false) ؛

في كل من الطرق الموضحة أعلاه ، هناك معلمة افتراضية تسمى غير شرعي أن
التخلف عن زائف. تشير هذه المعلمة إلى أنه لا ينبغي تجميع التتبع
منحل. إذا كنت تريد أن تتضمن آثارك كل حركة المرور التي يراها الجهاز
(وإذا كان الجهاز يدعم الوضع المختلط) ، فما عليك سوى إضافة معلمة حقيقية إلى أي من ملفات
المكالمات أعلاه. على سبيل المثال،

Ptr اختصار الثاني؛

helper.EnablePcap ("بادئة" ، nd ، صواب) ؛

سيمكن وضع اللقطات المختلطة على NetDevice المحدد من قبل nd.

تتضمن الطريقتان الأوليان أيضًا معلمة افتراضية تسمى صريح اسم الملف ذلك سوف
تناقش أدناه.

نشجعك على الاطلاع على وثائق واجهة برمجة التطبيقات (API) الخاصة بالفصل الدراسي PcapHelperForDevice للعثور على
تفاصيل هذه الأساليب؛ ولكن لتلخيص ...

· يمكنك تمكين تتبع PCAP على زوج عقدة/جهاز شبكة معين من خلال توفير ملف
Ptr إلى تمكينPcap طريقة. ال Ptr ضمنيًا منذ الجهاز الصافي
يجب أن تنتمي إلى عقدة واحدة بالضبط. على سبيل المثال،

Ptr اختصار الثاني؛

helper.EnablePcap ("بادئة" ، بدون تاريخ) ؛

· يمكنك تمكين تتبع PCAP على زوج عقدة/جهاز شبكة معين من خلال توفير ملف
الأمراض المنقولة جنسيا :: سلسلة تمثل سلسلة خدمة اسم الكائن إلى ملف تمكينPcap طريقة. ال
Ptr تم البحث عنه من سلسلة الاسم. مرة أخرى ، فإن ضمنيًا منذ ذلك الحين
يجب أن ينتمي جهاز الشبكة المحدد إلى عقدة واحدة بالضبط. على سبيل المثال،

الأسماء :: إضافة ("الخادم" ...) ؛
الأسماء :: إضافة ("server / eth0" ...) ؛

helper.EnablePcap ("بادئة"، "server / ath0") ؛

· يمكنك تمكين تتبع PCAP على مجموعة من أزواج العقدة/الشبكة من خلال توفير ملف
NetDeviceContainer. لكل واحد NetDevice في الحاوية يتم فحص النوع. لكل
جهاز من النوع المناسب (نفس النوع الذي يديره مساعد الجهاز) ، التتبع هو
ممكن. مرة أخرى ، فإن ضمنيًا نظرًا لأن جهاز الشبكة الذي تم العثور عليه يجب أن ينتمي إليه
عقدة واحدة بالضبط. على سبيل المثال،

NetDeviceContainer d = ... ؛

helper.EnablePcap ("بادئة"، d) ؛

· يمكنك تمكين تتبع PCAP على مجموعة من أزواج العقدة/الشبكة من خلال توفير ملف
NodeContainer. لكل عقدة في NodeContainer مرفق به NetDevices تتكرر.
لكل NetDevice المرفقة بكل عقدة في الحاوية، هو نوع هذا الجهاز
التحقق. لكل جهاز من النوع المناسب (نفس النوع الذي يديره الجهاز
مساعد)، تم تمكين التتبع.

NodeContainer n ؛

helper.EnablePcap ("بادئة"، n) ؛

· يمكنك تمكين تتبع PCAP على أساس معرف العقدة ومعرف الجهاز بالإضافة إلى ذلك
صريح بي تي آر. تحتوي كل عقدة في النظام على معرف عقدة صحيح وكل جهاز متصل
إلى عقدة لديها معرف جهاز عدد صحيح.

helper.EnablePcap ("بادئة"، 21، 1) ؛

· وأخيرًا، يمكنك تمكين تتبع PCAP لجميع الأجهزة الموجودة في النظام، ومن نفس النوع
كما أن يديرها مساعد الجهاز.

helper.EnablePcapAll ("بادئة") ،

أسماء الملفات
ضمنيًا في أوصاف الطريقة أعلاه هو إنشاء اسم ملف كامل بواسطة
طريقة التنفيذ. وفقًا للاتفاقية، يتتبع PCAP في NS-3 النظام من الشكل
- معرف> - معرف> .pcap

كما ذكرنا سابقًا، سيكون لكل عقدة في النظام معرف عقدة مخصص للنظام؛ و
سيحتوي كل جهاز على فهرس واجهة (يسمى أيضًا معرف الجهاز) بالنسبة للعقدة الخاصة به.
افتراضيًا، يتم إنشاء ملف تتبع PCAP كنتيجة لتمكين التتبع في الأول
جهاز Node 21 باستخدام البادئة "prefix" سيكون البادئة -21-1.

يمكنك دائمًا استخدام ملف NS-3 خدمة اسم الكائن لجعل هذا أكثر وضوحًا. على سبيل المثال ، إذا
يمكنك استخدام خدمة اسم الكائن لتعيين اسم "الخادم" للعقدة 21، PCAP الناتج
سيصبح اسم ملف التتبع تلقائيًا ، بادئة خادم 1.pcap وإذا قمت أيضًا بتعيين
اسم "eth0" على الجهاز، فإن اسم ملف PCAP الخاص بك سوف يلتقط هذا تلقائيًا ويكون
تسمى بادئة خادم eth0.pcap.

أخيرًا، هناك طريقتان من الطرق الموضحة أعلاه،

EnablePcap باطلة (بادئة std :: string ، Ptr الثانية ، منطقية مختلطة = خطأ ، منطقية صريحة = خطأ) ؛
EnablePcap باطل (std :: string بادئة ، std :: string ، ndName ، bool مختلط = false ، bool صريح صريح = خطأ) ؛

لها معلمة افتراضية تسمى صريح اسم الملف. عند التعيين على صحيح ، هذه المعلمة
يعطل آلية إكمال اسم الملف التلقائي ويسمح لك بإنشاء ملف
اسم الملف. يتوفر هذا الخيار فقط في الطرق التي تتيح تتبع PCAP على ملف
جهاز واحد.

على سبيل المثال، من أجل الترتيب لمساعد الجهاز لإنشاء PCAP واحد غير شرعي
ملف التقاط باسم محدد my-pcap-file.pcap على جهاز معين، يمكن للمرء:

Ptr اختصار الثاني؛

helper.EnablePcap ("my-pcap-file.pcap" ، nd ، true ، true) ؛

أول صحيح تمكن المعلمة من تتبعات الوضع المختلط والثانية تخبر المساعد
لتفسير بادئة المعلمة كاسم ملف كامل.

ASCII
سلوك مساعد التتبع ASCII mixin يشبه إلى حد كبير إصدار PCAP.
الق نظرة على src / network / helper / trace-helper.h إذا كنت تريد متابعة المناقشة
أثناء النظر إلى الكود الحقيقي.

الفصل AsciiTraceHelperForDevice يضيف وظائف عالية المستوى لاستخدام ASCII
التتبع إلى فئة مساعد الجهاز. كما هو الحال في حالة PCAP، يجب على كل جهاز تنفيذ
طريقة افتراضية واحدة موروثة من تتبع ASCII mixin.

الفراغ الظاهري EnableAsciiInternal (Ptr تدفق،
الأمراض المنقولة جنسيا::سلسلة البادئة،
بي تي آر اختصار الثاني،
منطقي اسم الملف الواضح) = 0؛

يعكس توقيع هذه الطريقة وجهة النظر المتمحورة حول الجهاز للوضع في هذا الصدد
مستوى؛ وكذلك حقيقة أن المساعد قد يكتب إلى تدفق إخراج مشترك. كل
الأساليب العامة المرتبطة بتتبع ASCII الموروثة من الفصل AsciiTraceHelperForDevice
تقليل استدعاء طريقة التنفيذ المعتمدة على جهاز واحد. على سبيل المثال ، ملف
أدنى مستوى لطرق تتبع ascii

باطلة EnableAscii (std::string بادئة، Ptr nd، bool simpleFilename = false)؛
باطل EnableAscii (Ptr تيار ، Ptr اختصار الثاني)؛

سيستدعي تنفيذ الجهاز لـ تمكين AsciiInternal بشكل مباشر ، مع توفير إما أ
بادئة أو تيار صالح. ستعتمد جميع طرق تتبع ASCII العامة الأخرى على هذه الأساليب
وظائف منخفضة المستوى لتوفير وظائف إضافية على مستوى المستخدم. ماذا يعني هذا ل
المستخدم هو أن جميع مساعدي الأجهزة في النظام سيكون لديهم جميع طرق تتبع ASCII
متاح؛ وستعمل جميع هذه الطرق بنفس الطريقة عبر الأجهزة إذا كانت الأجهزة
تنفيذ EnablAscii الداخلية بشكل صحيح.

طرق
باطلة EnableAscii (std::string بادئة، Ptr nd، bool simpleFilename = false)؛
باطل EnableAscii (Ptr تيار ، Ptr اختصار الثاني)؛

void EnableAscii (std::string prefix, std::string ndName, bool plainFilename = false);
باطل EnableAscii (Ptr تيار ، الأمراض المنقولة جنسيا :: سلسلة ndName) ؛

EnableAscii باطلة (بادئة std :: string ، NetDeviceContainer d) ؛
باطل EnableAscii (Ptr تيار ، NetDeviceContainer د) ؛

EnableAscii باطلة (بادئة std :: string ، NodeContainer n) ؛
باطل EnableAscii (Ptr تيار ، NodeContainer n) ؛

باطل EnableAsciiAll (الأمراض المنقولة جنسيا :: بادئة سلسلة) ؛
باطل EnableAsciiAll (Ptr تدفق)؛

void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t devicesid, bool plainFilename);
باطل EnableAscii (Ptr تيار ، uint32_t nodeid ، uint32_t deviceid) ؛

نشجعك على الاطلاع على وثائق واجهة برمجة التطبيقات (API) الخاصة بالفصل الدراسي AsciiTraceHelperForDevice إلى
العثور على تفاصيل هذه الأساليب. ولكن لتلخيص ...

· هناك ضعف عدد الطرق المتاحة لتتبع ASCII مقارنة بـ PCAP
اقتفاء أثر. وذلك لأنه بالإضافة إلى نموذج نمط PCAP حيث توجد آثار من كل منهما
تتم كتابة زوج العقدة / الجهاز الفريد في ملف فريد ، ونحن ندعم النموذج الذي تتبع فيه
تتم كتابة المعلومات الخاصة بالعديد من أزواج العقد / الأجهزة في ملف مشترك. هذا يعني أن ملف
- - يتم استبدال آلية إنشاء اسم الملف بآلية
الرجوع إلى ملف مشترك ؛ ويتضاعف عدد طرق API للسماح للجميع
مجموعات.

· كما هو الحال في تتبع PCAP، يمكنك تمكين تتبع ASCII على جهاز معين (عقدة، شبكة)
الزوج من خلال توفير ملف Ptr إلى تمكين طريقة. ال Ptr ضمني
نظرًا لأن جهاز الشبكة يجب أن ينتمي إلى عقدة واحدة بالضبط. على سبيل المثال،

Ptr اختصار الثاني؛

helper.EnableAscii ("البادئة" ، الثانية) ؛

· تتضمن الطرق الأربع الأولى أيضًا معلمة افتراضية تسمى صريح اسم الملف أن
تعمل بشكل مشابه للمعلمات المكافئة في حالة PCAP.

في هذه الحالة، لا تتم كتابة أي سياقات تتبع إلى ملف تتبع ASCII لأنها ستكون كذلك
متكرر. سيختار النظام اسم الملف الذي سيتم إنشاؤه باستخدام نفس القواعد مثل
الموصوفة في قسم PCAP، باستثناء أن الملف سيكون له اللاحقة .tr بدلا من
.pcap.

· إذا كنت تريد تمكين تتبع ASCII على أكثر من جهاز شبكي واحد وإرسال كافة الآثار
إلى ملف واحد، يمكنك القيام بذلك أيضًا باستخدام كائن للإشارة إلى ملف واحد.
لقد رأينا هذا بالفعل في مثال "cwnd" أعلاه:

Ptr و 1 ؛
Ptr و 2 ؛

Ptr تيار = asciiTraceHelper.CreateFileStream ("trace-file-name.tr") ؛

المساعد EnableAscii (تيار ، nd1) ؛
المساعد EnableAscii (تيار ، nd2) ؛

في هذه الحالة، سياقات التتبع . مكتوبة في ملف تتبع ASCII لأنها مطلوبة
لإزالة الغموض عن الآثار من الجهازين. لاحظ أنه منذ المستخدم تماما
تحديد اسم الملف، يجب أن تتضمن السلسلة ملف ، آر لاحقة للاتساق.

· يمكنك تمكين تتبع ASCII على زوج معين (عقدة، شبكة جهاز) من خلال توفير
الأمراض المنقولة جنسيا :: سلسلة تمثل سلسلة خدمة اسم الكائن إلى ملف تمكينPcap طريقة. ال
Ptr تم البحث عنه من سلسلة الاسم. مرة أخرى ، فإن ضمنيًا منذ ذلك الحين
يجب أن ينتمي جهاز الشبكة المحدد إلى عقدة واحدة بالضبط. على سبيل المثال،

الأسماء :: إضافة ("العميل" ...) ؛
الأسماء :: إضافة ("client / eth0" ...) ؛
الأسماء :: إضافة ("الخادم" ...) ؛
الأسماء :: إضافة ("server / eth0" ...) ؛

helper.EnableAscii ("بادئة"، "client / eth0") ؛
helper.EnableAscii ("بادئة"، "server / eth0") ؛

سيؤدي ذلك إلى ظهور ملفين باسم "prefix-client-eth0.tr" و
``prefix-server-eth0.tr`` مع تتبعات لكل جهاز في
ملف التتبع المعني. نظرًا لأن جميع وظائف ``EnableAscii``
يتم تحميلها بشكل زائد لأخذ غلاف دفق، يمكنك استخدام هذا النموذج كـ
حسنًا::

الأسماء :: إضافة ("العميل" ...) ؛
الأسماء :: إضافة ("client / eth0" ...) ؛
الأسماء :: إضافة ("الخادم" ...) ؛
الأسماء :: إضافة ("server / eth0" ...) ؛

Ptr تيار = asciiTraceHelper.CreateFileStream ("trace-file-name.tr") ؛

helper.EnableAscii (تيار ، "العميل / eth0") ؛
helper.EnableAscii (تيار ، "الخادم / eth0") ؛

قد ينتج عن هذا ملف تتبع واحد يسمى تتبع اسم الملف.tr الذي يحتوي على كل
أحداث التتبع لكلا الجهازين. سيتم توضيح الأحداث من خلال سياق التتبع
سلاسل.

· يمكنك تمكين تتبع ASCII على مجموعة من أزواج (العقدة، الشبكة-الجهاز) من خلال توفير ملف
NetDeviceContainer. لكل واحد NetDevice في الحاوية يتم فحص النوع. لكل
جهاز من النوع المناسب (نفس النوع الذي يديره مساعد الجهاز) ، التتبع هو
ممكن. مرة أخرى ، فإن ضمنيًا نظرًا لأن جهاز الشبكة الذي تم العثور عليه يجب أن ينتمي إليه
عقدة واحدة بالضبط. على سبيل المثال،

NetDeviceContainer d = ... ؛

helper.EnableAscii ("البادئة" ، d) ؛

قد يؤدي هذا إلى إنشاء عدد من ملفات تتبع ASCII،
كل منها يتبع `` - - .tr``
مؤتمر.

يتم دمج كافة الآثار في ملف واحد بشكل مشابه للأمثلة
في الاعلى:

NetDeviceContainer d = ... ؛

Ptr تيار = asciiTraceHelper.CreateFileStream ("trace-file-name.tr") ؛

المساعد EnableAscii (تيار ، د) ؛

· يمكنك تمكين تتبع ASCII على مجموعة من أزواج (العقدة، الشبكة-الجهاز) من خلال توفير ملف
NodeContainer. لكل عقدة في NodeContainer مرفق به NetDevices تتكرر.
لكل NetDevice المرفقة بكل عقدة في الحاوية، هو نوع هذا الجهاز
التحقق. لكل جهاز من النوع المناسب (نفس النوع الذي يديره الجهاز
مساعد)، تم تمكين التتبع.

NodeContainer n ؛

helper.EnableAscii ("بادئة"، n) ؛

قد يؤدي هذا إلى إنشاء عدد من ملفات تتبع ASCII، يتبع كل منها
هيه - معرف> - معرف>. tr مؤتمر. الجمع بين كافة الآثار في أ
يتم إنجاز ملف واحد بشكل مشابه للأمثلة المذكورة أعلاه.

· يمكنك تمكين تتبع PCAP على أساس معرف العقدة ومعرف الجهاز بالإضافة إلى ذلك
صريح بي تي آر. تحتوي كل عقدة في النظام على معرف عقدة صحيح وكل جهاز متصل
إلى عقدة لديها معرف جهاز عدد صحيح.

helper.EnableAscii ("بادئة" ، 21 ، 1) ؛

بالطبع ، يمكن دمج الآثار في ملف واحد كما هو موضح أعلاه.

· وأخيرًا، يمكنك تمكين تتبع PCAP لجميع الأجهزة الموجودة في النظام، ومن نفس النوع
كما أن يديرها مساعد الجهاز.

helper.EnableAsciiAll ("بادئة") ؛

قد يؤدي هذا إلى إنشاء عدد من ملفات تتبع ASCII، ملف واحد لكل جهاز
في النظام من النوع الذي يديره المساعد. كل هذه الملفات سوف تتبع
- معرف> - معرف>. tr مؤتمر. الجمع بين كل الآثار في واحد
ملف تم إنجازه بشكل مشابه للأمثلة أعلاه.

أسماء الملفات
ضمنيًا في أوصاف أسلوب البادئة أعلاه هو بناء الكامل
أسماء الملفات عن طريق طريقة التنفيذ. وفقًا للاتفاقية، يتتبع ASCII في ملف NS-3 نظام
هي من الشكل - معرف> - معرف>. tr

كما ذكرنا سابقًا، سيكون لكل عقدة في النظام معرف عقدة مخصص للنظام؛ و
سيحتوي كل جهاز على فهرس واجهة (يسمى أيضًا معرف الجهاز) بالنسبة للعقدة الخاصة به.
افتراضيًا، يتم إنشاء ملف تتبع ASCII كنتيجة لتمكين التتبع في الملف الأول
جهاز Node 21، باستخدام البادئة "prefix"، سيكون البادئة 21-1.tr.

يمكنك دائمًا استخدام ملف NS-3 خدمة اسم الكائن لجعل هذا أكثر وضوحًا. على سبيل المثال ، إذا
يمكنك استخدام خدمة اسم الكائن لتعيين اسم "الخادم" للعقدة 21، مما ينتج عنه
سيصبح اسم ملف التتبع ASCII تلقائيًا، بادئة- server-1.tr وإذا قمت أيضًا بتعيين
الاسم "eth0" إلى الجهاز، وسيلتقط اسم ملف التتبع ASCII هذا تلقائيًا
ويتم استدعاؤهم بادئة- server-eth0.tr.

تحتوي العديد من الطرق على معلمة افتراضية تسمى صريح اسم الملف. عند الضبط على
صحيح أن هذه المعلمة تعمل على تعطيل آلية إكمال اسم الملف تلقائيًا وتسمح لك بذلك
لإنشاء اسم ملف واضح. هذا الخيار متاح فقط في الطرق التي تستغرق
البادئة وتمكين التتبع على جهاز واحد.

بروتوكول المساعدون
PCAP
الهدف من هؤلاء مزيج هو تسهيل إضافة وسيلة تتبع PCAP متسقة إلى
البروتوكولات. نريد أن تعمل جميع النكهات المختلفة لتتبع PCAP بنفس الطريقة في الجميع
البروتوكولات ، لذلك يتم توريث أساليب هؤلاء المساعدين بواسطة مساعدي المكدس. ألق نظرة على
src / network / helper / trace-helper.h إذا كنت تريد متابعة المناقشة أثناء النظر في
كود حقيقي.

سنقوم في هذا القسم بتوضيح الأساليب المطبقة على البروتوكول IPv4. إلى
تحديد التتبع في بروتوكولات مماثلة ، فقط استبدل النوع المناسب. على سبيل المثال،
إستخدم Ptr بدلا من Ptr و اتصل تمكينPcapIpv6 بدلا من تمكينPcapIpv4.

الفصل PcapHelperForIpv4 يوفر وظائف عالية المستوى لاستخدام تتبع PCAP
في ال IPv4 بروتوكول. يجب أن يقوم كل مساعد بروتوكول يتيح هذه الأساليب بتنفيذ ملف
الطريقة الافتراضية الموروثة من هذه الفئة. سيكون هناك تنفيذ منفصل لـ
IPv6، على سبيل المثال ، ولكن الاختلاف الوحيد سيكون في أسماء الطرق والتوقيعات.
مطلوب أسماء طرق مختلفة لإزالة الغموض عن الفصل IPv4 تبدأ من IPv6 كلاهما
مشتق من الطبقة هدفوالطرق التي تشترك في نفس التوقيع.

الفراغ الظاهري EnablePcapIpv4Internal (بادئة سلسلة::std،
بي تي آر IPv4,
واجهة uint32_t،
منطقي اسم الملف الواضح) = 0؛

يعكس توقيع هذه الطريقة البروتوكول وعرض مركز الواجهة لـ
الوضع على هذا المستوى. جميع الأساليب العامة الموروثة من الطبقة PcapHelperForIpv4
تقليل إلى استدعاء طريقة التنفيذ المعتمدة على جهاز واحد. على سبيل المثال ، ملف
طريقة PCAP ذات المستوى الأدنى

EnablePcapIpv4 باطلة (std::string بادئة، Ptr ipv4, واجهة uint4_t, bool plainFilename = false);

سيستدعي تنفيذ الجهاز لـ تمكينPcapIpv4Internal مباشرة. كل الجمهور الآخر
تعتمد أساليب تتبع PCAP على هذا التنفيذ لتوفير مستوى إضافي للمستخدم
وظائف. ما يعنيه هذا للمستخدم هو أن جميع مساعدي البروتوكول في النظام
سيكون لديه كافة أساليب التتبع PCAP المتاحة؛ وستعمل جميع هذه الأساليب في
بنفس الطريقة عبر البروتوكولات إذا قام المساعد بتنفيذها تمكينPcapIpv4Internal بشكل صحيح.

طرق
تم تصميم هذه الأساليب لتكون في مراسلات فردية مع العقدة و
NetDevice- الإصدارات المركزية لإصدارات الجهاز. بدلاً من العقدة و NetDevice زوج
القيود ، نستخدم قيود البروتوكول والواجهة.

لاحظ أنه تمامًا كما هو الحال في إصدار الجهاز ، هناك ست طرق:

EnablePcapIpv4 باطلة (std::string بادئة، Ptr ipv4, واجهة uint4_t, bool plainFilename = false);
void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t Interface, bool plainFilename = false);
باطل EnablePcapIpv4 (std :: string بادئة ، Ipv4InterfaceContainer c) ؛
EnablePcapIpv4 باطلة (بادئة std :: string ، NodeContainer n) ؛
void EnablePcapIpv4 (std::string prefix, uint32_tnodeid, uint32_t Interface, bool plainFilename);
باطل EnablePcapIpv4All (std :: string بادئة) ؛

نشجعك على الاطلاع على وثائق واجهة برمجة التطبيقات (API) الخاصة بالفصل الدراسي PcapHelperForIpv4 لتجد ال
تفاصيل هذه الأساليب ؛ لكن لتلخيص ...

· يمكنك تمكين تتبع PCAP على زوج بروتوكول/واجهة معين من خلال توفير ملف
Ptr الواجهة إلى تمكينPcap طريقة. على سبيل المثال،

Ptr ipv4 = عقدة-> GetObject () ؛

helper.EnablePcapIpv4 ("بادئة"، ipv4، 0) ؛

· يمكنك تمكين تتبع PCAP على زوج عقدة/جهاز شبكة معين من خلال توفير ملف
الأمراض المنقولة جنسيا :: سلسلة تمثل سلسلة خدمة اسم الكائن إلى ملف تمكينPcap طريقة. ال
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 على أساس معرف العقدة والواجهة أيضًا. في هذا
في الحالة، تتم ترجمة معرف العقدة إلى a Ptr ويتم البحث عن البروتوكول المناسب
في العقدة. يتم استخدام البروتوكول والواجهة الناتجة لتحديد النتيجة
مصدر التتبع.

helper.EnablePcapIpv4 ("بادئة"، 21، 1) ؛

· وأخيراً، يمكنك تمكين PCAP لتتبع كافة الواجهات في النظام، مع المرتبطة بها
البروتوكول هو نفس النوع الذي يديره مساعد الجهاز.

helper.EnablePcapIpv4All ("بادئة") ؛

أسماء الملفات
ضمنيًا في جميع توصيفات الطريقة أعلاه هو بناء الكامل
أسماء الملفات عن طريق طريقة التنفيذ. وفقًا للاتفاقية، يتم أخذ آثار PCAP للأجهزة الموجودة في
هيه NS-3 النظام على شكل " - - .pcap". في حالة
بروتوكول تتبع ، هناك مراسلات واحد لواحد بين البروتوكولات و العقد. هذا
وذلك لأن البروتوكول الأجسام يتم تجميعها إلى العقدة الأجسام. لأنه لا يوجد عالمي
معرف البروتوكول في النظام، نستخدم معرف العقدة المقابل في تسمية الملفات. لذلك
هناك احتمالية لتضارب أسماء الملفات في أسماء ملفات التتبع التي تم اختيارها تلقائيًا.
لهذا السبب، يتم تغيير اصطلاح اسم الملف لتتبعات البروتوكول.

كما ذكرنا سابقًا، سيكون لكل عقدة في النظام معرف عقدة مخصص للنظام.
نظرًا لوجود مراسلات فردية بين مثيلات البروتوكول ومثيلات العقدة
نحن نستخدم معرف العقدة. تحتوي كل واجهة على معرف واجهة يتعلق بالبروتوكول الخاص بها. نحن نستخدم
الاتفاقية " -ن -أنا .pcap "لتسمية ملف التتبع بتنسيق
مساعدي البروتوكول.

لذلك، بشكل افتراضي، يتم إنشاء ملف تتبع PCAP كنتيجة لتمكين التتبع
ستكون الواجهة 1 لبروتوكول Ipv4 للعقدة 21 باستخدام البادئة "البادئة".
"البادئة-n21-i1.pcap".

يمكنك دائمًا استخدام ملف NS-3 خدمة اسم الكائن لجعل هذا أكثر وضوحًا. على سبيل المثال ، إذا
يمكنك استخدام خدمة اسم الكائن لتعيين الاسم "serverIpv4" إلى Ptr على العقدة
21، سيصبح اسم ملف تتبع PCAP الناتج تلقائيًا،
"بادئة nserverIpv4-i1.pcap".

تحتوي العديد من الطرق على معلمة افتراضية تسمى صريح اسم الملف. عند الضبط على
صحيح أن هذه المعلمة تعمل على تعطيل آلية إكمال اسم الملف تلقائيًا وتسمح لك بذلك
لإنشاء اسم ملف واضح. هذا الخيار متاح فقط في الطرق التي تستغرق
البادئة وتمكين التتبع على جهاز واحد.

ASCII
يشبه سلوك مساعدات التتبع ASCII إلى حد كبير حالة PCAP. خذ أ
النظر في src / network / helper / trace-helper.h إذا كنت تريد متابعة المناقشة أثناء
بالنظر إلى الكود الحقيقي.

سنقوم في هذا القسم بتوضيح الأساليب المطبقة على البروتوكول IPv4. إلى
تحديد التتبع في بروتوكولات مماثلة ، فقط استبدل النوع المناسب. على سبيل المثال،
إستخدم Ptr بدلا من Ptr و اتصل تمكينAsciiIpv6 بدلا من
تمكينAsciiIpv4.

الفصل AsciiTraceHelperForIpv4 يضيف وظائف عالية المستوى لاستخدام ASCII
تتبع إلى مساعد بروتوكول. يجب على كل بروتوكول يمكّن هذه الأساليب تنفيذ أ
طريقة افتراضية واحدة موروثة من هذه الفئة.

الفراغ الظاهري EnableAsciiIpv4Internal (Ptr تدفق،
الأمراض المنقولة جنسيا::سلسلة البادئة،
بي تي آر IPv4,
واجهة uint32_t،
منطقي اسم الملف الواضح) = 0؛

يعكس توقيع هذه الطريقة طريقة عرض البروتوكول والواجهة المركزية لـ
الوضع على هذا المستوى. وكذلك حقيقة أن المساعد ربما يكتب إلى ملف مشترك
تيار الإخراج. جميع الأساليب العامة الموروثة من الطبقة
PcapAndAsciiTraceHelperForIpv4 تقليل إلى استدعاء هذا الجهاز الفردي المعتمد
طريقة التنفيذ. على سبيل المثال، أساليب تتبع ASCII ذات المستوى الأدنى،

باطلة EnableAsciiIpv4 (std::string بادئة، Ptr ipv4, واجهة uint4_t, bool plainFilename = false);
باطل EnableAsciiIpv4 (Ptr تيار ، Ptr ipv4 ، واجهة uint4_t) ؛

سيستدعي تنفيذ الجهاز لـ تمكينAsciiIpv4Internal بشكل مباشر ، مع توفير إما
البادئة أو الدفق. ستعتمد جميع طرق تتبع ASCII العامة الأخرى على هذه الأساليب
وظائف منخفضة المستوى لتوفير وظائف إضافية على مستوى المستخدم. ماذا يعني هذا ل
المستخدم هو أن جميع مساعدي الأجهزة في النظام سيكون لديهم جميع طرق تتبع ASCII
متاح؛ وستعمل جميع هذه الطرق بنفس الطريقة عبر البروتوكولات إذا كان
تنفيذ البروتوكولات EnablAsciiIpv4 داخلي بشكل صحيح.

طرق
باطلة EnableAsciiIpv4 (std::string بادئة، Ptr ipv4, واجهة uint4_t, bool plainFilename = false);
باطل EnableAsciiIpv4 (Ptr تيار ، Ptr ipv4 ، واجهة uint4_t) ؛

void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t Interface, bool plainFilename = false);
باطل EnableAsciiIpv4 (Ptr تيار ، الأمراض المنقولة جنسيا :: سلسلة ipv4Name ، واجهة uint32_t) ؛

باطل EnableAsciiIpv4 (std :: string بادئة ، Ipv4InterfaceContainer c) ؛
باطل EnableAsciiIpv4 (Ptr تيار ، Ipv4InterfaceContainer ج) ؛

باطل EnableAsciiIpv4 (std :: string بادئة ، NodeContainer n) ؛
باطل EnableAsciiIpv4 (Ptr تيار ، NodeContainer n) ؛

باطل EnableAsciiIpv4All (std :: string prefix) ؛
باطل EnableAsciiIpv4All (Ptr تدفق)؛

void EnableAsciiIpv4 (std::string prefix, uint32_tnodeid, uint32_t devicesid, bool plainFilename);
باطل EnableAsciiIpv4 (Ptr تيار ، uint32_t nodeid ، واجهة uint32_t) ؛

نشجعك على الاطلاع على وثائق واجهة برمجة التطبيقات (API) الخاصة بالفصل الدراسي PcapAndAsciiHelperForIpv4 إلى
العثور على تفاصيل هذه الأساليب. ولكن لتلخيص ...

· هناك ضعف عدد الطرق المتاحة لتتبع ASCII مقارنة بـ PCAP
اقتفاء أثر. وذلك لأنه بالإضافة إلى نموذج نمط PCAP حيث توجد آثار من كل منهما
تتم كتابة زوج بروتوكول / واجهة فريد في ملف فريد ، ونحن ندعم نموذجًا فيه
تتم كتابة معلومات التتبع للعديد من أزواج البروتوكول / الواجهة في ملف مشترك. هذا
يعني أن -ن - آلية إنشاء اسم الملف هي
واستبدالها بآلية للإشارة إلى ملف مشترك؛ وعدد طرق API هو
تضاعف للسماح لجميع المجموعات.

· كما هو الحال في تتبع PCAP، يمكنك تمكين تتبع ASCII على بروتوكول/واجهة معينة
الزوج من خلال توفير ملف Ptr و الواجهة إلى تمكين طريقة. على سبيل المثال،

Ptr ipv4 ؛

helper.EnableAsciiIpv4 ("بادئة" ، ipv4 ، 1) ؛

في هذه الحالة، لا تتم كتابة أي سياقات تتبع إلى ملف تتبع ASCII لأنها ستكون كذلك
متكرر. سيختار النظام اسم الملف الذي سيتم إنشاؤه باستخدام نفس القواعد مثل
الموصوفة في قسم PCAP، باستثناء أن الملف سيحتوي على اللاحقة ".tr" بدلاً من ذلك
من ".pcap".

· إذا كنت تريد تمكين تتبع ASCII على أكثر من واجهة واحدة وإرسال كافة الآثار
إلى ملف واحد، يمكنك القيام بذلك أيضًا باستخدام كائن للإشارة إلى ملف واحد.
لدينا بالفعل شيء مشابه لهذا في مثال "cwnd" أعلاه:

Ptr Protocol4 = node1-> GetObject () ؛
Ptr Protocol4 = node2-> GetObject () ؛

Ptr تيار = asciiTraceHelper.CreateFileStream ("trace-file-name.tr") ؛

helper.EnableAsciiIpv4 (تيار ، بروتوكول 1 ، 1) ؛
helper.EnableAsciiIpv4 (تيار ، بروتوكول 2 ، 1) ؛

في هذه الحالة، تتم كتابة سياقات التتبع إلى ملف التتبع ASCII نظرًا لأنها مطلوبة
لإزالة الغموض عن الآثار من الواجهتين. لاحظ أنه منذ المستخدم تماما
عند تحديد اسم الملف، يجب أن تتضمن السلسلة "،tr" لتحقيق الاتساق.

· يمكنك تمكين تتبع ASCII على بروتوكول معين من خلال توفير الأمراض المنقولة جنسيا :: سلسلة
تمثل سلسلة خدمة اسم الكائن إلى ملف تمكينPcap طريقة. ال Ptr is
بحثت عن سلسلة الاسم. ال في أسماء الملفات الناتجة ضمنيًا منذ ذلك الحين
هناك مراسلات فردية بين مثيلات البروتوكول والعقد، على سبيل المثال،

الأسماء :: إضافة ("node1Ipv4" ...) ؛
الأسماء :: إضافة ("node2Ipv4" ...) ؛

helper.EnableAsciiIpv4 ("بادئة"، "node1Ipv4"، 1) ؛
helper.EnableAsciiIpv4 ("بادئة"، "node2Ipv4"، 1) ؛

قد ينتج عن هذا ملفين باسم "بادئة-nnode1Ipv4-i1.tr" و
"بادئة-nnode2Ipv4-i1.tr" مع تتبعات لكل واجهة في ملف التتبع المعني.
نظرًا لأن جميع وظائف EnableAscii محملة فوق طاقتها لأخذ غلاف دفق ، يمكنك ذلك
استخدم هذا النموذج أيضًا:

الأسماء :: إضافة ("node1Ipv4" ...) ؛
الأسماء :: إضافة ("node2Ipv4" ...) ؛

Ptr تيار = 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، يتبع كل منها
ال -ن -أنا .tr اتفاقية. يتم دمج كل الآثار في ملف
ملف واحد يتم إنجازه بشكل مشابه للأمثلة أعلاه:

عقد NodeContainer

أجهزة NetDeviceContainer = deviceHelper.Install (العقد) ؛

IPv4AddressHelper ipv4 ؛
ipv4.SetBase ("10.1.1.0"، "255.255.255.0") ؛
واجهات Ipv4InterfaceContainer = ipv4.Assign (الأجهزة) ؛

Ptr تيار = asciiTraceHelper.CreateFileStream ("trace-file-name.tr") ؛

helper.EnableAsciiIpv4 (دفق ، واجهات) ؛

· يمكنك تمكين تتبع ASCII على مجموعة من أزواج البروتوكول/الواجهة من خلال توفير ملف
NodeContainer. لكل عقدة في NodeContainer تم العثور على البروتوكول المناسب.
يتم تعداد واجهات كل بروتوكول وتمكين التتبع على النتائج
أزواج. على سبيل المثال،

NodeContainer n ؛

helper.EnableAsciiIpv4 ("بادئة"، n) ؛

قد يؤدي هذا إلى إنشاء عدد من ملفات تتبع ASCII، يتبع كل منها
ال - - .tr اتفاقية. يتم دمج كل الآثار في ملف
يتم إنجاز ملف واحد بشكل مشابه للأمثلة المذكورة أعلاه.

· يمكنك تمكين تتبع PCAP على أساس معرف العقدة ومعرف الجهاز أيضًا. في هذا
في الحالة، تتم ترجمة معرف العقدة إلى a Ptr ويتم البحث عن البروتوكول المناسب
في العقدة. يتم استخدام البروتوكول والواجهة الناتجة لتحديد النتيجة
مصدر التتبع.

helper.EnableAsciiIpv4 ("بادئة"، 21، 1) ؛

بالطبع ، يمكن دمج الآثار في ملف واحد كما هو موضح أعلاه.

· وأخيرا، يمكنك تمكين تتبع ASCII لجميع الواجهات في النظام، مع المرتبطة بها
البروتوكول هو نفس النوع الذي يديره مساعد الجهاز.

helper.EnableAsciiIpv4All ("بادئة") ؛

قد يؤدي هذا إلى إنشاء عدد من ملفات تتبع ASCII، واحد لكل منها
واجهة في النظام تتعلق ببروتوكول من النوع الذي يديره المساعد. كل
ستتبع هذه الملفات -ن -أنا
يتم تنفيذ جميع عمليات التتبع في ملف واحد بشكل مشابه للأمثلة المذكورة أعلاه.

أسماء الملفات
ضمنيًا في أوصاف أسلوب البادئة أعلاه هو بناء الكامل
أسماء الملفات عن طريق طريقة التنفيذ. وفقًا للاتفاقية، يتتبع ASCII في ملف NS-3 نظام
هي من الشكل " - - .tr"

كما ذكرنا سابقًا، سيكون لكل عقدة في النظام معرف عقدة مخصص للنظام.
نظرًا لوجود مراسلات فردية بين البروتوكولات والعقد التي نستخدمها لمعرف العقدة
لتحديد هوية البروتوكول. سيكون لكل واجهة على بروتوكول معين
فهرس الواجهة (يسمى أيضًا ببساطة واجهة) بالنسبة إلى بروتوكولها. بشكل افتراضي،
بعد ذلك، يتم إنشاء ملف تتبع ASCII كنتيجة لتمكين التتبع على الجهاز الأول
العقدة 21، باستخدام البادئة "prefix"، ستكون "prefix-n21-i1.tr". استخدم البادئة ل
توضيح عدة بروتوكولات لكل عقدة.

يمكنك دائمًا استخدام ملف NS-3 خدمة اسم الكائن لجعل هذا أكثر وضوحًا. على سبيل المثال ، إذا
يمكنك استخدام خدمة اسم الكائن لتعيين اسم "serverIpv4" للبروتوكول الموجود على Node
21، وكذلك تحديد الواجهة الأولى، سيتم تلقائيًا إنشاء اسم ملف التتبع ASCII الناتج
تصبح ، "بادئة-nserverIpv4-1.tr".

تحتوي العديد من الطرق على معلمة افتراضية تسمى صريح اسم الملف. عند الضبط على
صحيح أن هذه المعلمة تعمل على تعطيل آلية إكمال اسم الملف تلقائيًا وتسمح لك بذلك
لإنشاء اسم ملف واضح. هذا الخيار متاح فقط في الطرق التي تستغرق
البادئة وتمكين التتبع على جهاز واحد.

الملخص
NS-3 يتضمن بيئة غنية للغاية تسمح للمستخدمين بالتخصيص على عدة مستويات
أنواع المعلومات التي يمكن استخلاصها من عمليات المحاكاة.

هناك وظائف مساعدة عالية المستوى تتيح للمستخدمين التحكم ببساطة في مجموعة الملفات
مخرجات محددة مسبقًا بدقة دقيقة. هناك وظائف مساعدة متوسطة المستوى للسماح بها
مستخدمين أكثر تطوراً لتخصيص كيفية استخراج المعلومات وحفظها؛ و هناك
هي وظائف أساسية منخفضة المستوى للسماح للمستخدمين الخبراء بتغيير النظام لتقديم جديد و
المعلومات التي لم يتم تصديرها مسبقًا بطريقة يمكن للمستخدمين الوصول إليها على الفور
مستويات أعلى.

هذا نظام شامل للغاية، ونحن ندرك أنه يتطلب الكثير من الهضم، على وجه الخصوص
للمستخدمين الجدد أو أولئك الذين ليسوا على دراية وثيقة بـ C++ ومصطلحاته. نحن نعتبر
يعد نظام التتبع جزءًا مهمًا جدًا من NS-3 ولذا نوصي بأن تصبح مألوفًا
ممكن معها. ربما يكون الأمر كذلك هو فهم بقية NS-3 نظام
سيكون الأمر بسيطًا للغاية بمجرد إتقان نظام التتبع

بيانات مجموعة


يقدم الفصل التعليمي الأخير لدينا بعض المكونات التي تمت إضافتها إليها NS-3 في الإصدار
3.18، والتي لا تزال قيد التطوير. هذا القسم التعليمي هو أيضا
العمل قيد التنفيذ.

التحفيز
إحدى النقاط الرئيسية لتشغيل عمليات المحاكاة هي إنشاء بيانات المخرجات، سواءً كانت
لأغراض البحث أو ببساطة للتعرف على النظام. في الفصل السابق نحن
قدم النظام الفرعي للتتبع والمثال six.cc. من خلالها تتبع PCAP أو ASCII
يتم إنشاء ملفات . هذه الآثار ذات قيمة لتحليل البيانات باستخدام مجموعة متنوعة من
أدوات خارجية، وبالنسبة للعديد من المستخدمين، تعد بيانات المخرجات هذه وسيلة مفضلة لجمعها
البيانات (للتحليل بواسطة أدوات خارجية).

ومع ذلك، هناك أيضًا حالات استخدام لأكثر من مجرد إنشاء ملفات التتبع، بما في ذلك
التالية:

· توليد البيانات التي لا تتوافق بشكل جيد مع آثار PCAP أو ASCII، مثل البيانات غير الحزمة
البيانات (مثل انتقالات آلة حالة البروتوكول)،

عمليات المحاكاة الكبيرة التي يتطلبها إدخال/إخراج القرص لتوليد ملفات التتبع
محظورة أو مرهقة، و

· الحاجة إلى online تقليل البيانات أو حسابها، أثناء عملية المحاكاة.
وخير مثال على ذلك هو تحديد شرط إنهاء المحاكاة
متى يتوقف عندما يتلقى بيانات كافية لتكوين ثقة ضيقة بما فيه الكفاية
الفاصل الزمني حول تقدير بعض المعلمات.

إنّ NS-3 تم تصميم إطار جمع البيانات لتوفير هذه القدرات الإضافية
أبعد من الإخراج القائم على التتبع. ونوصي القارئ المهتم بهذا الموضوع باستشارة
هيه NS-3 دليل لمعالجة أكثر تفصيلا لهذا الإطار؛ هنا، نلخص مع
برنامج مثال لبعض القدرات النامية.

مثال رمز
المثال التعليمي أمثلة/البرنامج التعليمي/seventh.cc يشبه six.cc مثال نحن
تمت مراجعتها مسبقًا، باستثناء بعض التغييرات. أولاً، تم تمكينه لـ IPv6
الدعم مع خيار سطر الأوامر:

CommandLine كمد ؛
cmd.AddValue ("useIpv6"، "استخدام Ipv6"، useV6)؛
cmd ، Parse (argc ، argv) ؛

إذا حدد المستخدم useIpv6الخيار، سيتم تشغيل البرنامج باستخدام IPv6 بدلاً من IPv4.
إنّ مساعدة الخيار متاح للجميع NS-3 البرامج التي تدعم كائن CommandLine كـ
كما هو موضح أعلاه، يمكن استدعاؤه على النحو التالي (يرجى ملاحظة استخدام علامات الاقتباس المزدوجة):

./waf --تشغيل "السابع --مساعدة"

الذي ينتج:

ns3-dev-seventh-debug [وسائط البرنامج] [الوسائط العامة]

حجج البرنامج:
--useIpv6: استخدم Ipv6 [خطأ]

الحجج العامة:
--PrintGlobals: طباعة قائمة العالميات.
--PrintGroups: طباعة قائمة المجموعات.
--PrintGroup=[group]: طباعة كافة معرفات المجموعة.
--PrintTypeIds: طباعة كافة معرفات النوع.
--PrintAttributes=[typeid]: طباعة كافة سمات typeid.
--PrintHelp: اطبع رسالة المساعدة هذه.

يمكن تغيير هذا الافتراضي (استخدام IPv4، نظرًا لأن useIpv6 خطأ) عن طريق تبديل القيمة المنطقية
القيمة على النحو التالي:

./waf --تشغيل "السابع --useIpv6=1"

وإلقاء نظرة على PCAP الذي تم إنشاؤه، كما هو الحال مع com.tcpdump:

tcpdump -r السابع.pcap -nn -tt

لقد كان هذا استطرادا قصيرا لدعم IPv6 وسطر الأوامر، والذي كان كذلك
تم تقديمه مسبقًا في هذا البرنامج التعليمي. للحصول على مثال مخصص لاستخدام سطر الأوامر،
لطفا أنظر src/core/examples/command-line-example.cc.

عاد الآن إلى جمع البيانات. في ال أمثلة / البرنامج التعليمي / الدليل، اكتب ما يلي
أمر: فرق -u six.cc السابع، وفحص بعض الأسطر الجديدة لهذا الاختلاف:

+ الأمراض المنقولة جنسيا::نوع التحقيق سلسلة؛
+ ستد::سلسلة تتبع المسار؛
+ إذا (useV6 == خطأ)
+ {

+probeType = "ns3::Ipv4PacketProbe";
+ TracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
+ }
+ آخر
+ {

+probeType = "ns3::Ipv6PacketProbe";
+ TracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
+ }

+ // استخدم GnuplotHelper لرسم عدد بايتات الحزمة بمرور الوقت
+ GnuplotHelperplotHelper;
+
+ // تكوين المؤامرة. الوسيطة الأولى هي بادئة اسم الملف
+ // لملفات الإخراج التي تم إنشاؤها. الثاني والثالث والرابع
+ // الوسائط هي، على التوالي، عنوان قطعة الأرض، والمحور السيني، والمحور الصادي
+plotHelper.ConfigurePlot ("عدد البايتات السابع للحزمة"،
+ "عدد بايتات الحزمة مقابل الوقت"،
+ "الوقت (بالثواني)"،
+ "عدد بايت الحزمة")؛
+
+ // حدد نوع المسبار، وتتبع مسار المصدر (في مساحة اسم التكوين)، و
+ // التحقيق في مصدر تتبع الإخراج ("OutputBytes") للتخطيط. الحجة الرابعة
+ // يحدد اسم تسمية سلسلة البيانات على قطعة الأرض. الاخير
+ // تقوم الوسيطة بتنسيق المؤامرة عن طريق تحديد المكان الذي يجب وضع المفتاح فيه.
+plotHelper.PlotProbe (probeType،
+ مسار التتبع،
+ "وحدات بايت الإخراج"،
+ "عدد بايت الحزمة"،
+ GnuplotAggregator::KEY_BELOW);
+
+ // استخدم FileHelper لكتابة عدد بايت الحزمة بمرور الوقت
+ FileHelper fileHelper؛
+
+ // تكوين الملف المراد كتابته وتنسيق بيانات الإخراج.
+ fileHelper.ConfigureFile ("عدد البايتات السابعة للحزمة"،
+ مجمع الملفات::FORMATTED);
+
+ // قم بتعيين التسميات لملف الإخراج المنسق هذا.
+ fileHelper.Set2dFormat ("الوقت (الثواني) = %.3e\tعدد بايت الحزمة = %.0f");
+
+ // حدد نوع المسبار ومسار المسبار (في مساحة اسم التكوين) و
+ // التحقيق في مصدر تتبع الإخراج ("OutputBytes") للكتابة.
+ fileHelper.WriteProbe (probeType،
+ مسار التتبع،
+ "وحدات بايت الإخراج");
+
محاكي::توقف (ثواني (20))؛
محاكي :: تشغيل () ؛
جهاز محاكاة :: تدمير () ؛

لا بد أن القارئ المتأني قد لاحظ، عند اختبار سمة سطر أوامر IPv6 أعلاه،
أن السابع قام بإنشاء عدد من ملفات الإخراج الجديدة:

الحزمة السابعة بايت عدد 0.txt
الحزمة السابعة بايت عدد 1.txt
الحزمة السابعة بايت عدد. dat
العدد السابع للحزمة البايت
عدد البايتات السابعة.png
الحزمة السابعة بايت- العد. sh

تم إنشاؤها بواسطة البيانات الإضافية المقدمة أعلاه؛ على وجه الخصوص، من قبل أ
GnuplotHelper وFileHelper. تم إنتاج هذه البيانات عن طريق ربط جمع البيانات
المكونات ل NS-3 تتبع المصادر، وتنظيم البيانات في شكل منسق غنوبلوت
في ملف نصي منسق. وفي الأقسام التالية، سنراجع كلًا منها.

مساعد Gnuplot
GnuplotHelper هو NS-3 كائن مساعد يهدف إلى إنتاج غنوبلوت المؤامرات مع
أقل عدد ممكن من البيانات، للحالات الشائعة. انها السنانير NS-3 تتبع المصادر بالبيانات
الأنواع التي يدعمها نظام جمع البيانات. ليس كل شيء NS-3 أنواع بيانات مصادر التتبع هي
مدعومة، ولكن العديد من أنواع التتبع الشائعة هي كذلك، بما في ذلك TracedValues ​​ذات القيمة القديمة البسيطة
أنواع البيانات (POD).

دعونا نلقي نظرة على المخرجات التي ينتجها هذا المساعد:

الحزمة السابعة بايت عدد. dat
العدد السابع للحزمة البايت
الحزمة السابعة بايت- العد. sh

الأول هو ملف بيانات gnuplot الذي يحتوي على سلسلة من الطوابع الزمنية والحزم المحددة بمسافات
عدد البايتات. سنغطي كيفية تكوين مخرجات البيانات المحددة هذه أدناه، ولكن دعنا نفعل ذلك
تواصل مع ملفات الإخراج. الملف العدد السابع للحزمة البايت هي مؤامرة gnuplot
الملف الذي يمكن فتحه من داخل gnuplot. يمكن للقراء الذين يفهمون بناء جملة gnuplot أن يفعلوا ذلك
تأكد من أن هذا سيؤدي إلى إخراج ملف PNG منسق باسم
عدد البايتات السابعة.png. وأخيرا، نص شل صغير
الحزمة السابعة بايت- العد. sh يقوم بتشغيل ملف الرسم هذا من خلال gnuplot لإنتاج الملف المطلوب
PNG (الذي يمكن عرضه في محرر الصور)؛ أي الأمر:

sh XNUMX-packet-byte-count.sh

سوف تسفر عدد البايتات السابعة.png. لماذا لم يتم إنتاج PNG هذا في الأول
مكان؟ الجواب هو أنه من خلال توفير ملف plt، يمكن للمستخدم تكوين ملف
النتيجة إذا رغبت في ذلك، قبل إنتاج PNG.

ينص عنوان صورة PNG على أن هذه المؤامرة عبارة عن مؤامرة "عدد بايت الحزمة مقابل الوقت"، و
أنه يقوم بتخطيط البيانات التي تم فحصها والتي تتوافق مع مسار مصدر التتبع:

/NodeList/*/$ns3::Ipv6L3Protocol/Tx

لاحظ حرف البدل في مسار التتبع. باختصار، ما تلتقطه هذه الحبكة هو الحبكة
من بايتات الحزمة التي تمت ملاحظتها عند مصدر تتبع الإرسال لكائن Ipv6L3Protocol؛
إلى حد كبير مقاطع TCP بحجم 596 بايت في اتجاه واحد، و60 بايت TCP في الاتجاه الآخر (اثنان
تمت مطابقة مصادر تتبع العقدة مع مصدر التتبع هذا).

كيف تم تكوين هذا؟ من الضروري تقديم بعض البيانات. أولاً، برنامج GnuplotHelper
يجب الإعلان عن الكائن وتكوينه:

+ // استخدم GnuplotHelper لرسم عدد بايتات الحزمة بمرور الوقت
+ GnuplotHelperplotHelper;
+
+ // تكوين المؤامرة. الوسيطة الأولى هي بادئة اسم الملف
+ // لملفات الإخراج التي تم إنشاؤها. الثاني والثالث والرابع
+ // الوسائط هي، على التوالي، عنوان قطعة الأرض، والمحور السيني، والمحور الصادي
+plotHelper.ConfigurePlot ("عدد البايتات السابع للحزمة"،
+ "عدد بايتات الحزمة مقابل الوقت"،
+ "الوقت (بالثواني)"،
+ "عدد بايت الحزمة")؛

إلى هذه النقطة، تم تكوين قطعة أرض فارغة. بادئة اسم الملف هي الأولى
الوسيطة، عنوان الحبكة هو الثاني، وتسمية المحور السيني هي الثالثة، وتسمية المحور ص
الحجة الرابعة.

الخطوة التالية هي تكوين البيانات، وهنا يتم ربط مصدر التتبع.
أولاً، لاحظ أعلاه في البرنامج أننا أعلنا عن بعض المتغيرات لاستخدامها لاحقًا:

+ الأمراض المنقولة جنسيا::نوع التحقيق سلسلة؛
+ ستد::سلسلة تتبع المسار؛
+probeType = "ns3::Ipv6PacketProbe";
+ TracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";

نستخدمها هنا:

+ // حدد نوع المسبار، وتتبع مسار المصدر (في مساحة اسم التكوين)، و
+ // التحقيق في مصدر تتبع الإخراج ("OutputBytes") للتخطيط. الحجة الرابعة
+ // يحدد اسم تسمية سلسلة البيانات على قطعة الأرض. الاخير
+ // تقوم الوسيطة بتنسيق المؤامرة عن طريق تحديد المكان الذي يجب وضع المفتاح فيه.
+plotHelper.PlotProbe (probeType،
+ مسار التتبع،
+ "وحدات بايت الإخراج"،
+ "عدد بايت الحزمة"،
+ GnuplotAggregator::KEY_BELOW);

الوسيطتان الأوليان هما اسم نوع المسبار ومسار مصدر التتبع. هؤلاء
من المحتمل أن يكون تحديد اثنين هو الأصعب عند محاولة استخدام هذا الإطار لرسم إطار آخر
آثار. أثر التحقيق هنا هو Tx تتبع مصدر الطبقة بروتوكول IPv6L3. عندما كنا
فحص تنفيذ هذا الفصل (src/internet/model/ipv6-l3-protocol.cc) يمكننا أن نلاحظ:

.AddTraceSource ("Tx"، "إرسال حزمة IPv6 إلى الواجهة الصادرة."،
MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace))

هذا يقول ذلك Tx هو اسم للمتغير m_txTrace، والذي يحتوي على إعلان:

/ **
* \brief Callback لتتبع حزم TX (الإرسال).
*/
تتبع الاتصال , بي تي آر , uint6_t> m_txTrace;

اتضح أن توقيع مصدر التتبع المحدد هذا مدعوم بفئة Probe (what
نحتاجه هنا) من فئة Ipv6PacketProbe. انظر الملفات
src/internet/model/ipv6-packet-probe.{h,cc}.

لذا، في عبارة PlotProbe أعلاه، نرى أن العبارة تقوم بربط التتبع
المصدر (يتم تحديده بواسطة سلسلة المسار) مع مطابقة NS-3 نوع المسبار IPv6PacketProbe. إذا
لم ندعم هذا النوع من المسبار (مطابقة توقيع مصدر التتبع)، لم يكن من الممكن أن نفعل ذلك
استخدم هذا البيان (على الرغم من أنه كان من الممكن أن تكون بعض البيانات ذات المستوى الأدنى الأكثر تعقيدًا
المستخدمة، كما هو موضح في الدليل).

يقوم Ipv6PacketProbe بتصدير بعض مصادر التتبع التي تستخرج البيانات من الملف
كائن الحزمة الذي تم اختباره:

النوع
Ipv6PacketProbe :: GetTypeId ()
{
ثابت TypeId tid = TypeId ("ns3 :: Ipv6PacketProbe")
.SetParent ()
.AddConstructor ()
.AddTraceSource ("الإخراج"،
"الحزمة بالإضافة إلى كائن IPv6 الخاص بها والواجهة التي تعمل كإخراج لهذا التحقيق" ،
MakeTraceSourceAccessor (& Ipv6PacketProbe :: m_output))
.AddTraceSource ("OutputBytes"،
"عدد البايت في الحزمة" ،
MakeTraceSourceAccessor (& Ipv6PacketProbe :: m_outputBytes))
;
عودة المد
}

تحدد الوسيطة الثالثة في بيان PlotProbe أننا مهتمون بـ
عدد البايتات في هذه الحزمة؛ على وجه التحديد، مصدر التتبع "OutputBytes" لـ
IPv6PacketProbe. أخيرًا، توفر الوسيطتان الأخيرتان للبيان أسطورة الحبكة
لسلسلة البيانات هذه ("عدد بايتات الحزمة")، وبيان تنسيق gnuplot الاختياري
(GnuplotAggregator::KEY_BELOW) أننا نريد إدراج مفتاح المؤامرة أسفل المؤامرة.
تتضمن الخيارات الأخرى NO_KEY، وKEY_INSIDE، وKEY_ABOVE.

مدعومة أثر الأنواع
يتم دعم القيم المتتبعة التالية باستخدام المجسات حتى كتابة هذه السطور:

┌───────────────┬──────────────┬─── ────────── ──────────────────┐
│ نوع TracedValue │ نوع المسبار │ الملف │
├───────────────┼──────────────┼─── ────────── ──────────────────┤
│double │ DoubleProbe │ احصائيات/نموذج/double-probe.h │
├───────────────┼──────────────┼─── ────────── ──────────────────┤
│uint8_t │ Uinteger8Probe │ 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::الوقت │ TimeProbe │ stats/model/time-probe.h │
└───────────────┴──────────────┴─── ────────── ──────────────────┘

يتم دعم أنواع TraceSource التالية بواسطة Probes حتى كتابة هذه السطور:

┌──────────────────┬─────────────── ──────┬─── ─────────────────────────────────── ────────── ──────────┐
├──────────────────┼─────────────── ──────┼─── ──────────────────────────────── ────────── ──────────┤
├──────────────────┼─────────────── ──────┼─── ──────────────────────────────── ────────── ──────────┤
├──────────────────┼─────────────── ──────┼─── ──────────────────────────────── ────────── ──────────┤
├──────────────────┼─────────────── ──────┼─── ──────────────────────────────── ────────── ──────────┤
├──────────────────┼─────────────── ──────┼─── ──────────────────────────────── ────────── ──────────┤
└──────────────────┴─────────────── ──────┴─── ──────────┴──────────────────────── ────────── ──────────┘

كما هو واضح، يتم دعم عدد قليل فقط من مصادر التتبع، وكلها موجهة نحوها
إخراج حجم الحزمة (بالبايت). ومع ذلك، فإن معظم أنواع البيانات الأساسية
متاحة حيث يمكن دعم TracedValues ​​باستخدام هؤلاء المساعدين.

FileHelper
تعد فئة FileHelper مجرد نسخة مختلفة من مثال GnuplotHelper السابق. ال
يوفر برنامج المثال مخرجات منسقة لنفس البيانات ذات الطابع الزمني، مثل ما يلي:

الوقت (بالثواني) = 9.312e + 00 عدد بايت الحزمة = 596
الوقت (بالثواني) = 9.312e + 00 عدد بايت الحزمة = 564

يتم توفير ملفين، أحدهما للعقدة "0" والآخر للعقدة "1" كما يمكن رؤيته في ملف
أسماء الملفات. دعونا نلقي نظرة على الكود قطعة قطعة:

+ // استخدم FileHelper لكتابة عدد بايت الحزمة بمرور الوقت
+ FileHelper fileHelper؛
+
+ // تكوين الملف المراد كتابته وتنسيق بيانات الإخراج.
+ fileHelper.ConfigureFile ("عدد البايتات السابعة للحزمة"،
+ مجمع الملفات::FORMATTED);

بادئة الملف المساعد للملف هي الوسيطة الأولى، ومحدد التنسيق هو التالي. بعض
تتضمن الخيارات الأخرى للتنسيق SPACE_SEPARATED، وCOMMA_SEPARATED، وTAB_SEPARATED.
يستطيع المستخدمون تغيير التنسيق (إذا تم تحديد FORMATTED) باستخدام سلسلة تنسيق
مثل ما يلي:

+
+ // قم بتعيين التسميات لملف الإخراج المنسق هذا.
+ fileHelper.Set2dFormat ("الوقت (الثواني) = %.3e\tعدد بايت الحزمة = %.0f");

وأخيرًا، يجب ربط مصدر الاهتمام التتبعي. مرة أخرى، نوع التحقيق وTracePath
يتم استخدام المتغيرات في هذا المثال، ومصدر تتبع إخراج المسبار "OutputBytes" هو
معلق:

+
+ // حدد نوع المسبار، وتتبع مسار المصدر (في مساحة اسم التكوين)، و
+ // التحقيق في مصدر تتبع الإخراج ("OutputBytes") للكتابة.
+ fileHelper.WriteProbe (probeType،
+ مسار التتبع،
+ "وحدات بايت الإخراج");
+

تتطابق حقول أحرف البدل في محدد مصدر التتبع هذا مع مصدري تتبع. على عكس
مثال GnuplotHelper، حيث تم تراكب سلسلتين من البيانات على نفس المخطط، هنا، اثنتان
تتم كتابة ملفات منفصلة على القرص.

الملخص
يعد دعم جمع البيانات جديدًا اعتبارًا من ns-3.18، والدعم الأساسي لتوفير السلاسل الزمنية
تمت إضافة الإخراج. يمكن تكرار النمط الأساسي الموضح أعلاه داخل
نطاق دعم التحقيقات الحالية ومصادر التتبع. المزيد من القدرات بما في ذلك
سيتم إضافة معالجة الإحصاءات في الإصدارات المستقبلية.

الخلاصة


العقود الآجلة
تهدف هذه الوثيقة إلى أن تكون وثيقة حية. ونأمل ونتوقع أن تنمو مع مرور الوقت
لتغطية المزيد والمزيد من الصواميل والمسامير NS-3.

إن كتابة الفصول اليدوية والدروس التعليمية ليس شيئًا يثير حماسنا جميعًا، ولكنه كذلك
مهم جدا للمشروع. إذا كنت خبيرا في أحد هذه المجالات، من فضلك
النظر في المساهمة في NS-3 وذلك بتقديم أحد هذه الفصول؛ أو أي فصل آخر لك
قد يعتقد أنه من المهم.

إغلاق
NS-3 هو نظام كبير ومعقد. من المستحيل تغطية كل الأشياء التي لديك
سوف تحتاج إلى معرفته في برنامج تعليمي صغير واحد. يتم تشجيع القراء الذين يرغبون في معرفة المزيد على ذلك
اقرأ الوثائق الإضافية التالية:

· ال NS-3 كتيب

· ال NS-3 وثائق المكتبة النموذجية

· ال NS-3 دوكسيجين (وثائق API)

· ال NS-3 ويكي

-- ال NS-3 فريق التطوير.

استخدم البرنامج التعليمي ns-3 عبر الإنترنت باستخدام خدمات onworks.net


خوادم ومحطات عمل مجانية

قم بتنزيل تطبيقات Windows و Linux

أوامر لينكس

Ad