Carambolas هي مكتبة دعم للأغراض العامة المتطورة التي تتكون من مجموعات متعددة .NET Standard 2.0 . بخاصة، إنه يتميز بتنفيذ بروتوكول UDP موثوق به متعدد القنوات مخصص للتقديم لتطبيقات شبكة منتجات المنتجات النطاق الترددي المنخفضة/النطاق الترددي المنخفض مع قيود في الوقت الفعلي الناعم .
الإصدار الأول هو جوهر الحد الأدنى مع وحدة شبكة يعمل بكامل طاقتها. تم تنظيم هذا المستودع حول حل واحد لأنني أخطط للتوسع عن طريق إضافة وحدات جديدة في المستقبل.
لا تزال تغطية الاختبار ضئيلة ، لذا لا ينبغي ضمنيًا لمستوى صواب دون تفتيش وثيق للرمز المصدر. هذا مشروع مستمر في مراحله الأولى.
يمكن أن تكون الثنائيات قريبًا في قسم الأرشيف أو في شكل حزم Nuget.
ويمثل المضيف المحلي مثيل Carambolas.net.host . يجب استخدامه للاتصال بمضيف عن بُعد أو قبول الاتصالات الواردة.
يتم تمثيل كل مضيف عن بُعد بمثال من carambolas.net.peer .
يتم استلام أحداث مثل الاتصال والانفصال والبيانات من خلال كائن المضيف بينما يمكن استخدام كائنات الأقران لإرسال البيانات أو الفصل بشكل نشط.
في هذه المرحلة ، تعتبر عمليات الاتصال وفصلها وترسلها واستلامها غير محبوطة ؛ مفتوحة وإغلاق الحظر (لأسباب واضحة).
لاحظ أنه يمكن استخدام نفس كائن المضيف لطلب الاتصالات بشكل نشط وقبول الاتصالات الواردة كلها مما يجعلها قابلة للاستخدام في طبولوجيا P2P. لا يتم فرض أدوار العميل/الخادم وتظهر ببساطة عن طريق تكوين المضيف. يجوز للمضيف حتى إرسال طلبات الاتصال إلى مضيفات بعيدة متعددة في وقت واحد.
أمثلة :
كائن مضيف تم إنشاء مثيله للاتصال بنظير بعيد. الحلقة الداخلية هي المسؤولة عن ضمان عدم تراكم الأحداث للتكرار التالي.
using ( var host = new Host ( "MyHost" )
{
host . Open ( IPEndPoint . Any , new Host . Settings ( 0 ) ) ;
host . Connect ( new IPEndPoint ( IPAddress . Loopback , 1313 ) , out Peer peer ) ;
.. .
while ( true )
{
while ( host . TryGetEvent ( out Event e ) )
{
if ( e . EventType == EventType . Data )
Console . WriteLine ( $ "DATA: { e . Peer } { e . Data } " ) ;
else if ( e . EventType == EventType . Connection )
Console . WriteLine ( $ "CONNECTED: { e . Peer } " ) ;
else if ( e . EventType == EventType . Disconnection )
{
Console . WriteLine ( $ "DISCONNECTED: { e . Peer } { e . Reason } " ) ;
return ;
}
}
Thread . Sleep ( 33 ) ;
}
}كائن مضيف تم إنشاء مثيله لانتظار ما يصل إلى 10 اتصالات واردة. الحلقة الداخلية هي المسؤولة عن ضمان عدم تراكم الأحداث للتكرار التالي.
using ( var host = new Host ( "MyHost" )
{
host . Open ( new IPEndPoint ( IPAddress . Loopback , 1313 ) , new Host . Settings ( 10 ) ) ;
.. .
while ( true )
{
while ( host . TryGetEvent ( out Event e ) )
{
if ( e . EventType == EventType . Data )
Console . WriteLine ( $ "DATA: { e . Peer } { e . Data } " ) ;
else if ( e . EventType == EventType . Connection )
Console . WriteLine ( $ "CONNECTED: { e . Peer } " ) ;
else if ( e . EventType == EventType . Disconnection )
{
Console . WriteLine ( $ "DISCONNECTED: { e . Peer } { e . Reason } " ) ;
return ;
}
}
Thread . Sleep ( 33 ) ;
}
} يعود تاريخ المشروع إلى عام 2015 عندما جئت إلى كندا لدراسة تصميم وألعاب الفيديو في مدرسة تورنتو السينمائية. كان الدافع الأصلي هو إنشاء مجموعة من فئات الملحقات التي يمكن إعادة استخدامها في مشاريع Unity3D المتعددة. بعد فترة من الوقت ، بدأت في البحث عن حلول الشبكات من أجل لعبة متعددة اللاعبين ، وانتقل التركيز نحو تصميم وحدة شبكة قابلة لإعادة الاستخدام. في البداية ، تعاملت مع المشكلة كمسألة بسيطة تتمثل في دمج UNET أو أي مكتبة أخرى مناسبة لجهة خارجية يمكن أن أجدها في ذلك الوقت. بعد فترة وجيزة ، بدأت في الاصطدام بجميع أنواع المشاكل من الافتراضات المكسورة إلى مقايضات التنفيذ المخفية. لم يكن من غير المألوف العثور على قوائم ميزات مضللة (مضللة تقريبًا) أو عدم توافق التصميم أو التطبيقات العادية المكسورة. على وجه الخصوص ، ما أزعجني أكثر هو أن العديد من جوانب الحلول بدت تعسفية عشوائيًا مع تفسير ضئيل أو معدوم لسبب تفضيل هذا النهج أو فرض حد معين. أود أن أقضي ساعات في فحص مصدر المشروع في تدوين الملاحظات لمعرفة سبب وجود شيء ما هو ما كان عليه فقط أن ندرك لاحقًا أن جزءًا آخر من الكود كان في تناقض مباشر.
كل هذا دفعني إلى مزيد من العمل ، وفي النهاية قررت إنشاء مكتبة شبكة خفيفة الوزن بنفسي مع قائمة ميزات معقولة يمكنني تنفيذها والتحقق منها. لا الاندفاع ، لا مواعيد نهائية. مجرد محاولة حقيقية لتنفيذ أفضل حل تقني يمكنني وضعه.
وفي الوقت نفسه ، تخرجت ، وعدت إلى وظيفة بدوام كامل واضطررت إلى وضع هذا المشروع جانبا. قبل عام ، بعد العثور على بعض الملاحظات القديمة ، قمت بترميم أرشيف النماذج الأولية وقررت تجميع بناء شامل مع جميع المعلومات التي جمعتها حتى لا يتمكن الآخرون فقط من تجربتها ولكنهم أيضًا فهم الطريقة التي تعمل بها ولماذا.
يمكن بناء التجميعات المدارة في أي منصة مع مترجم يدعم C# 7.3 أو أعلى. تتطلب الاختبارات وتطبيقات الملحقات netcore 2.2.
يمكن بناء المكتبات الأصلية باستخدام CMake مع GCC أو Visual Studio.
إصدارات OS المدعومة:
بالنسبة لأي منصة أخرى ، أو في غياب مكتبة أصلية مطلوبة ، يوجد رمز الاحتياط أنه على الرغم من أن بشكل عام قد يكون أقل كفاءة يجب أن يكون يعمل بالكامل وشفافًا.
تم تكوين جميع مشاريع C# والبرامج النصية لتخزين الملفات والثنائيات الوسيطة تحت مجلد بناء موجود في جذر المشروع بحيث يمكن فحص البناء بسهولة والتحقق منها وتنظيفها.
يستخدم الرمز Dllimport لربط المكتبات الأصلية. قد تستخدم Dllimport دائمًا أسماء مكتبة Windows وستضيف تلقائيًا بادئات/لاحقة منصات أخرى على النحو المطلوب. على سبيل المثال ، carambolas.net.native.dll ، اسم المكتبة الأصلية على Windows ، يصبح libcarambolas.net.native.dll.so على linux و libcarambolas.net.native.dll.dynlib على macos. قم بإنشاء البرامج النصية بالفعل إنشاء المكتبات تحت الأسماء المناسبة.
يتم تضمين حل Visual Studio للراحة ، لذلك لا ينبغي أن تكون هناك حاجة إلى خطوات بناء إضافية لنظام التشغيل Windows. تأكد فقط من تحديد النظام الأساسي المقابل لنظام التشغيل المضيف الخاص بك (إما X86 أو X64). هذا مطلوب لإنشاء تطبيقات الاختبار ولاختبارات الوحدة. تم تصميم جميع تجميعات .NET لـ anycpu بغض النظر عن منصة الحلول المحددة ، ولكن يجب أن تعرف Visual Studio ما هي المكتبات الأصلية التي يجب بناءها للاختبار كما هو متوقع أن يتم نشرها جنبًا إلى جنب مع مجموعاتها المرتبطة بها.
استخدم nugetpack.bat لتجميع المكتبة الأصلية والتجميعات المحمولة وإنشاء حزم nuget في إجراء واحد.
استخدم build.bat لبناء جميع المشاريع للإصدار دون استخدام Visual Studio.
لم يتم اختبار Visual Studio لنظام التشغيل Mac ولا يتم دعمه ، لذلك لا تتوقع أن تعمل.
تأكد من وجود CMake (> = 2.8) و GCC لتكون قادرة على تجميع المكتبة الأصلية. مطلوب Dotnet Core SDK 2.1 لتجميع التجميعات وإنشاء حزم nuget.
استخدم nugetpack.sh لتجميع المكتبة الأصلية والتجميعات المحمولة وإنشاء حزم nuget في إجراء واحد.
استخدم build.sh لبناء جميع المشاريع للإصدار دون استخدام Visual Studio.
تأكد من تثبيت Cmake (> = 2.8) ، وتثبيت البناء والبناء و GCC-Multilib لتتمكن من تجميع المكتبة الأصلية لكل من X86 و X64.
على Ubuntu Run: $ sudo apt-get install build-assess arsess
مطلوب Dotnet Core SDK 2.1 لتجميع التجميعات وإنشاء حزم nuget.
على Ubuntu Run:
$ wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ sudo apt-get update;
sudo apt-get install -y apt-transport-https &&
sudo apt-get update &&
sudo apt-get install -y dotnet-sdk-2.1
استخدم nugetpack.sh لتجميع المكتبة الأصلية والتجميعات المحمولة وإنشاء حزم nuget في إجراء واحد.
استخدم build.sh لبناء جميع المشاريع للإصدار دون استخدام Visual Studio.
يتم تنفيذ مجموعة الحد الأدنى من اختبارات الوحدة حول الميزات الرئيسية باستخدام مشاريع Xunit.
Carambolas.net.tests.host هو تطبيق وحدة تحكم بسيط يستخدم للتحقق يدويًا من وظائف الشبكة الأساسية. إنه مفيد بشكل خاص عندما يقف إلى جانب Wireshark و Glumsy
Carambolas.net.tests.integration هي مجموعة من اختبارات التكامل لـ Carambolas.net التي تم تنفيذها أيضًا مع Xunit. يتم تشغيل الاختبارات بالتتابع ، كل منهما يبدأ اثنين من موضوعات منفصلة (خادم وعميل) ، يتواصل عبر واجهة الاسترجاع لفترة محددة من الوقت. يمثل الاسترجاع شبكة مثالية حيث يكون وقت الرحلة المستديرة الحد الأدنى ، ولم تصل الحزم أبدًا عن الترتيب ولا تضيع أبدًا ما لم يكن هناك فائض في التدفق. هذه الخصائص مفيدة للتحقق من مسارات التنفيذ العادية.
Wireshark هي أداة تصحيح لا تقدر بثمن يمكن استخدامها لمراقبة نشاط الشبكة وفحص الحزم. بالإضافة إلى ذلك ، يدعم Wireshark فئة خاصة من المكونات الإضافية تسمى التشريحات التي يمكن استخدامها لتحليل البروتوكولات المخصصة.
يتضمن هذا المشروع مصرفيًا أساسيًا لـ Wireshark لـ Carambolas. من أجل استخدامه ، تأكد من تثبيت Wireshark بالفعل.
Clumsy هو برنامج لالتقاط حزم الشبكة يعمل في وضع المستخدم وقادر على اعتراض الحزم لمحاكاة ظروف الشبكة المتدهورة في الوقت الفعلي.
إضافة سطر مرشح مسبقًا مثل ما يلي في ملف config.txt للتأثير على المضيفين المتصلين بواجهة الاسترجاع على نفس المنفذ المستخدم في اختبارات التكامل (1313):
carambolas: udp and outbound and loopback and (udp.DstPort == 1313 or udp.SrcPort == 1313)
لاحظ أن هناك بعض التحذيرات عند استخدام خرقاء مع واجهة الاسترجاع. من دليل المستخدم الخرقاء:
- لا يمكن القبض على الحزم الواردة الواقعة. عندما تفكر في الأمر ، من الصعب حقًا معرفة أنها حزمة واردة أو خارجية عند إرسال حزم من الكمبيوتر إلى نفسه. في الواقع ، يبدو أن منصة تصفية Windows الأساسية تصنف جميع حزم الاسترجاع على أنها خارجية. الشيء الذي يجب تذكره هو أنه عند معالجة حزم الاسترجاع ، لا يمكنك "الواردة" في المرشح. من المهم أن تعرف أن جهاز الكمبيوتر الخاص بك قد يحتوي على IPs بخلاف 127.0.0.1 ، مثل IP Indranet الذي يخصصه جهاز التوجيه الخاص بك. هذه تعتبر أيضا حزم الاسترجاع.
- يتم التقاط حزم الاسترجاع مرتين. نظرًا لأننا لا نملك حزم الاسترجاع الواردة ، فإن جميع حزم الاسترجاع تعتبر خارجًا. لذلك سيقوم خرقاء معالجتها مرتين: المرة الأولى هي عند الإرسال ، والمرة الثانية عند الاستلام. مثال بسيط هو أنه عندما يكون المرشح ببساطة "خارج" ، وتطبيق تأخر 500 مللي ثانية. عندما تكون ping localhost ، سيكون تأخر 1000 مللي ثانية. يمكنك العمل حوله عن طريق تحديد منفذ الوجهة وأشياء من هذا القبيل. ولكن سيكون من الأسهل أن تضع هذا الأمر في الاعتبار وأن تكون حذراً عند تعيين المعلمات.
- الالتقاط الحزمة الواردة لا يعمل طوال الوقت. كما لوحظ سابقًا ، لا يمكن تعزيز الحزم الواردة. المشكلة هي أنه في المناسبات ، قد يتم تصنيف بعض الحزم على أنها حزم واردة ، حتى لو لم يكن IP الوجهة لجهاز الكمبيوتر الخاص بك. هذا يؤثر فقط على الحزم غير المرتبطة. إذا كنت تعمل فقط على المضيف المحلي ، فسيكون ذلك على ما يرام. الهدف من الإفراج في المستقبل هو تشخيص سبب هذا وتوفير حل.
- لا يمكن تصفية استنادًا إلى نظام عملية التقاط الشبكات على نطاق واسع كميزة. ولكن هذا في الحقيقة لأنه لا توجد طريقة سهلة لتوفير حل قوي.
أنا دائمًا منفتح على المساهمات ، إما في شكل تقارير الأخطاء ، أو إصلاحات الأخطاء (حتى أفضل!) أو تغطية الاختبار المحسنة.
نرحب بطلبات الميزات ولكن قد يتم الاحتفاظ بها في تراكم اعتمادًا على مدى شمولية أو مواجهة أو مرغوبة. إذا كان طلب الميزات معقدًا للغاية ، فقد يعتمد على الرعاية لأن لدي موارد محدودة (الوقت والمال) لتكريسها.
إذا كنت ترغب في دعم هذا المشروع ، فقد أكون مهتمًا بالسماع منك ، لذا تواصل!
باللغة البرتغالية ، كارامبولاس هو الشكل الجمع لكارامبولا (= النجوم). يستخدم المصطلح أيضًا بالعامية في مناطق معينة من البرازيل للتعبير عن دهشة أو نفاد الصبر.
قبل Carambolas ، قمت ببذل ما لا يقل عن نصف دزينة لتنظيم أفكاري في مشروع قابل للاستخدام. مع Carambolas ، قررت إنشاء سلسلة من النماذج الأولية من أجل التعرف على مشكلات التصميم واختبار طرق مختلفة. كان لكل نموذج أولي اسم رمز تم تشكيله بواسطة خطاب ورقم يبدأ من A1. كان رمز المصدر الذي تم استيراده في البداية في هذا المستودع هو التكرار 75 للنموذج الأولي التاسع ، وبالتالي A9.
يتم توفير المكتبات الأصلية في الغالب لأسباب أداء ، وبالتالي فهي اختيارية تمامًا. كان من غير المعقول محاولة توفير تنفيذ أصلي لكل منصة ممكنة (فكر في جميع أجهزة سطح المكتب ، والهاتف المحمول ، ووحدة التحكم ، والمدمجة ...) والاعتماد حصريًا على المكتبات الأصلية ، من شأنه أن يقلل من المنصات المستهدفة فقط إلى حفنة ، وربما سطح المكتب فقط (Windows ، Linux و MacOS). لذلك كقاعدة عامة ، يجب أن يكون هناك دائمًا تطبيق احتياطي في التعليمات البرمجية المدارة لأي وظيفة تنفذها مكتبة أصلية.
نظرًا لأن المكتبات الأصلية اختيارية ، لا يمكن للبرنامج معرفة ما إذا كان من المفترض أن يكون الملف المفقود موجودًا أم لا ، ولهذا السبب لا يوجد خطأ أو تسجيل لمكتبة أصلية مفقودة. بحكم التعريف ، فإن المكتبة الأصلية المفقودة ليست خطأ.
بشكل عام ، لا يمكنك ذلك. ولا ينبغي عليك ، على الأقل ليس من منظور API. لا ينبغي أن يكون من المهم للمستخدم (أو مبرمج التطبيق) ما هي استراتيجية التنفيذ الأساسية التي يتم استخدامها من قبل reparecy ، في هذه الحالة Carambolas. ومع ذلك ، قد تكون هذه المعلومات ذات صلة بالنشر ، لذلك ، في كل مرة يتم فيها إنشاء كائن interop الذي يحتوي أيضًا على عائق تلقائي ، ينتج الرمز معلومات سجل مؤشرة. على سبيل المثال ، ستنتج carambolas.net.socket معلومات سجل مماثلة لـ "استخدام carambolas.net.sockets.native.socket" عندما يتم العثور على مكتبة أصلية لتنفيذ المقبس الأساسي. وبهذه الطريقة إذا كنت تنتشر مع المكتبات الأصلية في الاعتبار ، يمكنك تحديد ما إذا كانت تستخدم بالفعل.
هذا يعني أنك تنشر مكتبة أصلية إما فاسدة أو تم تجميعها لهندسة المعالجة المركزية الخاطئة.
يجب أن تتجه المكتبات الأصلية جنبًا إلى جنب مع تجميعاتها المتماثلة المقابلة وعلى الرغم من أن التجميعات قد يتم تجميعها مرة واحدة لأي بنية وحدة المعالجة المركزية ، لا يمكن للمكتبات الأصلية. يجب أن تتطابق مع بنية وحدة المعالجة المركزية لنظام التشغيل قيد التشغيل ، وإلا فإنهم يعاملون كملفات تالفة و .NET يلقي نظامًا. badimageFormatexception. لاحظ أن هذا ليس هو نفسه محاولة تحميل مكتبة لم يتم العثور عليها وهي بحكم التعريف وليس خطأً.
منتج Delay النطاق الترددي (BDP) هو نتاج سعة نقل رابط الشبكة (في بتات في الثانية) ووقت تأخير الرحلة المستدير (بالثواني). إنه يمثل الحد الأقصى للبيانات التي يمكن للشبكة الاحتفاظ بها قبل وصول أي إقرار.
يمكن استخدام BDP لتصنيف الشبكات وفقًا لما إذا كان أعلى أو أقل من عتبة معينة. وتسمى الشبكات مع BDP كبيرة شبكات الدهون الطويلة (LFNS). قد تكون LFNs شبكات ذات فترة ذهنية كبيرة للغاية (لا يتجاوز عرض النطاق الترددي ، كما هو الحال في روابط الأقمار الصناعية) أو شبكة واسعة (عرض النطاق الترددي العالي) التي تعرض أوقات ذهابًا وإيابًا (كما في روابط Gigabit Ethernet).
تحقق من ويكيبيديا لمزيد من المعلومات حول هذا الموضوع.
يعمل كائن carammbolas.net.socket كواجهة لتنفيذ المقبس الأصلي أو تطبيق احتياطي يعتمد على system.net.sockets.socket. يساعد على فصلها وتقليل تعقيد كائنات المضيف والأقران. ارجع إلى DOC/README-CARAMBOLAS.NET لمزيد من المعلومات.
System.net.ipaddress و system.net.ipendpoint هي كائنات قابلة للتغيير تعزز عدد من التخصيصات غير الضرورية في جميع المنافسات الحالية لإطار .NET Core و .NET. Carambolas.net.ipaddress و carambolas.net.ipendpoint هي أنواع القيمة غير القابلة للتغيير التي تسهم في تقليل ضغط GC. ارجع إلى DOC/README-CARAMBOLAS.NET لمزيد من المعلومات.
يتم دعم AEAD مع Chacha20 و Poly1305 خارج الصندوق. قد يتم تنفيذ الاستراتيجيات المخصصة من خلال تزويد المضيف بتطبيقات واجهات carambolas.net.pectionher و carambolas.net.ipherfactory. المتطلبات الوحيدة هي:
يكون تطبيق المستخدم مجانيًا في ضغط بياناته قبل الإرسال ولكن لا توجد آلية حاليًا لتوفير ضغط/فك ضغط تلقائي لأي من الرسائل الفردية أو الحزم الكاملة.
يتم ترخيص جميع رمز المصدر وأي ثنائيات تم إنتاجها إلى جانب تطبيق المستخدم بموجب ترخيص معهد ماساتشوستس للتكنولوجيا.
استندت Carambolas.CommandLineArguments إلى مقال من Griffonrl مع رمز المصدر المنشور تحت رخصة معهد ماساتشوستس للتكنولوجيا مع أفكار إضافية من مقال آخر من قبل جيك جينييفان توسعت على المصدر الأصلي.
استند Carambolas.Securography.crc32c على CRC32.net بالقوة بموجب ترخيص معهد ماساتشوستس للتكنولوجيا.
carambolas.securical.criptography.nacl استند وتوسيع على NaCl.core بواسطة David de Smet بموجب ترخيص معهد ماساتشوستس للتكنولوجيا.
يتوفر منشور البروتوكول المكتوب في Lua for Wireshark بموجب ترخيص GPLV3. من المفترض أن يتم استخدامه فقط كملف إدخال لـ Wireshark من أجل توسيع قدراته والسماح لها بعرض المزيد من المعلومات حول حزم UDP التي تم تنسيقها وفقًا لبروتوكول شبكة Carambolas. لذلك فهي منفصلة تمامًا ولا تتفاعل أو تعتمد أو تساهم بأي طريقة في أي ملفات أو تجميعات أو مكتبات أصلية.