بسم الله الرحمن الرحيم
في برمجة الشبكات, مهما كانت اللغة التي اكتب بها ومهما كانت الأدوات التي استخدمها . فإن قوة برنامجي تعتمد على التصميم السليم , والتصميم السليم محتاج إتخاذ قرارات مناسبة , قبل الشروع في كتابة اي كود.
قد يختلف موضوع برمجة الشبكات انة مهما تطورت الأدوات واللغات , فإن الهموم تظل نفسها.
وحتى "ادخل في المفيد" سأذكر مسألتين اساسيتين يخوض فيها مبرمج الشبكات المحترف وبشكل دائم وهي محل خلاف أزلي .
ارجو ان تصبروا علي , وسأحاول ان لا اطيل عليكم.
1-مسألة الThreads :
لتوضيح نقطة الخلاف في هذا الموضوع سأتكلم عن تطبيق من تطبيقات الشبكات , الا وهو بناء السيرفر.
معروف عن السيرفر ان عندة القدرة على خدمة اكثر من عميل في نفس الوقت, لتطبيق هذة الفكرة ,هناك اسلوب شائع مستخدم من قبل أغلب المبرمجين قديما ومستخدم حتى الأن , ألا وهو أسلوب thread لكل عميل.
تقوم هذة الthread بخدمة عميل واحد فقط , حيث تستقبل الطلب منة request وتقوم بإرسال الرد لة response ثم تتبدد.
إذا كنت تصمم سيرفر لشبكة صغيرة نسبيا أي لا تتوقع اتصالات كثيرة ,فهذا الإسلوب لا غبار علية. حتى أنة سهل التطبيق (وقد لا تجد كتاب java إلا و يعطي مثال عملي عن هذا اللإسلوب ).
لكن تخيل 1000 عميل في نفس الوقت؟ هذا يعني 1000 thread ...تخيل 5000 عميل؟ هذا يعني 5000 thread ؟؟؟.. وماذا بعد؟...ستنهار JVM في النهاية !
وما الطريقة البديلة ؟؟
بل قل ما الطرق البديلة ! , هناك عشرات الطرق التي يتم تطويرها وابتكارها , وتطبيقها على درجة اعلى من التعقيد من الاولى بكثير لأنة يتطلب خبرة في الmultithreading والstream ,بالإضافة لمباديء علم الشبكات وطبعا لن تجدها "جاهزة في كتاب تعليمي" مثل الاولى . واذا بحثت في الانترنت ستجد الاف الشروحات والمقالات , وستجد ايضا الاف البرامج المفتوحة المصدر ولكل واحدة اسلوب خاص. وإذا كنت تعتقد أن هناك أساس واحد قامت علية كل هذة الأساليب فإعتقادك سليم .لن أسهب في الموضوع وسأتركك لgoogle لتقرأ اكثر.
2- مسألة الMemory:
أبسط مثال لتأثير موضوع الذاكرة في تصميم برامج الشبكات هو التعامل مع DatagramSocket الخاصة ببروتوكول UDP , بإستخدام هذة الأداة فأنت ترسل \تستقبل البيانات بشكل مصفوفة من نوع byte أي buffer .
استخدام DatagramSocket بسيط جدا جدا... جميل!
اسأل نفسك السؤال التالي... عند التنصت على البيانات الواردة, هل يجب أن أستخدم buffer جديد في كل مرة؟ ام استخدم نفس الbuffer ؟؟ اذا كنت تعتقد أن الإجابة هينة.. فاقرأ التالي:
اذا كنت تستخدم buffer جديد في كل مرة , هذا يعني انك تستخدم مساحة جديدة في الذاكرة لكل packet تستلمة؟؟
هذا يعني أن الذاكرة ستظل مشغولة ببيانات لا فائدة منها.. وهذا هدر.
البعض يقول ((أنا ادرى ببرنامجي.. والبيانات التي ارسلها واستقبلها ليست كبيرة وغير مؤثرة وفي النهاية GarabageCollector سيقوم بدورة ويزيحها)).
أولا لا أحد يعرف كمية البيانات التي يستلمها برنامجة , اذا كان هناك برنامج تخريبي اخر على نفس الشبكة ويعلم رقم المنفذ الذي يستخدمة برنامجك , وقام بإغراقك بسيل من البيانات فسيتوقف برنامجك (والجهاز كلة) عن العمل.. فراجع الإجابة مرة أخرى :wink: .
ثانيا الGC ليس بساحر يقوم بالتنظيف وراء "الضعف في التصميم", الGC عبارة عن خدمة Utilitiy تشتغل وتقوم بتنظيف الذاكرة عند الحاجة , وركز عند كلمة "عند الحاجة" يعني عندما يكون JVM بحاجة لمزيد من الذاكرة وهناك نقص في الذاكرة المتوفرة. وليعمل GC بكفائة وبسرعة فهو محتاج "ايضا" لذاكرة يستخدمها. وبما أن الذاكرة قد تكون في الأساس مستهلكة تماما , فإن GC يصبح مجرد عبء اخر على JVM وليس حلا. (لتتصور الموقف تخيل أنك محجوز في غرفة مملوءة حتى السقف بالكراسي المقلوبة , ومع ذلك تحاول ترتيبها !!).
والان لنعد لموضوعنا , قد يفضل البعض إستخدام buffer واحد , جميل جدا.
هذا يعني ان الThread المسؤولة عن التنصت يجب أن تنتظرحتى يتم معالجة البيانات في buffer قبل استبدالها. جميل جدا جدا... والان أسأل نفسك السؤال هذا (كثرت الأسئلة هة؟) كيف سيتم هذ؟؟
البعض قد يقول (( حسنا , الامر بسيط – سأجعل الThread المتنصتة تتزامن مع Thread أخرى تقوم بمعالجة البيانات , وبالتالي لن يتم استبدال البيانات في buffer إلا بعد معالجتها)).
والبعض قد يقول: (( بلا إنتظار بلا وجع قلب , سأجعل الThread المتنصتة تقوم هي نفسها بمعالجة البيانات التي تستلمها ..ولا تقول لي أن معالجة البيانات قد تستغرق وقتا فتفوت علينا اي بيانات واصلة جديدة..لأني أعرف "تماما" ما يقوم بة برنامجي "و الشبكة مالها دعوة هذة المرة!!")).
الطريقتين لا فرق بينهما (مع أن الاولى فيها "شياكة" اكثر ). وهما بالفعل تقيان من الإستهلاك السيء للذاكرة.
"ولكن" هناك مأخذ واحد عليهما (على الأقل عندي) .. تخيل حدوث خطأ -بعد الإستلام - في معالجة البيانات؟؟
نعم , نعم انت ادرى ولن تترك خطأ كهذا يحدث في برنامجك . "خذني على قد عقلي" و تخيل أن المعالجة تسببت في خطأ غير متوقع "مع بيانات معينة مثلا". فما النتيجة؟؟.. في الحالة الأولى ستنتظر الThread المسؤولة عن التنصت الى مالا نهاية. وفي الحالة الثانية ستتبدد!.
"بالعربي" برنامجك سيتوقف عن القدرة على إستلام البيانات من الشبكة , ليس بسبب مشكلة في الشبكة.. ولكن في مشكلة في "برنامجك"!! .. هذة المشكلة قد تبقيك "اشهرا" وانت تظن انها مشكلة في الشبكة او في التنصت . ولا أبالغ في هذا لأن مبرمجي الشبكات – ومنهم اخوكم- يحبوا الإعتقاد ان برامجهم تعمل جيدا ولكن المشكلة هي دائما في "الشبكة" وهي مزدحمة و مخترقة و ضعيفة و ..و..و, وهي في الحقيقة بريئة براءة الذئب من دم ابن يعقوب!.
والأن بعد أن انتهينا من إستعراض المسألتين "صدقوني أختصرت قدر الإمكان".
قم بالبحث في الأنترنت عن شروحات لطرق بديلة لما استعرضناة , فستجد الاف المقالات والشروحات تعالج هذة المواضيع بشكل مختلف ومن وجهات نظر خاصة وفي النهاية رغم أنة يثري معلوماتك فإنة "كلام نظري" , أختصر الموضوع وابحث عن برامج شبكات مفتوحة المصدر حتى تدخل في الجو العملي مباشرة وتعرف الطرق المستخدمة فستجد الاف البرامج و"انصاف البرامج" الفعالة والممتازة , كل واحد يعتمد اسلوب مختلف ولكن للأسف قد لا تستفيد منها كثيرا لأنها مصممة لغرض معين وتؤدي وظيفة معينة وقد لا تتناسب مع متطلبات التصميم التي تريدها وصدقني اذا قمت بتعديل تصميمك او "لويت عنقة" فقط حتى يتناسب مع الطريقة "المبتكرة" التي وجدتها في برنامج مفتوح المصدر فلن تكون النتيجة جيدة دائما.
خلاصة القول نحن-في هذة المرحلة- بحاجة لشيء "أكثر" من الشرح النظري والأمثلة "المدرسية" و اقل من البرامج الجاهزة المقيدة.
ليس في الشبكات وحسب ولكن في أي مجال برمجي أخر , وهل تعلم لماذا؟؟, لأن هذا هو السبيل " للإبتكار" و "الإبداع"
وتطوير برامج ونظم تحمل بصمة المبرمج العربي الخاصة , وتتوقف عن "إعادة اختراع العجلة!" و تبدأ في "البناء" وليس "إعادة البناء" , هذا هو مبدأي الذي انام واصحو علية منذ سنوات.
وهذا نداء اطلقة لجميع مبرمجي العرب , شاركوا خبرتكم مع الجميع دون استثناء , وكفى شرحا في ادوات اللغة فشرحها سنجدة في كتاب بل علمني كيف استفيد منها "صح", ولا تعطيني برنامجا انت صنعتة بل اعطني الفرصة لأصنع واحدا "أفضل منة".
وها أنذا بدأت بنفسي واضع خبرتي المتواضعة في يد الجميع.
في موضوعي السابق تكلمت عن حزمة برمجية , هذة الحزمة لا تقدم ادوات برمجية "لا مثيل لها", بالعكس فإن اغلب الادوات الأساسية التي يحتاجها ولا يحتاجها المبرمج موجودة أصلا في java . هذة الحزمة تقدم "طرق إستخدام عملية" وليست "مدرسية" لمجموعة الأدوات الأساسية الخاصة بالشبكات في java ستجد فيها ردا على التساؤلات التي وضعتها في الأعلى. قم بتحميلها من رابط المدونة في الأسفل.
وأشكر القاريء الصبور, فعندما ابدأ الكتابة لا أتوقف!
والله من وراء القصد.



