فهم نموذج OSI حقًا — تشريح طلب HTTP واحد إلى طبقاته السبع

· · نموذج OSI, TCP/IP, الشبكات, Wireshark, Ethernet, TCP, HTTP, C#, .NET, Socket, الاستشارات التقنية

نموذج OSI المرجعي هو أول ما يظهر دائمًا في أي كتاب تمهيدي عن الشبكات، ومع ذلك كثيرًا ما نسمع عبارة: «أستطيع تعداد أسماء الطبقات السبع، لكن بصراحة لا أملك تصورًا حقيقيًا لها». فرغم حفظ الطبقة الفيزيائية وطبقة ارتباط البيانات وطبقة الشبكة وما إلى ذلك، يبقى كثيرون غير قادرين على ربط ذلك المخطط المكوّن من سبع طبقات بكود C# الذي يكتبونه، أو بأعطال الاتصال التي تحدث أمامهم مباشرة.

لقد نشرنا في هذه المدونة من قبل مقالات تتناول سلوك L4 (طبقة النقل)، مثل الفهم الخاطئ القائل بإمكانية استقبال البيانات (Receive) بنفس الوحدات التي أُرسلت بها عبر Send على TCP وسبب توقف اتصال الكاميرا الصناعية بسبب إعادة إرسال TCP وطريقة تحديده، لكن لم يكن هناك مقال يجمع فكرة «الطبقة» نفسها التي تشكل الأساس لكل ذلك.

نهج هذا المقال بسيط. سنُنشئ فعليًا إطار Ethernet واحدًا يحمل طلب HTTP GET واحدًا، ثم نُشرّحه بدءًا من الخارج. فالطبقات السبع ليست مجرد كلام في مخطط تصوري، بل توجد فعليًا متداخلة داخل 171 بايتًا تتدفق عبر الشبكة. وبمجرد رؤية ذلك بأم عينك عبر تفريغ سداسي عشري (hex dump) وWireshark، يتوقف نموذج OSI المرجعي عن كونه موضوعًا للحفظ.

الكود الوارد في هذا المقال منشور على GitHub كمجموعة عينات كاملة قابلة للبناء والتشغيل (مكتبة لتجميع الإطارات وتشريحها، وتصدير ملف pcap يمكن فتحه في Wireshark، واختبارات وحدة (unit tests)).

osi-model-packet-anatomy - komurasoft-blog-samples (GitHub)

1. الخلاصة أولًا

  • نموذج OSI المرجعي هو «مفردات» وليس «تطبيقًا فعليًا». ما يعمل فعليًا على الإنترنت الحقيقي هو مجموعة بروتوكولات TCP/IP (أربع طبقات فعليًا)، أما بروتوكولات OSI ذات الطبقات السبع نفسها فقد خسرت سباق الانتشار ولم تُستخدم فعليًا قط. ما بقي هو النموذج كلغة مشتركة، مثل عبارتي «لنعزل المشكلة عند L2» أو «هذه مشكلة L7».12
  • الطبقات السبع متداخلة فعليًا كسلسلة من البايتات. في إطار يحمل طلب HTTP GET، تكون أول 14 بايتًا هي ترويسة Ethernet (L2)، والعشرون بايتًا التالية هي ترويسة IPv4 (L3)، والعشرون بايتًا التالية هي ترويسة TCP (L4)، والباقي هو نص HTTP (L7). ويمكن التحقق مباشرةً من كون ترويسة كل طبقة تبدأ فور انتهاء الطبقة السابقة، وذلك عبر تفريغ سداسي عشري وWireshark في متن هذا المقال.
  • الشيء الوحيد الذي تكتبه شفرة C# الخاصة بك مباشرةً هو سلسلة بايتات L7. فما تُمرره إلى Socket.Send هو بيانات التطبيق فقط، أما ترويستا TCP وIP فيضيفهما مكدس بروتوكولات نظام التشغيل، وترويسة Ethernet والإشارة الكهربائية تُضيفهما بطاقة الشبكة (NIC). ولهذا فإن اختيار استخدام HttpClient أو SslStream أو Socket هو في جوهره اختيار «إلى أي طبقة فما دون تُفوّض المهمة إلى نظام التشغيل».3
  • الطبقتان L5 (طبقة الجلسة) وL6 (طبقة العرض) لا توجدان كطبقتين مستقلتين في المكدس الحقيقي. يتولى TLS وترميز الأحرف جزءًا من هذا الدور، لكن في نموذج TCP/IP تُجمع كل هذه الأدوار ضمن طبقة التطبيق. وإذا كنت لا تفهم «ما المقصود بـL6»، فالمشكلة ليست فيك، بل لأن هذا بالضبط هو الموضع الذي ينحرف فيه النموذج عن الواقع.2
  • الموضع الذي يُثبت فيه نموذج OSI فائدته الحقيقية في العمل هو استكشاف الأخطاء والتحاور بين الفرق. فتضييق النطاق باستخدام مفردات الطبقات - مثل «يمر ping لكن يفشل HTTP، إذن L3 حي فلنشك في L4 وما فوقها» - يصبح لغة مشتركة يفهمها مطورو الشبكات والبنية التحتية والتطبيقات.

2. لماذا ينتهي نموذج OSI المرجعي إلى مجرد حفظ

تبدأ كثير من الشروحات بجدول مثل هذا.

الطبقة الاسم الوصف
L7 طبقة التطبيق توفر خدمات الاتصال للتطبيقات
L6 طبقة العرض تحوّل صيغة تمثيل البيانات
L5 طبقة الجلسة تدير بدء الاتصال وإنهاءه
L4 طبقة النقل توفر نقل بيانات موثوقًا
L3 طبقة الشبكة تتولى اختيار المسار والعنونة
L2 طبقة ارتباط البيانات تنقل البيانات بين العقد المتجاورة
L1 الطبقة الفيزيائية تحوّل البتّات إلى إشارات كهربائية

هذا الجدول صحيح، لكن كل سطر فيه مكتوب بعبارات مجردة، لذا فإن قراءته لا تُكوّن صورة ذهنية واضحة. فحين تُقال لك عبارة «تحوّل صيغة تمثيل البيانات»، لن يستطيع أحد أن يحدد أي سطر من كوده الخاص تشير إليه هذه العبارة.

هناك حقيقة تاريخية أخرى ينبغي ذكرها بصراحة. نموذج OSI المرجعي هو معيار وضعته ISO (المنظمة الدولية للتوحيد القياسي) وITU-T (ISO/IEC 7498-1، ITU-T X.200)، وكان في الأصل تصورًا طموحًا يقترن فيه بكل طبقة من الطبقات السبع مجموعة بروتوكولات OSI الخاصة بها.1 لكن في سباق الانتشار خلال تسعينيات القرن الماضي، أصبح TCP/IP - الذي كانت له تطبيقات عاملة بالفعل - المعيار الفعلي، وانتهى الأمر ببروتوكولات OSI نفسها إلى أنها بالكاد استُخدمت. ويشرح RFC 1122، الذي أرسى أسس الإنترنت، العالم من خلال أربع طبقات فعليًا هي: طبقة الارتباط، وطبقة الإنترنت (IP)، وطبقة النقل، وطبقة التطبيق، دون وجود طبقتين مستقلتين تقابلان L5 وL6.2

بعبارة أخرى، فإن سبب دراستنا لنموذج OSI المرجعي اليوم ليس «لأنه هكذا يُنفَّذ فعليًا»، بل للحصول على أداة «التفكير عبر الطبقات» ومفردات مشتركة لاستكشاف الأخطاء وإصلاحها. وبتبني هذا المنطلق، لن تحتاج بعد الآن للقلق من «عدم العثور على وجود فعلي لـL5 وL6»، وتتضح الرؤية دفعة واحدة.

3. الموضوع الرئيسي: تشريح طلب HTTP واحد

لننهِ المقدمة هنا ولننظر إلى الشيء الحقيقي. تفريغ البايتات السداسي عشري التالي هو إطار Ethernet (بإجمالي 171 بايتًا) يحمل طلب HTTP واحدًا هو GET /index.html HTTP/1.1. وقد جمّعه الكود العيني المذكور في مقدمة المقال، وبما أن كلًا من مجموع الاختبار (checksum) لترويسة IPv4 ومجموع اختبار TCP محسوبان بشكل صحيح، فإن Wireshark يعرضه كحزمة سليمة تمامًا عند تحميله.

0000  02 00 00 00 00 01 02 00  00 00 00 02 08 00 45 00  ..............E.
0010  00 9d 12 34 40 00 40 06  3b 99 c0 00 02 0a c6 33  ...4@.@.;......3
0020  64 50 cb 84 00 50 00 00  03 e8 00 00 07 d0 50 18  dP...P........P.
0030  ff ff a3 05 00 00 47 45  54 20 2f 69 6e 64 65 78  ......GET /index
0040  2e 68 74 6d 6c 20 48 54  54 50 2f 31 2e 31 0d 0a  .html HTTP/1.1..
0050  48 6f 73 74 3a 20 65 78  61 6d 70 6c 65 2e 63 6f  Host: example.co
0060  6d 0d 0a 55 73 65 72 2d  41 67 65 6e 74 3a 20 4b  m..User-Agent: K
0070  6f 6d 75 72 61 53 6f 66  74 44 65 6d 6f 2f 31 2e  omuraSoftDemo/1.
0080  30 0d 0a 41 63 63 65 70  74 3a 20 74 65 78 74 2f  0..Accept: text/
0090  68 74 6d 6c 0d 0a 43 6f  6e 6e 65 63 74 69 6f 6e  html..Connection
00a0  3a 20 63 6c 6f 73 65 0d  0a 0d 0a                 : close....

بالنظر إلى عرض ASCII في العمود الأيمن، يمكن ملاحظة أن نصًا يمكن للبشر قراءته يبدأ اعتبارًا من منتصف الطريق (الإزاحة 0x36)، وهو GET /index.html HTTP/1.1. فما هي إذن البايتات الـ54 التي تسبقه؟ عند تمريرها إلى مُشرِّح العينة (dissector)، يُصدر التقرير التالي.

[ L2 Ethernet II | offset   0 |  14 bytes | dst=02:00:00:00:00:01 src=02:00:00:00:00:02 type=0x0800 (IPv4)
  [ L3 IPv4        | offset  14 |  20 bytes | 192.0.2.10 -> 198.51.100.80 TTL=64 proto=6 (TCP) checksum=OK
    [ L4 TCP         | offset  34 |  20 bytes | 52100 -> 80 [Psh, Ack] seq=1000 win=65535
      [ L7 HTTP        | offset  54 | 117 bytes | GET /index.html HTTP/1.1

هذا هو المخطط الذي أريدك أكثر من أي شيء آخر أن تراه في هذا المقال. وله ثلاث نقاط أساسية.

  1. تبدأ كل طبقة «فور انتهاء الطبقة السابقة» مباشرة. ترويسة Ethernet من البايت 0 إلى 13، وترويسة IPv4 من البايت 14 إلى 33، وترويسة TCP من البايت 34 إلى 53، ويبدأ HTTP من البايت 54. فالطبقة ليست تصنيفًا مفاهيميًا، بل يمكن الإشارة إليها كـنطاق بايتات محسوب من بداية الإطار.
  2. الطبقة الداخلية ليست سوى «حمولة (payload)» بالنسبة للطبقة الخارجية. فمن منظور Ethernet، كل ما بعد IPv4 مجرد حمولة، ولا يهمه إن كان محتواها TCP أم لا. ومن منظور IP، ما بعد TCP هو الحمولة، ومن منظور TCP، HTTP هو الحمولة. تقرأ كل طبقة ترويستها الخاصة فقط، ثم تمرر الحمولة إلى الأعلى دون المساس بها. وهذه البنية القائمة على «عدم الاكتراث» هي بالضبط ما يُسمى التغليف (encapsulation).
  3. لا تظهر L1 (الطبقة الفيزيائية) ولا L5 وL6 في هذا المخطط. فمهمة L1 هي تحويل سلسلة البايتات هذه إلى إشارة كهربائية أو ضوء أو موجات لاسلكية، لذا لا تظهر في التفريغ إطلاقًا، أما L5 وL6 فكما ذكرنا في الفصل السابق، لا وجود مستقل لهما في HTTP/1.1 كنص صريح. «من بين الطبقات السبع، أربع فقط تظهر في التفريغ» - هذه هي الحقيقة الفعلية.

أكرر مرة أخرى: ليس الأمر خاصًا بـHTTP. سواء كان اتصال قاعدة بيانات، أو gRPC، أو GigE Vision لكاميرا صناعية، فطالما كان الاتصال هو TCP/IP فوق Ethernet، فإن كل حزمة تحمل هذا التركيب المتداخل نفسه تمامًا. والشيء الوحيد الذي يتغير هو محتوى حمولة L7.

4. L2، طبقة ارتباط البيانات — التوصيل حتى «العقدة المجاورة»

لنستعرض نتائج التشريح بدءًا من الخارج. أول 14 بايتًا هي ترويسة Ethernet II.

02 00 00 00 00 01   عنوان MAC الوجهة (6 بايتات)
02 00 00 00 00 02   عنوان MAC المصدر (6 بايتات)
08 00               EtherType = 0x0800 (الحمولة هي IPv4)

مهمة L2 هي «التوصيل حتى العقدة المجاورة ضمن نفس قطعة الشبكة (network segment)». وتُستخدم عناوين MAC لتحديد الوجهة. عنوان MAC هو معرّف مخصص لبطاقة الشبكة (NIC)، ومن حيث المبدأ لا يصل إلى الطرف الآخر عبر جهاز توجيه (router). فالإطار المُرسَل من جهاز كمبيوتر في المكتب إلى خادم ويب يكون عنوان MAC الوجهة الخاص به ليس خادم الويب، بل عنوان MAC الخاص بالبوابة الافتراضية (جهاز التوجيه).

وهنا يتساءل كثيرون، ولو لمرة واحدة، عن السبب في «وجود عنوان IP بالفعل، فلماذا يلزم أيضًا عنوان MAC؟». والجواب يكمن في توزيع المسؤوليات بين الطبقات. فعنوان IP هو العنوان الذي يشير إلى «الوجهة النهائية»، بينما عنوان MAC هو العلامة التي تشير إلى «من سينقل القطعة التالية من المسار». ولو شبّهنا الأمر بخدمات التوصيل السريع، فعنوان IP هو عنوان التسليم المكتوب على بوليصة الشحن، وعنوان MAC هو اسم «مركز الترحيل التالي». بوليصة الشحن (L3) لا تتغير حتى النهاية، لكن العلامة (L2) تُستبدل في كل قطعة من المسار. وARP هو ما يبحث عن عنوان MAC لعقدة مجاورة انطلاقًا من عنوان IP، ويمكن الاطلاع على جدول التطابق الذي يتذكره الكمبيوتر عبر أمر arp -a.

أما من ناحية الأجهزة، فالجهاز الذي يُحيل البيانات بالاعتماد على L2 هو المِبدّل (switch، أو ما يُعرف بمجمّع التبديل). يختار المِبدّل المنفذ بالاعتماد فقط على عنوان MAC الوجهة، ولا ينظر إلى عنوان IP الموجود في الحمولة.

5. L3، طبقة الشبكة — التوصيل إلى أقاصي العالم

العشرون بايتًا التالية هي ترويسة IPv4. وفيما يلي أهم حقولها.

45          الإصدار = 4، طول الترويسة = 5 كلمات (20 بايتًا)
00 9d       الطول الكلي 157 بايتًا (ترويسة IP + TCP + HTTP، لا يشمل الـ14 بايتًا الخاصة بـEthernet)
40 06       TTL = 64، البروتوكول = 6 (الحمولة هي TCP)
3b 99       مجموع اختبار الترويسة (checksum)
c0 00 02 0a عنوان IP المصدر   192.0.2.10
c6 33 64 50 عنوان IP الوجهة     198.51.100.80

مهمة L3 هي «التوصيل إلى المضيف (host) الوجهة النهائية، مهما كان عدد أجهزة التوجيه التي يجب عبورها». فبينما لا تنقل L2 سوى قطعة واحدة من المسار (قفزة واحدة، hop)، يبقى عنوان IP الوجهة في L3 دون تغيير من بداية الاتصال حتى نهايته. وينظر جهاز التوجيه إلى عنوان IP الوجهة في الحزمة المستلمة، ويقرر «إلى أي جهاز توجيه يُسلّمها بعد ذلك»، ثم يعيد إرسالها بعد استبدال ترويسة L2.

حقل TTL (Time To Live) هو الحقل الذي يجعل حركة «عبور أجهزة التوجيه» هذه مرئية أمامنا. فهو يتناقص بمقدار واحد في كل مرة يعبر فيها جهاز توجيه، وعندما يصل إلى الصفر تُهمَل الحزمة ويُعاد خطأ إلى المرسل. ويعمل أمر tracert (أمر استكشاف المسار في Windows) عبر إرسال حزم بقيم TTL تزداد عمدًا 1 ثم 2 ثم 3 وهكذا، ليكشف أجهزة التوجيه الموجودة على المسار واحدًا تلو الآخر. بعبارة أخرى، كل سطر يظهر في مخرجات tracert هو التجسيد الفعلي لـ«قفزة L3».

6. L4، طبقة النقل — تحديد العملية (process) التي تستلم البيانات

العشرون بايتًا التالية هي ترويسة TCP.

cb 84       منفذ المصدر 52100
00 50       منفذ الوجهة 80
00 00 03 e8 رقم التسلسل (sequence number)
00 00 07 d0 رقم الإقرار (acknowledgment number)
50 18       طول الترويسة = 5 كلمات، الأعلام (flags) [PSH, ACK]
ff ff       حجم النافذة (window size)
a3 05       مجموع الاختبار (checksum)

بحلول L3، تكون الحزمة قد وصلت إلى «المضيف (الجهاز)» الوجهة. لكن على ذلك الجهاز، قد يتواصل خادم الويب وقاعدة البيانات والعديد من العمليات (processes) الأخرى في الوقت نفسه. وإحدى مهام L4 هي استخدام رقم المنفذ (port) لتحديد «إلى أي عملية (وأي مقبس socket خاص بها) تُسلَّم البيانات». ومنفذ الوجهة 80 هو، بحكم العرف، «الرقم الذي يستمع عليه خادم HTTP»، وينظر نظام التشغيل إلى هذا الرقم ليضع البيانات في مخزن الاستقبال (buffer) الخاص بالعملية المعنية.

والمهمة الكبرى الأخرى لـTCP هي توفير «دفق بايتات موثوق (reliable byte stream)» عبر أرقام التسلسل والإقرارات وإعادة الإرسال والتحكم في التدفق (flow control).4 وهذا السلوك، وكيفية التعامل معه، عميق بما يكفي ليكون كل جانب منه موضوع مقال قائم بذاته، لذا أحيلك إلى مقال حدود الرسائل في TCP ومقال إعادة إرسال TCP. ما أريدك أن تستوعبه هنا هو هذا الشعور: «فوق L4، لم يعد الشكل شكل شبكة على الإطلاق، بل يبدو أنبوبًا (pipe) يصل عملية بعملية أخرى مباشرة».

هناك حقيقة طريفة توضّح الفجوة بين مثالية النموذج والواقع. فمجموع اختبار (checksum) TCP لا يُعرَّف بحسابه على قطعة TCP (segment) وحدها، بل بإضافة «ترويسة زائفة (pseudo header)» تحتوي على معلومات L3 (عنوانا IP المصدر والوجهة) في مقدمتها ثم الحساب على الجميع.4 فلو كانت الطبقات مستقلة استقلالًا تامًا، لما كان من المفترض أن تختلط عناوين L3 بحساب L4. وهذا مثال جيد على أن نموذج OSI المرجعي ليس سوى خريطة للتنظيم الذهني، بينما تتجاوز البروتوكولات الفعلية حدود الطبقات كلما اقتضت الحاجة ذلك.

7. L5 وL6 — الموضع الذي ينحرف فيه النموذج عن الواقع

والآن، لاحظ أن مخطط التشريح لم يتضمن L5 (طبقة الجلسة) ولا L6 (طبقة العرض). وهذا هو السبب الأكبر وراء الشعور بأن «نموذج OSI غير مفهوم»، لذا سأكتبه بوضوح.

لا توجد L5 وL6 كطبقتين مستقلتين في مكدس TCP/IP الحقيقي. ففي نموذج الإنترنت الذي يحدده RFC 1122، كل ما فوق TCP هو «طبقة التطبيق».2 والأدوار التي تصورها نموذج OSI ممتصة فعليًا ومبعثرة على النحو التالي.

ما تصوره OSI مثال على الموضع الذي امتُص فيه فعليًا
L5: إنشاء الحوار (الجلسة) وإدارته مصافحة جلسة TLS (handshake)، وملفات تعريف الارتباط (cookies) والرموز المميزة (tokens) في HTTP، وإدارة تسجيل الدخول الخاصة بالتطبيق نفسه
L6: تحويل تمثيل البيانات وتشفيرها تشفير TLS، وترميز الأحرف (UTF-8)، وصيغ التسلسل (serialization) مثل JSON

فمثلًا في حالة HTTPS، يُقحَم TLS فوق TCP (L4)، ويتدفق HTTP داخله. وسؤال «أي طبقة ينتمي إليها TLS؟» هو من نوع الأسئلة التي يودّ المرء تحويلها إلى سؤال امتحاني، لكن لا قيمة عملية لتحديد إجابة واحدة صحيحة. فالأهم من القدرة على الإجابة الفورية بـ«إنها L6» هو القدرة على شرح أنه يقع فوق L4 وتحت L7، جامعًا بين إدارة الجلسة (دور شبيه بـL5) والتشفير (دور شبيه بـL6).

وفي كود .NET، تظهر هذه العلاقة مباشرة في طريقة تكديس الأصناف (classes) بعضها فوق بعض. فعندما تُغلِّف دفق L4 الذي حصلت عليه من TcpClient.GetStream() باستخدام SslStream، يُشفَّر النص الصريح الذي تكتبه عبر Write في سجل TLS قبل أن يُسلَّم إلى TCP.5

using var client = new TcpClient("example.com", 443);
// نُغلِّف دفق بايتات L4 بـTLS (ما يعادل L5/L6)
using var ssl = new SslStream(client.GetStream());
await ssl.AuthenticateAsClientAsync("example.com");
// ما يُكتب هنا هو نص L7 (HTTP) الصريح. التشفير هو مهمة SslStream
await ssl.WriteAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n..."));

وهذا التركيب القائم على تغليف دفق بدفق آخر هو النسخة البرمجية للتغليف (encapsulation). وإذا نظرت إلى اتصال المنفذ 443 في Wireshark، ستجد أن حمولة TCP لا تظهر إلا ككتلة معتمة تحمل التسمية Application Data، مما يتيح التحقق من الاتجاه المعاكس من أن «L7 قد وُضعت داخل غلاف مكافئ لـL6».

8. أي طبقة تلامسها شفرة C# الخاصة بك فعليًا؟

لنُطابق ما سبق مع أدوات مطوّر تطبيقات Windows.

الطبقة مثال حقيقي مثال على واجهة برمجة تطبيقات .NET من يضيف الترويسة
L7 التطبيق HTTP، gRPC، بروتوكول مخصص HttpClient، Grpc.Net.Client، تجميع الرسائل يدويًا كودك الخاص / مكتبة برمجية
(ما يعادل L5/L6) TLS، التسلسل (serialization)، ترميز الأحرف SslStream، JsonSerializer، Encoding مكتبة برمجية
L4 النقل TCP، UDP Socket، TcpClient، UdpClient (نظام التشغيل يُنشئ الترويسة) مكدس بروتوكولات نظام التشغيل
L3 الشبكة IP، التوجيه (routing)، ICMP Ping، NetworkInterface (قراءة فقط) مكدس بروتوكولات نظام التشغيل
L2 ارتباط البيانات Ethernet، Wi-Fi، ARP (لا يُلمس مباشرةً عادةً من تطبيق عادي) مشغّل بطاقة الشبكة (NIC driver) / بطاقة الشبكة (NIC)
L1 الفيزيائية إشارة كهربائية، ضوء، موجات لاسلكية بطاقة الشبكة (NIC) / الكابل / الفضاء

يمكن استخلاص أمرين من هذا الجدول.

أولًا، اختيار واجهة برمجة التطبيقات (API) هو في جوهره اختيار «إلى أي طبقة فما دون تُفوَّض المهمة». فاستخدام HttpClient يتيح تفويض حتى تجميع L7، بينما استخدام Socket يعني أن عليك كتابة L7 بالكامل بنفسك. وفي المقابل، لا يكاد تطبيق Windows العادي يتلاعب مباشرةً بـL3 أو ما دونها (فالمقابس الخام raw sockets تتطلب صلاحيات المسؤول وتخضع لقيود صارمة).

ثانيًا، الشيء الوحيد الذي يُمرَّر إلى Socket.Send هو سلسلة بايتات L7 «فقط». فالجزء الثاني (Part 2) من العينة عرض توضيحي يُرسل طلب HTTP فعليًا عبر loopback، لكن كل ما يُجهّزه التطبيق هو 60 بايتًا من نص HTTP فقط، أما مجموعة الترويسات البالغة 54 بايتًا التي رأيناها في الفصل الثالث فيُضيفها نظام التشغيل وبطاقة الشبكة. فكود الشبكة في تطبيقك، في الواقع، لا يقوم إلا بمهمة صنع أعمق حمولة من بين الطبقات السبع - وهذه هي العلاقة الدقيقة بين نموذج OSI وكودك.

using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(IPAddress.Loopback, port);

byte[] request = Encoding.ASCII.GetBytes(
    $"GET / HTTP/1.1\r\nHost: localhost:{port}\r\nConnection: close\r\n\r\n");

// كل ما يُمرَّر هو سلسلة بايتات L7 فقط. تُضاف ترويسات TCP/IP/Ethernet
// في الجانب الآخر من هذا الاستدعاء (نظام التشغيل وبطاقة الشبكة)
int sent = await socket.SendAsync(request);

9. جرّب بنفسك — تجميع إطار وفتحه في Wireshark

لتحويل «فهمتُ بالقراءة» إلى «فهمتُ بالرؤية»، سنستعرض كيفية تشغيل الكود العيني.

محور العينة هو SampleFrameBuilder، الذي يُجمّع إطار الفصل الثالث بالترتيب نفسه الذي يُغلَّف به من L7 نزولًا إلى L2. وما يحدث في كل طبقة أثناء الإرسال يتجسد مباشرة في ترتيب الدوال (methods).

public static byte[] BuildHttpGetFrame()
{
    // L7: كل ما يُمرره التطبيق إلى Send هو سلسلة البايتات هذه "فقط"
    byte[] http = Encoding.ASCII.GetBytes(HttpRequest);

    // L4: مكدس بروتوكولات نظام التشغيل يُضيف ترويسة TCP في المقدمة
    byte[] tcp = WrapInTcp(http);

    // L3: يُضاف بعد ذلك ترويسة IPv4 في المقدمة
    byte[] ip = WrapInIpv4(tcp);

    // L2: يُضيف مشغّل بطاقة الشبكة ترويسة Ethernet في المقدمة قبل السلك مباشرة
    return WrapInEthernet(ip);
}

عند تشغيل العرض التوضيحي، بالإضافة إلى عرض تفريغ البايتات السداسي عشري والعرض المتداخل (nested view)، يُصدَّر هذا الإطار أيضًا كـملف pcap.

dotnet run --project samples/Demo

جرّب فتح ملف sample-http-get.pcap الناتج في Wireshark.6 ستظهر في اللوحة الوسطى أربعة أسطر مرتبة عموديًا هي Ethernet II / Internet Protocol Version 4 / Transmission Control Protocol / Hypertext Transfer Protocol، وعند النقر على أي منها يُبرَز فقط نطاق البايتات المقابل في تفريغ البايتات السداسي عشري أسفله. وبذلك تعرض لك أداة معيارية في هذا المجال الشيء نفسه الذي رأيته في العرض المتداخل بالفصل الثالث. وبمجرد التحقق من ذلك، تأتي الخطوة التالية: حركة المرور الحقيقية. ابدأ التقاطًا (capture) في Wireshark، وأدخل في المرشِّح (filter) شيئًا مثل tcp.port == 443، ثم افتح أي موقع في المتصفح، وستتمكن من التحقق من أن كل اتصال حقيقي مبني على هذا التداخل نفسه.

علمًا بأن تنفيذ جانب المُشرِّح (PacketDissector) يحتوي أيضًا على درس عملي مفيد. فمثلًا، عند استخراج حمولة IPv4، يجب الاعتماد على حقل TotalLength في الترويسة لتحديد حدود القطع، وليس على كامل ما تبقى من مخزن الاستقبال (buffer). والسبب أن Ethernet له حد أدنى لطول الإطار (60 بايتًا)، فتُلحَق بالحزم القصيرة حشوة (padding) لا معنى لها في نهايتها. «إزالة عبء الطبقة الخارجية (الحشوة) بالاعتماد على معلومات الطول الخاصة بالطبقة الداخلية» - هذا أيضًا مثال على كيفية ظهور توزيع مسؤوليات الطبقات في التنفيذ الفعلي، وهو أمر تم التحقق منه عبر اختبارات وحدة (unit tests).

10. استخدام نموذج OSI في العمل — تضييق النطاق باستخدام مفردات الطبقات

ذكرنا في المقدمة أن «OSI بقي حيًا كمفردات». وفيما يلي موضعان تُثبت فيهما هذه المفردات فائدتها فعليًا.

استكشاف الأخطاء وإصلاحها. يمكن تضييق نطاق بلاغ مثل «لا يمكنني الاتصال بالخادم» بشكل منهجي عند ترجمته إلى مفردات الطبقات. والقاعدة المتبعة هي التحقق بدءًا من الأسفل.

التحقق ما يُستخدم الطبقة التي يُثبت أنها حية
مصباح الاتصال (link light) / مؤشر اتصال Wi-Fi الفحص البصري L1-L2
ping إلى البوابة ضمن القطعة نفسها ping 192.168.x.1 L3 في محيطك المباشر
ping إلى المضيف البعيد ping <الطرف البعيد> L3 على طول المسار بالكامل
اتصال TCP بمنفذ الطرف البعيد Test-NetConnection <الطرف البعيد> -Port 443 L4 (+ أي جدار حماية على المسار)
إرسال طلب HTTP curl -v أو التطبيق نفسه L7 (+ TLS)

فمثلًا، إذا «نجح ping لكن فشل Test-NetConnection»، فهذا يعني أن كل شيء حتى L3 سليم، ويضيق نطاق الشك إلى شيء يحجب المنفذ عند L4 (خدمة متوقفة، جدار حماية، خطأ في إعداد رقم المنفذ). أما إذا «نجح اتصال TCP لكن أعاد HTTP الكود 400»، فالمشكلة ليست في الشبكة بل في L7 (محتوى الطلب). فبدلًا من فصل الكابلات وإعادة توصيلها عشوائيًا، حدِّد تدريجيًا وبشكل قاطع إلى أي طبقة لا يزال كل شيء حيًا - هذه هي طريقة استخدام نموذج OSI في العمل الفعلي.

لغة مشتركة للتحاور. فحوار من نوع «يبدو أنها مشكلة L2، هل يمكنك مراجعة منفذ المِبدّل؟» أو «هذا كلام عن L7، فهو من اختصاص فريق التطبيق» يُفهَم بدقة بين المسؤولين عن الشبكة والبنية التحتية ومطوّري التطبيقات. فرقم الطبقة هو نظام إحداثيات مشترك على مستوى الصناعة للتعبير بإيجاز عن نقطة المسؤولية.

11. تصحيح المفاهيم الخاطئة الشائعة

أخيرًا، لنجمع ونصحح المفاهيم الخاطئة الشائعة المتعلقة بنموذج OSI المرجعي.

  • «الإنترنت يعمل بالطبقات السبع لنموذج OSI» - غير صحيح. فما هو مُنفَّذ فعليًا هو TCP/IP (أربع طبقات فعليًا)، وOSI هو نموذج مرجعي للشرح والتحاور.2
  • «طبقات TCP/IP الأربع تُقابل بدقة طبقات OSI السبع» - التوافق بين L5 وL7 غامض في جوهره. كثيرًا ما نرى جداول تقول «طبقة تطبيق TCP/IP = L5 + L6 + L7 من OSI»، لكن كما رأينا في الفصل السابع، فإن أدوار L5 وL6 ممتصة فعليًا ومبعثرة بين TLS وصيغ التسلسل (serialization).
  • «TLS هو بروتوكول الطبقة السادسة (أو الخامسة)» - لا معنى لتحديده في طبقة واحدة بعينها. الوصف الدقيق هو أنه يقع فوق L4 وتحت L7، جامعًا بين أدوار مكافئة لـL5 وL6.
  • «يمكن معرفة البروتوكول من رقم المنفذ فقط» - كون المنفذ 80 لا يعني بالضرورة أنه HTTP. فرقم المنفذ مجرد عرف، ولا يمكن معرفة ما يتدفق فعليًا إلا بالنظر إلى الحمولة. ولهذا السبب بالذات يحدد مُشرِّح العينة نوع HTTP بالاعتماد على الأحرف الأولى من المحتوى وليس على رقم المنفذ.
  • «المِبدّل جهاز L2، وجهاز التوجيه جهاز L3» - هذا صحيح كنقطة انطلاق، لكن في الواقع توجد بشكل معتاد أجهزة تمتد عبر طبقات متعددة، مثل مِبدّلات L3، وموازنات الحمل (load balancers) التي توزّع عند L4، وجدران حماية تطبيقات الويب (WAF) التي تفحص L7. والأدق هو النظر إلى «حتى أي طبقة يقرأ هذا الجهاز».

12. الخلاصة

  • نموذج OSI المرجعي ليس تطبيقًا فعليًا، بل مفردات للتفكير عبر الطبقات. وما يعمل فعليًا هو TCP/IP (أربع طبقات فعليًا)
  • الطبقات السبع ليست مخططًا تصوريًا، بل متداخلة فعليًا داخل سلسلة بايتات إطار واحد (L2: 0-13، L3: 14-33، L4: 34-53، L7: 54 فما فوق)
  • تقرأ كل طبقة ترويستها الخاصة فقط، ولا تكترث بالحمولة (الطبقة الداخلية) - وهذا هو التغليف (encapsulation)
  • لا توجد L5 وL6 كطبقتين مستقلتين في المكدس الحقيقي، وقد امتص TLS والترميز أدوارهما
  • الشيء الوحيد الذي تكتبه شفرة C# الخاصة بك هو سلسلة بايتات L7. يُضيف نظام التشغيل ترويسات TCP/IP، وتُضيف بطاقة الشبكة ترويسة Ethernet
  • الاستخدام العملي هو استكشاف الأخطاء وإصلاحها عبر التحقق من الاستمرارية طبقة تلو أخرى بدءًا من الأسفل، إضافة إلى كونه لغة مشتركة بين الفرق
  • عند تجميع إطار باستخدام الكود العيني وفتحه في Wireshark، يمكنك التحقق من كل محتوى هذا المقال بأم عينيك

مقالات ذات صلة

مجالات استشارية ذات صلة

تتولى شركة KomuraSoft LLC (合同会社小村ソフト) تصميم وتنفيذ تطبيقات Windows التي تتواصل عبر TCP/IP، والتحقيق في الأسباب الجذرية لمشكلات الاتصال مع الأجهزة الصناعية (مثل «الانقطاع أحيانًا» أو «البطء»)، وتقديم الدعم في استكشاف الأخطاء وإصلاحها باستخدام التقاط الحزم (packet capture).

روابط مرجعية

  1. ITU-T، X.200 : Information technology - Open Systems Interconnection - Basic Reference Model: The basic model. المصدر الأصلي لنموذج OSI المرجعي الأساسي (مطابق في محتواه لـISO/IEC 7498-1). حول تعريف كل طبقة من الطبقات السبع.  2

  2. IETF، RFC 1122 - Requirements for Internet Hosts – Communication Layers. RFC يحدد المتطلبات التي يجب أن تُنفذها مضيفات الإنترنت. حول تنظيم مجموعة البروتوكولات ضمن أربع طبقات: طبقة الارتباط، وطبقة IP، وطبقة النقل، وطبقة التطبيق.  2 3 4 5

  3. Microsoft Learn، Socket Class (System.Net.Sockets). واجهة برمجة تطبيقات المقابس (sockets) في .NET. حول تمرير التطبيق للحمولة فقط، بينما يتولى مكدس بروتوكولات نظام التشغيل توليد ترويسات البروتوكول. 

  4. IETF، RFC 9293 - Transmission Control Protocol (TCP). المواصفة الحالية لـTCP. حول توفير الموثوقية عبر أرقام التسلسل والإقرارات، واستخدام ترويسة زائفة تحتوي على عناوين IP في حساب مجموع الاختبار (checksum).  2

  5. Microsoft Learn، SslStream Class (System.Net.Security). حول الصنف (class) الذي يُغلِّف دفقًا (stream) قائمًا (عادة NetworkStream الخاص بـTCP) لتوفير التشفير والمصادقة عبر TLS. 

  6. Wireshark Foundation، Wireshark User’s Guide. حول كيفية فتح ملفات الالتقاط (capture)، والعرض المتقابل بين لوحة تفاصيل الحزمة ولوحة سلسلة البايتات، وكيفية استخدام مرشحات العرض (display filters). 

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

معالجة التقويم الياباني والعطلات الرسمية وتاريخ الإغلاق في تطبيقات الأعمال — تصميم مقاوم لتغيّر العصر، وJapaneseCalendar، وحساب أيام العمل في الممارسة العملية

عرض «ريوا 8» في تقرير رسمي، وحساب أيام العمل باستثناء العطلات الرسمية، والدفع في آخر يوم عمل من الشهر التالي لإغلاق يقع في اليوم العشرين ...

ترتبط هذه المقالة بشكل طبيعي بصفحات الخدمات التالية.

الأسئلة الشائعة

أسئلة شائعة حول موضوع هذه المقالة.

هل تُستخدم الطبقات السبع لنموذج OSI فعليًا في الإنترنت الحقيقي؟
لا، لا تُستخدم. ما يعمل فعليًا على الإنترنت الحقيقي هو مجموعة بروتوكولات TCP/IP (أربع طبقات فعليًا)؛ أما بروتوكولات OSI ذات الطبقات السبع نفسها فقد خسرت سباق الانتشار في تسعينيات القرن الماضي وانتهى بها المطاف بالكاد مستخدمة. يشرح RFC 1122، الذي أرسى أسس الإنترنت، العالم من خلال أربع طبقات: طبقة الارتباط، وطبقة IP، وطبقة النقل، وطبقة التطبيق. ما بقي هو النموذج كمفردات مشتركة لاستكشاف الأخطاء وإصلاحها والتحاور، مثل عبارات «لنعزل هذا عند L2» أو «هذه مشكلة L7».
أين توجد فعليًا طبقة الجلسة (L5) وطبقة العرض (L6)؟
لا توجد كطبقتين مستقلتين في مكدس TCP/IP الحقيقي. الأدوار التي تصورها نموذج OSI مبعثرة فعليًا وممتصة في أماكن أخرى: L5 (إنشاء الحوار وإدارته) يقابله مصافحة TLS (handshake) أو ملفات تعريف الارتباط (cookies) والرموز المميزة (tokens) في HTTP، وL6 (تحويل تمثيل البيانات وتشفيرها) يقابله تشفير TLS، وترميز الأحرف، وصيغ التسلسل (serialization) مثل JSON. لا قيمة عملية لتحديد طبقة واحدة بعينها ينتمي إليها TLS — الأهم هو القدرة على شرح أنه يقع فوق L4 وتحت L7، جامعًا بين أدوار مكافئة لـL5 وL6.
إذا كان هناك عنوان IP بالفعل، فلماذا يلزم أيضًا عنوان MAC؟
لأن الطبقات توزّع المسؤولية بشكل مختلف. عنوان IP (L3) هو العنوان الذي يشير إلى الوجهة النهائية، ولا يتغير من بداية الاتصال حتى نهايته. أما عنوان MAC (L2) فهو العلامة التي تشير إلى من سينقل القطعة التالية من المسار، ويُستبدل في كل مرة يعبر فيها جهاز توجيه (router). الإطار المُرسَل من جهاز كمبيوتر في المكتب إلى خادم ويب يكون عنوان MAC الوجهة الخاص به ليس خادم الويب، بل البوابة الافتراضية (جهاز التوجيه). وARP هو ما يبحث عن عنوان MAC لعقدة مجاورة انطلاقًا من عنوان IP، ويمكن الاطلاع على جدول التطابق عبر أمر arp -a.
ما الفائدة العملية الحقيقية لنموذج OSI؟
استكشاف الأخطاء وإصلاحها والتحاور بين الفرق. يمكن تضييق نطاق بلاغ مثل «لا يمكنني الاتصال بالخادم» بشكل منهجي من خلال التحقق من استمرار عمل كل طبقة بدءًا من الأسفل: الفحص البصري لمصباح الاتصال (L1-L2)، وping إلى البوابة (L3)، والتأكد من اتصال TCP بمنفذ الوجهة (L4)، وإرسال طلب HTTP (L7). فمثلًا، إذا نجح ping لكن فشل اتصال TCP، يضيق نطاق الشك إلى شيء يحجب المنفذ عند L4، كخدمة متوقفة أو جدار حماية. كما يعمل النموذج كنظام إحداثيات مشترك على مستوى الصناعة للتعبير بإيجاز عن نقطة المسؤولية، كما في عبارة «يبدو أنها مشكلة L2، هل يمكنك مراجعة المِبدّل (switch)؟».

الملف الشخصي للمؤلف

صفحة الملف الشخصي لمؤلف المقالة.

غو كومورا

مؤسّس شركة كومورا سوفت ذ.م.م.

يركّز على تطوير برامج ويندوز، والاستشارات التقنية، والتحقيق في الأخطاء، ويتميّز في المشاريع التي تبقى فيها الأصول القديمة ناشطة، وفي تشخيص الأعطال التي يصعب تحديد سببها.

روابط عامة

العودة إلى المدونة