الدرس 21: مقابس TCP — الخادم والعميل
بروتوكول TCP (Transmission Control Protocol) هو أساس كل اتصال شبكي موثوق. عندما تفتح متصفحًا، أو تشغّل عملية Git fetch، أو تربط عمليتي NCCL للتدريب الموزّع — ففي معظم الحالات يعمل TCP خلف الكواليس. في هذا الدرس سنكتب خادم TCP وعميل TCP بلغة C++، مستخدمين استدعاءات النظام الأساسية: socket() وbind() و
تخيّل خادم TCP كأنه مطعم. أولًا تختار رقم طاولة (bind إلى منفذ)، ثم تفتح الباب وتعلن 'نحن مفتوحون' (listen)، ثم تجلس وتنتظر دخول زبون (accept). يصل الزبون (connect)، ويجلس، ويطلب (send)، ويستعيد طلبه مُعادًا إليه (recv). يضمن TCP وصول كل طبق بالترتيب الصحيح دون فقدان أي شيء — تمامًا كنادلٍ يتأكد من وصول كل صحن قبل تقديم التالي.
- مقبس (socket)
- نقطة نهاية للاتصال الشبكي. تُمثَّل في الكود كـ file descriptor (عدد صحيح) يمكنك الكتابة إليه والقراءة منه تمامًا كأنه ملف.
- ربط (bind)
- تخصيص عنوان IP ومنفذ لمقبس. يخبر استدعاء النظام bind() النواة: 'هذا المقبس سيستقبل الاتصالات الواصلة إلى المنفذ X'.
- استماع (listen)
- تحويل المقبس إلى الوضع السلبي بحيث يصبح جاهزًا لقبول الاتصالات الواردة. يحدد المعامل backlog عدد الاتصالات المعلّقة التي يمكن للنواة الاحتفاظ بها في طابورها.
- قبول اتصال (accept)
- سحب الاتصال التالي من طابور الانتظار. يعيد file descriptor جديدًا مخصصًا لذلك العميل وحده. يظل المقبس الأصلي مستمعًا لمزيد من العملاء.
- SO_REUSEADDR
- خيار مقبس يتيح لك إعادة ربط المنفذ فور إغلاق الخادم، دون انتظار انتهاء حالة TIME_WAIT. ضروري أثناء التطوير لتجنّب 'Address already in use' في كل إعادة تشغيل.