الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

برمجة Winsock الدرس #5

بدأه the inventor habib في 27 يوليو 2012 · 9 رد · 1,007 مشاهدة · في لغة Assembly لأنظمة 16, 32, 64 بت
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بعض العمليات علي الSocket:

هناك نوعان من العمليات التي يمكن التعامل معها في الSocket عملية الارسال والاستقبال.وسوف أشرح كل واحدة علي حدة.

ارسال البينات الي Remote Socket:

نستعمل الدالة send لكي نرسل البينات في stream socket وأما في النوع datagram socket فالدالة المستخدمة هي sendto وانا لن أشرح النوع datagram socket لقلة استعمالها وكترة استعمال stream socket في HTTP والبروتوكولات التي نستعملها بكترة.

send لديها الشكل التالي:

send PROTO socket:DWORD, buffer:DWORD, len:DWORD, flags:DWORD


البرامترات:

  1. socket:هي مقبس الSocket الدي نتعامل معه أو الدي أنشئناه.
  2. buffer:عنوان البينات التي تريد ارسالها ولا يشترط أ، تنتهي ب '\0' أو NULL-terminated لانك سوف تحدد مقدار البينات التي سترسل.
  3. len:حجم البنات التي تريد ارسالها.
  4. flags:تسعمل لتحديد كيفية تصرف االدالة وعادة تكون قيمة هدا البرامتر 0.

القيمة المرجعة:

ادا فشلت الدالة تكون القيمة المرجعة SOCKET_ERROR وتضع في المسجل eax وادا نجحت تكون القيمة المرجعة عدد البيتات التي أرسلت.

كود توضيحي:

1343384428621.jpg

شرح السطر:

  1. بدابة مقطع البينات.
  2. حجز مكان في الداكرة بحجم 100 بايت.
  3. هناك يتم وضع اكواد أخري متل دالة انشاء السوكت أو أن تقوم بملئ buffer يعني البينات التي تريد أن ترسلها....
  4. بداية مقطع الكود.
  5. -----
  6. استدعاء دالة الارسال.
  7. التحقق من القيمة المرجعة ادا فشلت الدالة ...
  8. نضع هناك ما نريد فعله أتناء فشل الدالة.
  9. ادا ما نجحت الدالة .
  10. نضع ما نريد هناك ادا نجحت الدالة.
  11. نهاية الشرط.

قرائة البينات من الSocket:

هناك دالتين كدلك للستقبال البينات من Socket هناك recv الخاصة بstream socket و recvfrom الخاصة بdatagram socket.

recv تأخد Syntax التالي:

recv PROTO socket:DWORD, buffer:DWORD, len:DWORD, flags:DWORD

البرامترات:

socket:هي مقبس الSocket الدي نتعامل معه أو الدي أنشئناه.

buffer:عنوان المكان في الداكرة الدي تريد وضع البينات الأتية فيه. len:حجم البينات التي تريد استقبالها. flags:تسعمل لتحديد كيفية تصرف االدالة وعادة تكون قيمة هدا البرامتر 0.

القيمة المرجعة:

ادا نجحت الدالة فسترجع عدد البيتات التي أستقبلت وادا فشلت ترجع قيمة SOCKET_ERROR وادا رجعت 0 فهدا يعني أن السوكت قد غلق.

ملاحضة:

هده الدالة تقوم باستقبال عدد البيتات التي وضعت .والمشكل الان هو كيف أعرف حجم البينات التي أرسلت الي؟ الجواب هو استخدام الدالة ioctlsocket التي لها الشكل التالي:

ioctlsocket PROTO socket:DWORD, cmd:DWROD, lpArgument:DWORD


البرامترات:

  1. socket:مقبس السوكت.
  2. cmd:هو الطلب الدي تريد من الدالة تلبيته وهناك تلات أنواع من command وهي FIONBIO, FIONREADو SIOCATMARK وبما أننا نريد حجم البينات التي سوف ترسل الينا وسوف نركز علي FIONREAD. FIONREAD هدين الطلبين يعطون حجم البينات التي سوف تقرأ وحجم البينات سوف توضع في موقع يؤشر اليه lpArgument
  3. lpArgument:مؤشر اضافي مساعد للبرامتر السابق.

القيمة المرجعة:

ادا نجحت القيمة المرجعة تكون في eax هي NULL والعكس وادا فشلت ترجع قيمة من نوع SOCKET_ERROR .

ملاحضة هده الدالة كما أشرنا في الموضوع الأول تقوم بالتحكم في نمط السوكت ادا استعملنا الطلب FIONBIO فسوف تحول بين النمطين blocking أو non-blocking mode مع الطلب FIONREAD فسوف يكون عمل الدالة هو تحديد حجم البينات التي ستقرأ.

كود توضيحي:

1343386309351.jpg

السطر:

  1. بداية مقطع البينات.
  2. الاعلان عن متغير وهو SOCKET.
  3. الأعلان عن متغير لكي يحمل مفبض المساحة التي سنحجزها في الدكرة.
  4. متغير سيحمل عناون أو حجرة في المساحة التي سنحجزها.
  5. متغير سوف يكون بمتابة البرامتر الأخير للدالة ioctlsocket.
  6. متغير سوف يحمل عدد البينات التي قرأت.
  7. ---
  8. بداية مقطع الكود.
  9. -----
  10. استدعاء الدالة ioctlsocket.
  11. التحقق من نجاح عمل الدالة.
  12. حجز مكان في الدكرة بحجم البينات التي ستقرأ.
  13. نقل القيمة المرجعة من الدالة السابقة الي hMemory وهي عبارة عن مقبض للمساحة التي تم حجزها.
  14. استعمال الدالة GlobalLock التي لها بارامتر وحيد وهو مقبض المساحة التي تم حجزها وهده الدالة تعيد عناون أو حجرة في المساحة التي تم حجزها ويمكننا استخدام هدا العنوان لنخزن فيه ما تم قرأته.
  15. نقل القيمة المرجعة من الدالة السابقة الي buffer الدي سيحمل ما تم قرأته.
  16. استدعاء الدالة recv.
  17. نقل عدد البيتات التي قرأت الي actual_data_read.
  18. ----.
  19. ----.
  20. ----.
  21. تحرير الداكرة.
  22. تحرير الداكرة.
  23. نهاية شرط التحقق السابق .

والسلام.

#2

لدي تسائل

عند ارسال 1 ميقا مادا سيحدث و اتصال 128 كيلوا ؟ و كيف يمكن ارسالها ؟

#3

يتم تقسيم كتلة البيانات المطلوب إرسالها إلى Packets.

والمسألة لا تتعلق بعرض الحزمة (bandwidth) التي لديك (128 كيلو)

وإنما تتعلق بقيمة الـ Maximum Transmission Unit (تعرف اختصاراً بـ MTU).

في شبكات Ethernet التي يستخدمها معظمنا، تكون قيمة MTU مساوية لـ 1500 بايت، لكن في اتصالات PPPoE وعندما يكون التغليف من النوع LLC/SNAP-BRIDGING فالقيمة تصبح 1492 بايت. مثال آخر، في الشبكات اللاسلكية التي تعمل بالبروتوكول 802.11 فالقيمة تصبح 7981 بايت.. وهكذا.

في كل Packet يتم احتساب Header-Payload-Trailer

الترويسة لها طول مختلف بحسب البروتوكول الذي ترسل عبره، مثلاً (IPv4 لها طول header مختلف عن IPv6)، إلخ..

بالنسبة للـ Trailer فطولها يحسب بحسب البروتوكول الذي تأتي فيه، مثلاً IP لا يحوي على trailer،

بينما في الاتصالات التي تحوي على error detection and correction قد تستخدم لتخزين معلومات تفيد في كشف الأخطاء.

للعلم فإن بروتوكول IP يقوم بوضع الـ checksum في الـ Header.

بعد حساب طول الـ header والـ trailer، تطرح القيمة من قيمة الـ MTU فيتبقى لديك الطول الذي تستطيع استخدامه لكل data packet، وعليه يتم تقسم الـ Data إلى عدد مختلف من الـ packets.

2

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#4

شيئ رائع جدا اخي ولكن لدي طلب خاص ممكن المراسلة mrsh66@ymail.com

وإن شاء الله دائماً منك التألق ولابداع

وممكن اعلان عن تأليف كتب في البرمجة فبماذا الغرب افضل منا

من فضلك لا تنس ترشيح الإجابات و تقييم المشاركات التي أفادتك لضمان ذهاب النقاط لمستحقيها

تم تعديل هذه المشاركة بواسطة mr omer في 27 يوليو 2012 في 20:38

#5

تم الاجابة والحمد لله لانني وجدت 3 ردود ورد لاستفسار

#6
mr omer كتب:

ولكن لدي طلب خاص ممكن المراسلة mrsh66@ymail.com

آسف أخي الكريم.

بريدي مخصص لدائرة مقرّبة من الأصدقاء والعائلة فقط.

اقتباس
وممكن اعلان عن تأليف كتب في البرمجة فبماذا الغرب افضل منا

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

بالتوفيق.

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#7
اقتباس
Xacker

تسلم حبيبي على الشرح الجميل للفكرة و اول مرة اسمع ب mtu و افهم من ردك انه : يتم تقسيم البيانات الى اجزاء صغيرة packed لبتم ارسالها لكن هدا يجرني الا تسائل

هل تقسيم يتم برمجيا من طرفنا - و يستحسن الا تتجاوز 1024 - ام برتكول الـ tcp يتكفل بدلك عند ارسلنا 1 ميقا دفعة واحدة يعني تمرير buffer بحجم 1 ميقا في متغير الـ len

send PROTO socket:DWORD, buffer:DWORD, len:DWORD, flags:DWORD

كما هو معلوم الـ tcp يضمن وصول البيانات فكيف نعرف ان بيانات وصلت بالكامل في حالتي الـ blocking و no blocking

الحقيقة هته الامور ملخبطة علي شوي و اود فهمها

تسلوم اخواني

تم تعديل هذه المشاركة بواسطة houdini في 28 يوليو 2012 في 15:26

#8

لا تحتاج للقيام بشئ برمجياً، العملية تتم عبر الطبقات الأخيرة من بروتوكول TCP/IP.

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

بالتوفيق.

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#9

اوكي اخي شكرا لك و شكرا لصاحب الموضوع على كشف النقاب على windows socket api :)

موفقين

#10

لا شكر علي الواجب

مواضيع مشابهة