أساسيات الشبكات
أساسيات الشبكات
كل واجهة برمجية لشبكات Java — من Socket الخام إلى HttpClient الحديث — تقوم على نفس المفاهيم الأساسية: حزمة بروتوكولات TCP/IP، والمنافذ، ونموذج العميل/الخادم. قبل أن تكتب سطرًا واحدًا من كود الشبكات عليك أن تفهم ما يحدث في كل طبقة، لأن هذه النماذج الذهنية هي التي تحدد كيفية تصميم الاتصالات، والتعامل مع الأخطاء، وضبط الأداء في أنظمة الإنتاج.
حزمة بروتوكولات TCP/IP
TCP/IP ليس بروتوكولًا واحدًا؛ بل هو مجموعة مكوّنة من أربع طبقات. من الأدنى إلى الأعلى:
- طبقة الوصول إلى الشبكة (الوصل) — الإرسال المادي: إطارات Ethernet، وحزم Wi-Fi. لا تتعامل Java مع هذه الطبقة مباشرة.
- طبقة الإنترنت (IP) — تُوجّه الحزم عبر الشبكات باستخدام عناوين IP. تتنقّل كل حزمة بشكل مستقل وقد تصل خارج الترتيب أو لا تصل أصلًا. البروتوكول IP يعمل على أساس بذل أفضل جهد.
- طبقة النقل — تُوصّل البيانات إلى العملية الصحيحة. يعيش هنا بروتوكولان: TCP وUDP.
- طبقة التطبيق — البروتوكولات التي ينفّذها تطبيقك فوق طبقة النقل: HTTP/2، وTLS، وWebSocket، وSMTP، وغيرها.
TCP: موثوق ومُرتَّب وقائم على الاتصال
يضيف بروتوكول TCP (بروتوكول التحكم في النقل) ثلاث ضمانات فوق IP الخام:
- التسليم الموثوق — تُعاد إرسال الحزم المفقودة تلقائيًا.
- التسليم المُرتَّب — تصل البايتات بالترتيب الذي أُرسلت به تمامًا.
- التحكم في التدفق والازدحام — يتم تقييد سرعة المُرسِل لتتناسب مع ما يستطيع المستقبل والشبكة استيعابه.
تأتي هذه الضمانات من المصافحة الثلاثية التي تُنشئ الاتصال قبل أن تتدفق أي بيانات للتطبيق:
كل Socket تُنشئه في Java يُطلق هذه المصافحة. وكل استدعاء لـ socket.close() يُطلق الإغلاق الرباعي. هذه الرحلات ذهابًا وإيابًا لها تكلفة زمنية — ولهذا أدخل HTTP/1.1 مفهوم keep-alive وأدخل HTTP/2 التعدد (multiplexing): لإعادة استخدام الاتصالات بدلًا من إعادة بنائها لكل طلب.
المنافذ وتعيينات المنافذ المعروفة
تُقسَّم نطاقات أرقام المنافذ ذات 16 بت (0–65535) بحسب الاتفاقية:
- 0–1023: المنافذ المعروفة — مُعيَّنة من قِبَل IANA. HTTP = 80، HTTPS = 443، SSH = 22، SMTP = 25. يتطلّب الربط بهذه المنافذ صلاحيات المسؤول (root) في معظم الأنظمة.
- 1024–49151: المنافذ المُسجَّلة — تستخدمها بروتوكولات التطبيقات المعروفة دون الحاجة إلى صلاحيات مرتفعة. MySQL = 3306، PostgreSQL = 5432، Redis = 6379.
- 49152–65535: المنافذ الديناميكية / المؤقتة — يُعيّنها نظام التشغيل تلقائيًا لـجانب العميل من الاتصال. عندما يتصل عميل Java بخادم، يختار نظام التشغيل منفذًا مؤقتًا كمنفذ مصدر حتى يتمكّن الخادم من إرسال الردود إلى ذلك المقبس تحديدًا.
نموذج العميل/الخادم
يتبع كل شبكات Java المعتمدة على TCP نفس التقسيم البنيوي:
- الخادم — يرتبط بمنفذ معيّن على واجهة محدّدة، ويدخل حالة الاستماع، ويقبل طلبات الاتصال الواردة. إنه سلبي.
- العميل — يعرف عنوان IP الخادم ومنفذه، ويبادر بالاتصال بشكل نشط، ويتواصل بمجرد اكتمال المصافحة.
في Java، يمثّل ServerSocket نقطة الاستماع؛ وكل استدعاء لـ serverSocket.accept() يحجب حتى يتصل عميل ثم يُعيد Socket عاديًا يمثّل ذلك الاتصال المحدد. يُسلّم الخادم عادةً هذا المقبس إلى خيط (thread) — أو خيط افتراضي في Java 21+— حتى يتمكّن من قبول العميل التالي فورًا.
عناوين IP: IPv4 وIPv6
تجرّد فئة InetAddress في Java كلا عائلتَي العناوين:
InetAddress.getByName() بحث DNS على الخيط المُستدعي. في الخوادم عالية الأداء، يُوقف هذا الخيوط. يتعامل HttpClient الحديث مع هذا داخليًا بشكل غير متزامن؛ مع المقابس الخام يجب عليك نقل بحوث DNS إلى خيوط منفصلة أو استخدام مكتبة DNS غير متزامنة.
المقابس موارد إدخال/إخراج — أغلقها دائمًا
كل من Socket وServerSocket ينفّذ AutoCloseable. استخدم دائمًا try-with-resources. المقبس غير المغلق يحتجز واصفًا لملف نظام التشغيل وفتحة اتصال TCP؛ تسريب المقابس تحت الضغط سيُنهك كليهما.
TCP مقابل UDP: متى تستحق تكلفة الموثوقية؟
ضمانات موثوقية TCP ليست مجانية: تُضيف إعادة الإرسال زمن استجابة، وحجب رأس الصف (head-of-line blocking) يعني أن حزمة مفقودة تُوقف جميع البيانات اللاحقة على ذلك الاتصال. يُقايض UDP الموثوقية بالسرعة:
- لا إعداد للاتصال — أرسل أول حزمة فورًا.
- لا إعادة إرسال — البيانات المفقودة تضيع نهائيًا.
- لا ترتيب — قد تصل الحزم بأي تسلسل.
استخدم UDP عندما تتفوّق التوقيت على الصحة: بث الفيديو/الصوت المباشر، وتحديثات حالة الألعاب الإلكترونية، واستعلامات DNS، وبروتوكول QUIC (الناقل تحت HTTP/3). لواجهات REST البرمجية، واتصالات قواعد البيانات، ونقل الملفات، ومعظم أعباء عمل المؤسسات، يظل TCP الخيار الافتراضي الصحيح.
الخلاصة
TCP/IP هو مجموعة طبقات حيث يُوجّه IP الحزم ويجعل TCP التسليم موثوقًا ومُرتَّبًا على حساب زمن استجابة المصافحة. تربط المنافذ نقطة نهاية النقل بعملية محدّدة. يُقسّم نموذج العميل/الخادم الشبكات إلى مُتصل نشط ومُستمع سلبي — مُعكوسان بالضبط بواسطة Socket وServerSocket في Java. هذه ليست مجرد مفاهيم نظرية: كل مهلة تضبطها، وكل حوض اتصالات تُحجّمه، وكل سياسة إعادة محاولة تُصمّمها، هي نتيجة مباشرة لفهم كيفية عمل TCP على هذا المستوى.