နားလည်ထားရမယ့် အချက်
Layering ရှိရတဲ့ အကြောင်းရင်းက network stack တစ်ခုဟာ တစ်ခုတည်းအဖြစ် design လုပ်၊ တည်ဆောက်၊ အစားထိုးဖို့ အလွန် ကြီးမားလွန်းလို့ ဖြစ်ပါတယ်။ ဝါယာကြိုးပေါ် bit တင်ပေးတဲ့ code နဲ့ HTTP request ကို ပုံစံချပေးတဲ့ code ဟာ ရှုပ်ထွေးစွာ ရောနှောနေမယ်ဆိုရင်၊ Wi-Fi ကနေ Ethernet ကို ပြောင်းလိုက်တာနဲ့ web browser တစ်ခုလုံးကို ပြန်ရေးရပါလိမ့်မယ်။ Layering က မျဉ်းတွေကို တမင် ဆွဲပေးထားပါတယ် — layer တစ်ခုစီက သူ့အထက်က layer ကို ကျဉ်းမြောင်းတဲ့ service တစ်ခု ပေးပြီး၊ သူ့အောက်က layer ဆီကလည်း ကျဉ်းမြောင်းတဲ့ service တစ်ခုကိုသာ မှီခိုပါတယ်။ ဒါကြောင့် Wi-Fi ကို အသစ်တီထွင်လိုက်လည်း HTTP က မသိရပါဘူး၊ HTTP/3 ပေါ်လာလည်း ဝါယာကြိုးတစ်ချောင်းမှ မထိရပါဘူး။
OSI model က ဒီလို layer ၇ ခုကို အမည်ပေးထားပါတယ် — physical, data link, network, transport, session, presentation, application။ ဒါကို blueprint လို့ မမြင်ဘဲ ဝေါဟာရ စာရင်းတစ်ခုလို့ မြင်တာ အကောင်းဆုံးပါ။ ဘယ်သူမှ OSI stack စစ်စစ်ကို မထုတ်ပါဘူး။ တကယ့် စနစ်တွေက အသုံးပြုတဲ့ TCP/IP model ကတော့ ၄ ခုပဲ သုံးပါတယ် — link, internet, transport, application။ ဆက်စပ်ပုံက တိတိကျကျ မဟုတ်ပေမယ့် အသုံးဝင်ပါတယ် — OSI ရဲ့ physical နဲ့ data link က TCP/IP ရဲ့ link ထဲ ပေါင်းသွားပြီး၊ network က internet ဖြစ်သွားတယ်၊ transport က transport အတိုင်းပဲ ကျန်ပြီး၊ OSI ရဲ့ အပေါ်ဆုံး သုံးခုက application တစ်ခုတည်း ဖြစ်သွားပါတယ် — ဒါကြောင့် လူတွေက transport အထက်က ဘယ်အရာကိုမဆို "Layer 7" လို့ ခေါ်ကြတာ ဖြစ်ပါတယ်။
Layering ကို တကယ့်အဖြစ်မှန် ဖြစ်စေတဲ့ mechanism ကတော့ encapsulation ပါ။ data က stack အောက်ဘက် ဆင်းသွားတဲ့အခါ layer တစ်ခုစီက သူ့ကိုယ်ပိုင် header ကို ရှေ့မှာ တပ်ပြီး၊ သူလက်ခံရရှိတဲ့ အရာအားလုံးကို ဖွင့်လို့မရတဲ့ payload အဖြစ်သာ သဘောထားပါတယ်။ သင့် bytes တွေက segment ဖြစ်သွားပြီး၊ segment က packet ဖြစ်၊ packet က frame ဖြစ်သွားပါတယ်။ လက်ခံတဲ့ဘက်မှာတော့ layer တစ်ခုစီက သူ့ header ကိုပဲ တိတိကျကျ ခွာချပြီး ကျန်တာကို အထက်ကို လှမ်းပေးပါတယ်။ ဒါကြောင့်ပဲ router တစ်ခုဟာ သင့် traffic က HTTP လား၊ video လား၊ ဂိမ်းလား ဆိုတာ လုံးဝ ဂရုမစိုက်ဘဲ forward လုပ်ပေးနိုင်တာ ဖြစ်ပါတယ်။
OSI VS TCP/IP, AND WHAT ENCAPSULATION LOOKS LIKE
------------------------------------------------
OSI (7 layers) TCP/IP (4 layers)
+------------------+ +--------------------+
| 7 Application | | |
| 6 Presentation |---------->| Application |
| 5 Session | | |
+------------------+ +--------------------+
| 4 Transport |---------->| Transport |
+------------------+ +--------------------+
| 3 Network |---------->| Internet |
+------------------+ +--------------------+
| 2 Data Link | | |
| 1 Physical |---------->| Link |
+------------------+ +--------------------+
Going DOWN the stack, each layer wraps whatever it was handed:
L7 [ data ] your bytes
L4 [ TCP | data ] = segment
L3 [ IP | TCP | data ] = packet
L2 [ETH| IP | TCP | data |FCS] = frame
\____________________________/
this is what the cable carries
Going UP, each layer removes exactly its own header and no more.လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Request တစ်ခု ဘာကြောင့် လုံးဝ မရောက်ဘူးလဲ ဆိုတာ ရှာနေပြီး packet capture တစ်ခု ဖွင့်ထားတယ် ဆိုပါစို့။ Layering က ဘယ်နေရာကို ဘယ်အစဉ်လိုက် ကြည့်ရမလဲ ဆိုတာ အတိအကျ ပြောပြပေးပါတယ်။ ဖမ်းမိထားတဲ့ frame တစ်ခုကို ဖြန့်ကြည့်လိုက်ရင် model က ပြောထားတဲ့ အထပ်ထပ် ထုပ်ပိုးမှုကို အတိအကျ တွေ့ရပါလိမ့်မယ် — MAC address နှစ်ခုပါတဲ့ Ethernet header၊ သူ့ထဲမှာ IP address နှစ်ခုပါတဲ့ IP header၊ သူ့ထဲမှာ port number နှစ်ခုပါတဲ့ TCP header၊ ပြီးမှသာ သင့် HTTP request စာသား ဖြစ်ပါတယ်။
ဒါကို စစ်ဆေးရမယ့် စာရင်းတစ်ခုလို ဖတ်ပါ။ frame ကိုယ်တိုင် လုံးဝ မရှိဘူးဆိုရင် ပြဿနာက network layer အောက်မှာ ရှိပါတယ် — ကြိုး၊ Wi-Fi association၊ ဒါမှမဟုတ် switch port။ frame တွေ ပေါ်ပေမယ့် IP header ထဲက destination က မျှော်လင့်ထားတာနဲ့ မတူဘူးဆိုရင် သင့် routing ဒါမှမဟုတ် DNS resolution မှားနေတာဖြစ်ပြီး application code မှားတာ မဟုတ်ပါဘူး။ IP က မှန်ပေမယ့် TCP မှာ SYN တွေ ထပ်ခါထပ်ခါ ပို့နေပြီး ပြန်စာ မရှိဘူးဆိုရင် တစ်စုံတစ်ခုက connection ကို ဖြတ်ချနေတာပါ — firewall ဒါမှမဟုတ် နားမထောင်နေတဲ့ service — ဒီအဆင့်မှာ HTTP payload ကို ဖတ်ဖို့ ကြိုးစားတာ အချည်းနှီးပါပဲ၊ ဘာလို့လဲဆိုတော့ HTTP ဆိုတာ တစ်ခုမှ မရှိသေးလို့ ဖြစ်ပါတယ်။
Encapsulation က performance ပြဿနာ တစ်ခုကိုလည်း ရှင်းပြပေးပါတယ် — layer တစ်ခုစီက header bytes တွေ ထပ်ဖြည့်ပါတယ်။ အောက်က code ပြသလိုပဲ 5-byte message သေးသေးလေးက 36-byte frame အဖြစ် ကြီးထွားသွားနိုင်ပါတယ်။ ဒီ overhead က file transfer အတွက် သိသာစရာ မရှိပေမယ့်၊ message သေးသေးလေးတွေ ခဏခဏ ပို့တဲ့ protocol တွေအတွက်တော့ အဓိက ကုန်ကျစရိတ် ဖြစ်လာပါတယ် — ဒါကြောင့်ပဲ protocol တွေက message တွေကို စုပြီး batch လုပ်ကြတာ ဖြစ်ပါတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
import struct
# Start at the top of the stack: the data the application wants to send.
data = b"hello"
# L4 transport: prepend src port, dst port, segment length.
l4_header = struct.pack("!HHH", 51000, 443, 6 + len(data))
segment = l4_header + data
# L3 network: prepend version, ttl, protocol, then src and dst IPv4.
l3_header = (struct.pack("!BBB", 4, 64, 6)
+ bytes([192, 0, 2, 15])
+ bytes([198, 51, 100, 34]))
packet = l3_header + segment
# L2 link: prepend dst MAC, src MAC, ethertype (0x0800 = IPv4).
l2_header = (bytes.fromhex("aabbccddeeff")
+ bytes.fromhex("112233445566")
+ struct.pack("!H", 0x0800))
frame = l2_header + packet
units = [
("L7 data", data, 0),
("L4 segment", segment, len(l4_header)),
("L3 packet", packet, len(l3_header)),
("L2 frame", frame, len(l2_header)),
]
print("%-11s %6s %7s %8s" % ("unit", "total", "header", "payload"))
print("-" * 36)
for name, unit, hdr in units:
print("%-11s %6d %7d %8d" % (name, len(unit), hdr, len(unit) - hdr))
print()
print("the frame is one flat byte string, built from these pieces:")
print(" L2 header:", l2_header.hex())
print(" L3 header:", l3_header.hex())
print(" L4 header:", l4_header.hex())
print(" L7 data :", data.hex())
print()
hex_frame = frame.hex()
print("full frame (%d bytes):" % len(frame))
for i in range(0, len(hex_frame), 56):
print(" ", hex_frame[i:i + 56])
print()
print("total header overhead :", len(frame) - len(data), "bytes")
print("payload efficiency :", round(100 * len(data) / len(frame), 1), "%")
# Decapsulation: the receiver strips the same headers in reverse order.
recovered = frame[len(l2_header):][len(l3_header):][len(l4_header):]
print("recovered payload :", recovered.decode())
unit total header payload
------------------------------------
L7 data 5 0 5
L4 segment 11 6 5
L3 packet 22 11 11
L2 frame 36 14 22
the frame is one flat byte string, built from these pieces:
L2 header: aabbccddeeff1122334455660800
L3 header: 044006c000020fc6336422
L4 header: c73801bb000b
L7 data : 68656c6c6f
full frame (36 bytes):
aabbccddeeff1122334455660800044006c000020fc6336422c73801
bb000b68656c6c6f
total header overhead : 31 bytes
payload efficiency : 13.9 %
recovered payload : hello၅ မိနစ် စမ်းကြည့်
data ကို b"hello" အစား 1400-byte payload (ဥပမာ b"x" * 1400) အဖြစ် ပြောင်းပြီး payload efficiency ဘယ်လောက် တက်သွားလဲ တွက်ကြည့်ပါ။ ပြီးရင် payload size 1, 10, 100, 1000 အတွက် efficiency ကို loop နဲ့ ထုတ်ပြပြီး၊ ဘယ်အရွယ်ကစပြီး header overhead က သိသိသာသာ မဟုတ်တော့လဲ ဆုံးဖြတ်ပါ။
သတိလေးတစ်ချက်
Encapsulation ကို layer တစ်ခုစီ data ကို "ပြောင်းလဲ" တာလို့ ထင်ခြင်း — တကယ်တော့ header ကို ရှေ့မှာ တပ်ရုံသာ ဖြစ်ပြီး မူရင်း bytes တွေက ပြောင်းလဲမသွားဘဲ frame ထဲမှာ အတိအကျ ကျန်နေပါတယ်
OSI ရဲ့ layer ၅ (session) နဲ့ ၆ (presentation) ကို တကယ့် network stack ထဲမှာ ရှာနေခြင်း — TCP/IP မှာ ဒီ layer တွေ သီးခြား မရှိဘဲ application layer ထဲ ပေါင်းထည့်ထားပါတယ်
RFC 1122 — Requirements for Internet Hosts (Communication Layers) — Computer Networking