Mininet — ทดสอบ Delay, Jitter, Loss และ Throughput
สร้างเน็ตเวิร์คจำลองด้วย Mininet บน Ubuntu ARM ใน Parallels แล้วบิดค่าลิงก์ด้วย tc netem — หน่วงเวลา ใส่ jitter ทำแพ็กเก็ตหาย แล้ววัดผลด้วย ping และ iperf3
ทำอะไร — แลปนี้ไม่มีอุปกรณ์จริงและไม่เกี่ยวกับ GNS3 เลย ทุกอย่างรันในลินุกซ์: สร้างโฮสต์ 4 ตัว สวิตช์ 2 ตัวด้วย Mininet แล้วใช้ tc netem ใส่ delay / jitter / loss ลงบน h1-eth0 แล้ววัดว่าเลขที่ ping กับ iperf3 รายงานเปลี่ยนไปยังไง
ได้อะไร — อ่านผล ping เป็นว่าตัวไหนคือ delay ตัวไหนคือ jitter ตัวไหนคือ loss และเข้าใจว่าทำไม TCP ถึงช้าลงเมื่อ RTT หรือ loss สูงขึ้น
ออกสอบตรงไหน — ข้อ 4 (15 คะแนน) ตรง ๆ ทั้งข้อ: สร้าง topology ตามรูปที่ 17 → ping ให้ครบทุกโหนด → (a) delay 100ms 10ms บน h1-eth0 เทียบก่อน/หลัง (b) loss 20% แล้ว ping · เปิด §3.20 อ่านก่อนเข้าห้องสอบ
3.1เป้าหมายและสิ่งที่ต้องส่ง
ใบแลปหัวข้อ 1 เขียนวัตถุประสงค์ไว้ 5 ข้อ — เมื่อทำเสร็จนักศึกษาจะสามารถ
- อธิบายความหมายและที่มาของค่า Delay, Jitter, Packet Loss, Bandwidth และ Throughput ได้อย่างถูกต้อง
- ใช้งานมินิเน็ตเพื่อจำลองเน็ตเวิร์คและปรับแต่งพารามิเตอร์ของลิงก์ด้วยคำสั่ง
tc/netem - วัดและบันทึกค่าประสิทธิภาพของเน็ตเวิร์คด้วยคำสั่ง
pingและโปรแกรมiperf3 - วิเคราะห์ความสัมพันธ์ระหว่าง Delay, Jitter, Loss กับ Throughput ของ TCP โดยอ้างอิงหลักการทางทฤษฎี
- เปรียบเทียบผลการทดลองที่ได้จากการจำลองบนมินิเน็ตกับการทดสอบบนอุปกรณ์จริง
| # | สิ่งที่ใบแลปสั่ง | อยู่ที่ไหน |
|---|---|---|
| 1 | เตรียมระบบ — ใบแลปเขียนว่า Ubuntu 18.04+ บน Windows 10/11 ผ่าน VMware Workstation Player 16 ใช้บน Mac ไม่ได้ → เราใช้ Ubuntu ARM บน Parallels แทน | §3.3 |
| 2 | ติดตั้ง Mininet — git clone แล้ว install.sh พร้อม option -a / -nfv / -s | §3.4 |
| 3 | สร้างเน็ตเวิร์คผ่าน GUI (MiniEdit) — ส่วนประกอบ 7 อย่าง, กำหนด IP 2 วิธี | §3.5 |
| 4 | การเรียกชื่อโฮสต์และสวิตซ์ — h1-eth0, s1-eth1 และเรื่อง namespace / veth | §3.6 |
| 5 | ทดสอบเน็ตเวิร์คที่สร้างขึ้น — Run → เปิด Terminal ของ h1 → ifconfig → ping | §3.7 |
| 6 | Traffic Control (tc/netem) — เพิ่ม/แก้/ลบ delay, jitter, loss | §3.8 |
| 7 | Iperf3 — โหมด server/client และความหมายของทุกคอลัมน์ในผลลัพธ์ | §3.9 |
| 8 | การทดลอง 8.1–8.5 — Delay, Jitter, Loss, Iperf3 และอุปกรณ์จริง ตัวข้อสอบ | §3.10–§3.15 |
| 9 | สรุปผลการทดลอง — กรอกตารางที่ 1 แล้วอภิปรายอ้างอิงทฤษฎีในหัวข้อ 2 | §3.16 |
ใบแลปข้อ 8.1 เขียนว่า "กำหนด IP address ของเน็ตเวิร์คตามหมายเลขรหัสนักศึกษาของตนเอง" — ใช้กติกาเดียวกับ Lab 1/2 คือ x = เลขหลังขีด = 3 และ y = สามตัวก่อนขีด mod 254 = 128 mod 254 = 128 ได้วง 192.3.128.0/24
| โหนด | IP | Interface | ต่อกับ |
|---|---|---|---|
| h1 | 192.3.128.1/24 | h1-eth0 ตัวที่ใส่ netem | s1-eth1 |
| h2 | 192.3.128.2/24 | h2-eth0 | s1-eth2 |
| h3 | 192.3.128.3/24 | h3-eth0 | s2-eth1 |
| h4 | 192.3.128.4/24 | h4-eth0 | s2-eth2 |
| s1 ↔ s2 | — | s1-eth3 ↔ s2-eth3 | สายระหว่างสวิตช์ |
ทุกโหนดอยู่วงเดียวกัน /24 จึง ไม่ต้องมี router และไม่ต้องตั้ง gateway — สวิตช์สองตัวต่อกันตรง ๆ ทำงานเป็นเลเยอร์ 2 อย่างเดียว
3.2ทฤษฎีพื้นฐาน: ประสิทธิภาพของเครือข่าย
ใบแลปหัวข้อ 2 ให้อ่านก่อนเริ่มทดลอง เพราะทุกตัวเลขที่จะวัดในแลปนี้มีชื่อและที่มาชัดเจน
2.1 ความหน่วง (Delay) และองค์ประกอบของความหน่วง
ความหน่วงปลายทางถึงปลายทาง (end-to-end delay) ประกอบด้วยความหน่วงย่อยหลายส่วน ตามรูปที่ 1 ของใบแลป
Processing Delay
เวลาที่โหนดใช้ในการประมวลผลเฮดเดอร์ของแพ็กเก็ต — อ่านปลายทาง ตรวจ checksum ตัดสินใจว่าจะส่งออกทางไหน
Queuing Delay
เวลาที่แพ็กเก็ตต้องรอในคิวก่อนถูกส่งออก — ขึ้นกับปริมาณทราฟฟิกที่คับคั่งในขณะนั้น (ตัวเดียวที่แปรผันตามโหลด จึงเป็นต้นเหตุหลักของ jitter)
Transmission Delay
เวลาที่ใช้ดันข้อมูลทั้งหมดออกทางลิงก์ คำนวณจาก L / R โดย L = ขนาดแพ็กเก็ต (bit) และ R = Bandwidth (bit/s)
Propagation Delay
เวลาที่สัญญาณเดินทางผ่านตัวกลาง คำนวณจาก d / s โดย d = ระยะทาง และ s = ความเร็วของสัญญาณในตัวกลาง
Transmission delay — แทนค่าจริง
L = 1500 ไบต์ = 12,000 bit · R = 100 Mbit/s
L/R = 12,000 / 100,000,000 = 0.12 ms
ถ้าลิงก์เป็น 1 Gbit/s จะเหลือ 0.012 ms — เร็วขึ้น 10 เท่าตามความเร็วลิงก์
Propagation delay — แทนค่าจริง
d = 200 km = 200,000 m · s ≈ 2×108 m/s ในสายไฟเบอร์
d/s = 200,000 / 2×108 = 1 ms
ไม่ขึ้นกับขนาดแพ็กเก็ตเลย — ขึ้นกับระยะทางอย่างเดียว
ใบแลปสรุปไว้ว่า คำสั่ง tc/netem จะเพิ่มค่า Transmission/Propagation Delay เทียมเข้าไปบนอินเตอร์เฟซที่กำหนด เพื่อจำลองสถานการณ์ที่โหนดอยู่ห่างกันทางภูมิศาสตร์ หรือลิงก์มีคุณภาพต่ำ
2.2 ความแปรปรวนของความหน่วง (Jitter)
Jitter คือความแปรปรวนของค่า Delay ในแต่ละแพ็กเก็ต ที่ส่งออกไป ตามรูปที่ 2 ของใบแลป — หากค่า Delay คงที่ทุกแพ็กเก็ต (กรณีอุดมคติ) ผู้รับจะสามารถเล่นข้อมูลได้อย่างต่อเนื่อง แต่หากมี Jitter สูง แพ็กเก็ตจะมาถึงไม่สม่ำเสมอ ซึ่งส่งผลกระทบรุนแรงต่อแอปพลิเคชันแบบเรียลไทม์ เช่น VoIP หรือวิดีโอคอล
โปรแกรมเรียลไทม์ต้องเล่นเสียงออกลำโพงทุก 20 ms พอดี ถ้าแพ็กเก็ตมาช้าไปกว่าคิวเล่น (jitter buffer) ที่เตรียมไว้ ก็ต้องทิ้งไปเลย → เสียงขาด · ส่วนการโหลดไฟล์ TCP แค่เอาไปต่อกันในบัฟเฟอร์ มาช้าก็แค่รอ ไม่มีอะไรเสียหาย — ฉะนั้น jitter กระทบ VoIP มากกว่ากระทบ throughput (ข้อนี้ใบแลปถามไว้ในคำถามข้อ 8.2)
2.3 การสูญหายของแพ็กเก็ต (Packet Loss)
Packet Loss คือสัดส่วนของแพ็กเก็ตที่ส่งออกไปแต่ไม่สามารถไปถึงปลายทางได้ ใบแลประบุสาเหตุหลักไว้ 3 อย่าง
- Buffer overflow ที่อุปกรณ์กลางทาง — คิวเต็ม แพ็กเก็ตใหม่ถูกทิ้ง
- ข้อผิดพลาดของสัญญาณ (bit error) ที่ทำให้ต้องทิ้งแพ็กเก็ต
- Congestion บนเส้นทาง
สำหรับ TCP การสูญหายของแพ็กเก็ตจะกระตุ้นกลไก Congestion Control ให้ลดขนาด Congestion Window (Cwnd) ลง ส่งผลให้ Throughput ลดลงตามไปด้วย
2.4 Bandwidth และ Throughput
Bandwidth
ความสามารถสูงสุดทางทฤษฎีที่ลิงก์รองรับได้ (bit/s) — เป็นตัวเลขบนกระดาษ เช่น "1 Gbit/s"
Throughput
อัตราการส่งข้อมูลจริงที่วัดได้ ซึ่งน้อยกว่าหรือเท่ากับ Bandwidth เสมอ เพราะมี Overhead ของโปรโตคอล, Delay, Jitter และ Packet Loss เข้ามาเกี่ยวข้อง
รูปที่ 3 ของใบแลปแสดงความสัมพันธ์นี้ด้วยสูตรประมาณของ Mathis et al.
| สัญลักษณ์ | ความหมาย | ค่าที่ใช้จริง |
|---|---|---|
MSS | Maximum Segment Size — ข้อมูลสูงสุดที่ใส่ได้ใน 1 เซกเมนต์ TCP | 1460 ไบต์ = 11,680 bit (MTU 1500 − IP 20 − TCP 20) |
RTT | Round-Trip Time — เวลาไป-กลับ ตัวเดียวกับ avg ที่ ping รายงาน | วัดได้จาก ping หน่วยเป็นวินาที |
Loss | อัตราการสูญหายของแพ็กเก็ต (สัดส่วน ไม่ใช่เปอร์เซ็นต์) | loss 1% → 0.01 · loss 20% → 0.20 |
| กรณี | RTT | Loss | คำนวณ | Throughput ≈ |
|---|---|---|---|---|
| baseline | 0.2 ms | 1% | 11680 / (0.0002 × 0.1) | 584 Mbit/s |
| ใส่ delay | 100 ms | 1% | 11680 / (0.1 × 0.1) | 1.17 Mbit/s ตก 500 เท่า |
| ใส่ loss หนัก | 100 ms | 20% | 11680 / (0.1 × 0.447) | 0.26 Mbit/s ตกอีก 4.5 เท่า |
จากสูตรจะเห็นว่า Throughput ของ TCP แปรผกผันกับ RTT (เพิ่ม RTT 2 เท่า → throughput ครึ่งเดียว) และแปรผกผันกับรากที่สองของอัตราการสูญหาย (loss เพิ่ม 4 เท่า → throughput ครึ่งเดียว) ซึ่งนักศึกษาจะได้พิสูจน์ความสัมพันธ์นี้ด้วยตนเองในหัวข้อ 8.4
ถ้าแทน Loss = 0 ตัวส่วนเป็นศูนย์ → throughput เป็นอนันต์ ซึ่งเป็นไปไม่ได้ · สูตรนี้ใช้ได้เฉพาะตอนมี loss จริง ในกรณี loss = 0 ตัวจำกัดจะกลายเป็นขนาดหน้าต่างหารด้วย RTT แทน (Throughput ≤ Window / RTT) ซึ่งเป็นสาเหตุที่ iperf3 ตกจาก 40 Gbit/s เหลือหลักร้อย Mbit/s ทันทีที่ใส่ delay 100 ms ทั้งที่ยังไม่มี loss สักแพ็กเก็ต (ส่วนหลังเป็นส่วนขยาย ไม่ได้อยู่ในใบแลป)
3.3เตรียมระบบ — เส้นทางของ MacBook Air M2
ใบแลปหัวข้อ 3 เขียนไว้ว่า ให้ใช้ Ubuntu 18.04 ขึ้นไป บน Windows 10/11 ทำงานภายใต้ VMware Workstation Player 16 (หรือใช้ WSL ก็ได้) แล้วสั่งให้ปิด Hyper-V ผ่าน Turn Windows features on or off ก่อนติดตั้ง
① ไม่มี VMware Workstation Player บน macOS (ตัว Player เป็นของ Windows/Linux เท่านั้น) ② ไม่มี Hyper-V และไม่มี Windows Features บน Mac ③ ไม่มี WSL ④ ISO ของ Ubuntu ที่ใบแลปให้โหลดเป็น amd64 ซึ่งบูตบน M2 ไม่ขึ้น ต้องใช้ arm64
→ เส้นทางของเราคือ Parallels Desktop + Ubuntu ARM แล้วสั่งงานผ่าน ssh ubuntu จาก Terminal ของ macOS
ถ้ายังไม่เคยลง ให้ทำตาม หน้าติดตั้ง §0.8 ก่อน — สรุปสั้น ๆ คือ
- ลง Parallels Desktop (หรือ UTM ถ้าไม่อยากจ่ายเงิน) — ทั้งคู่ใช้ Apple Virtualization บน M2 ได้
- สร้าง VM จาก Ubuntu สำหรับ ARM64 — Parallels มีตัวเลือกดาวน์โหลด Ubuntu ARM ให้ในหน้าสร้าง VM เลย ไม่ต้องไปหา ISO เอง
- เปิด SSH ใน VM แล้วตั้งชื่อย่อ
ubuntuไว้ใน~/.ssh/configของ macOS เพื่อให้พิมพ์แค่ssh ubuntu[macOS Terminal] — ~/.ssh/configHost ubuntu HostName 10.211.55.7 # IP ของ VM ดูด้วย ip -br a ใน Ubuntu User <ชื่อผู้ใช้ใน Ubuntu> - ทดสอบว่าติด
[macOS Terminal]
$ ssh ubuntu $ ssh ubuntu 'sudo mn --test pingall' # ต้องได้ 0% dropped
รูปที่ 4–6 ของใบแลป (ฝั่ง Windows) — กดดูได้ แต่ทำตามไม่ได้บน Mac
สามรูปนี้เป็นหน้าจอของ Windows ล้วน ๆ ใส่ไว้เพื่อให้รู้ว่าเพื่อนในห้องเห็นอะไร บน MacBook จะไม่มีหน้าจอเหล่านี้เลย — ให้ทำตามขั้นตอน Parallels ด้านบนแทน
amd64 ซึ่งบูตบน Apple Silicon ไม่ขึ้น ต้องใช้ arm64)3.4ติดตั้งมินิเน็ต
ใบแลปหัวข้อ 4 บอกว่ามินิเน็ตโหลดได้ 2 ทาง — โหลดเป็นเวอร์ชวลแมชชีนสำเร็จรูปจาก mininet.org หรือโหลดจากซอร์ซโค้ดโดยตรง ซึ่งใบแลปเลือกวิธีหลังเพราะจะได้มินิเน็ตเวอร์ชันล่าสุด
modern@ubuntu:~$ git clone git://github.com/mininet/mininetgit:// ใช้ไม่ได้แล้ว
GitHub ปิดโปรโตคอล git:// แบบไม่เข้ารหัสไปตั้งแต่ปี 2022 คัดลอกบรรทัดในใบแลปไปวางตรง ๆ จะค้างแล้วขึ้น Connection timed out หรือ The unauthenticated git protocol … is no longer supported · ให้เปลี่ยนเป็น https://
$ git clone https://github.com/mininet/mininetเมื่อโหลดเสร็จ ติดตั้งด้วย ./mininet/util/install.sh [option] โดย option เป็นเงื่อนไขของการติดตั้ง
| option | ติดตั้งอะไร |
|---|---|
-a | ติดตั้งทั้งหมด — มินิเน็ต, โอเพนวีสวิตซ์ (Open vSwitch), โอเพนโฟลว์ (OpenFlow), ไวร์ชาร์ก (Wireshark) และคอนโทรลเลอร์ POX ใบแลปแนะนำอันนี้ |
-nfv | ติดตั้งเฉพาะ มินิเน็ต, โอเพนโฟลว์ และโอเพนวีสวิตซ์ |
-s mydir | กำหนดตำแหน่งในการติดตั้ง |
modern@ubuntu:~$ ./mininet/util/install.sh -nfv
Detected Linux distribution: Ubuntu 18.04 bionic amd64
sys.version_info(major=2, minor=7, micro=17, releaselevel=final, serial=0)
Detected Python (python) version 2
Installing Mininet dependencies
[sudo] password for modern:ใบแลปย้ำว่า แนะนำให้ใช้ -a เพื่อให้ใช้ Open vSwitch, OpenFlow, Wireshark และคอนโทรลเลอร์ POX ได้ในบทถัดไป · และสำหรับ Ubuntu 18.04 ให้ติดตั้ง net-tools ด้วยเพื่อใช้คำสั่ง ifconfig
modern@ubuntu:~$ sudo apt install net-toolsบน Ubuntu รุ่นใหม่ (20.04 ขึ้นไป) แพ็กเกจ mininet อยู่ใน apt อยู่แล้ว และคอมไพล์มาสำหรับ arm64 เรียบร้อย — ไม่ต้องรัน install.sh ซึ่งบางขั้นยังสมมติว่าเป็น x86 อยู่
$ sudo apt update
$ sudo apt install -y mininet openvswitch-switch iperf3 net-tools ethtool
$ sudo mn --version # ดูว่าลงสำเร็จ
$ sudo mn --test pingall # ต้องได้ *** Results: 0% dropped (2/2 received)ต้องมี iperf3 และ ethtool ด้วย — ตัวแรกใช้ในหัวข้อ 8.4 ตัวหลังใช้ปิด offload ก่อนวัดค่า (§3.8) ทั้งคู่ไม่ได้มากับ Mininet
3.5สร้างเน็ตเวิร์คผ่าน GUI (MiniEdit)
ใบแลปหัวข้อ 5 บอกว่ามินิเน็ตจัดเตรียมการใช้งานผ่าน GUI เพื่อให้สร้างเน็ตเวิร์คที่ต้องการได้โดยง่าย
modern@ubuntu:~/mininet$ sudo examples/miniedit.pyssh ubuntu เฉย ๆ
MiniEdit เขียนด้วย Tkinter คือโปรแกรมกราฟิกของลินุกซ์ ถ้า ssh ubuntu ธรรมดาแล้วสั่งรัน จะขึ้น _tkinter.TclError: no display name and no $DISPLAY environment variable
ทางที่ง่ายที่สุด: เปิดหน้าต่าง VM ของ Parallels แล้วรัน MiniEdit ในเดสก์ท็อปของ Ubuntu เอง · ทางเลือก: ลง XQuartz บน macOS แล้ว ssh -Y ubuntu ก่อน
แต่ในห้องสอบไม่ต้องใช้ MiniEdit เลย — สร้าง topology ด้วยสคริปต์ Python เร็วกว่าและไม่พึ่ง GUI → §3.10
ส่วนประกอบสำคัญที่ใบแลประบุไว้ 7 อย่าง
| # | ปุ่ม | ใช้ทำอะไร |
|---|---|---|
| 1 | Select | สำหรับเลื่อนหรือลบอุปกรณ์ |
| 2 | Host | สำหรับสร้างโฮสต์ (h1, h2, …) |
| 3 | Switch | สำหรับใช้งานโอเพนโฟลว์สวิตซ์ (ต้องมีคอนโทรลเลอร์) |
| 4 | Legacy switch | สำหรับสวิตซ์ปกติ — เรียนรู้ MAC เองเหมือนสวิตช์ทั่วไป ไม่ต้องมีคอนโทรลเลอร์ |
| 5 | Link | สำหรับเชื่อมต่ออุปกรณ์ — ลากจากอุปกรณ์หนึ่งไปอีกอุปกรณ์หนึ่ง |
| 6 | Run | เริ่มการทำงานของโปรแกรมเลียนแบบ |
| 7 | Stop | หยุดการทำงานของโปรแกรมเลียนแบบ |
5.1 เน็ตเวิร์คอย่างง่าย
เมื่อสร้างเน็ตเวิร์คแล้ว กำหนด IP address ให้แต่ละโหนดได้ 2 วิธี
① กำหนดแอดเดรสเอง (ทีละโหนด)
คลิกขวาที่โหนดนั้น → Properties → กรอกช่อง IP Address เช่น 192.168.1.1/24
② กำหนดหมายเลขแบบอัตโนมัติ (ทั้งวง)
เมนู Edit → Preferences → ช่อง IP Base ค่าดีฟอลต์คือ 10.0.0.0/8 ให้เปลี่ยนเป็นที่ต้องการ (ใบแลปกำหนดเป็น 192.168.1.0/24)
/24 ต่อท้ายด้วย)
mn
ช่อง IP Base ในหน้า Preferences คือของอย่างเดียวกับแฟล็ก --ipbase ของคำสั่ง mn · ฉะนั้น sudo mn --ipbase 192.3.128.0/24 ให้ผลเหมือนกับการไปเปลี่ยนช่องนี้ใน GUI — ในห้องสอบใช้แฟล็กเร็วกว่ามาก
3.6การเรียกชื่อโฮสต์/สวิตซ์ และสิ่งที่เกิดขึ้นข้างใน
โฮสต์
แต่ละโฮสต์ที่สร้างในมินิเน็ตจะมีเนมสเปซ (network namespace) ของตนเองพร้อมเวอร์ชวลอินเตอร์เฟซ โดยทั่วไปใช้ชื่อ h1..hN — โฮสต์ 1 มีอินเตอร์เฟซ h1-eth0 โฮสต์ 2 มี h2-eth0
การตั้งค่าอินเตอร์เฟซต้องผ่านทางเนมสเปซของโฮสต์นั้นเท่านั้น
สวิตซ์
กำหนดชื่อ s1..sN โดยอินเตอร์เฟซแรกเป็น s1-eth1 และอินเตอร์เฟซที่ 2 เป็น s1-eth2 · หากมีสวิตซ์ใหม่ (s2) จะเป็น s2-eth1 และ s2-eth2
การเข้าถึงอินเตอร์เฟซของสวิตซ์ทำผ่าน "root" namespace ได้เลย
mn อยู่ใน root namespace ส่วนโฮสต์แต่ละตัวอยู่ใน namespace แยก เชื่อมกันด้วย veth pairs)เพราะ h1-eth0 ไม่มีตัวตนใน Ubuntu ปกติ — มันอยู่ในเนมสเปซของ h1 เท่านั้น ถ้าเปิดเทอร์มินัลของ Ubuntu แล้วพิมพ์ sudo tc qdisc add dev h1-eth0 … ตรง ๆ จะได้ Cannot find device "h1-eth0" · ต้องสั่งผ่าน Mininet CLI (mininet> h1 tc …) หรือใน xterm ของ h1 เท่านั้น · ลองพิสูจน์ด้วย ip -br a ใน Ubuntu จะเห็นแต่ s1-eth1, s1-eth2 ที่อยู่ใน root namespace ไม่เห็น h1-eth0 เลย
3.7ทดสอบเน็ตเวิร์คที่สร้างขึ้น
ใบแลปหัวข้อ 5.3 — หลังจากสร้างเน็ตเวิร์คที่ต้องการ ให้ไปที่เมนู Run หรือคลิกปุ่ม Run
จากนั้นไปที่โฮสต์ h1 และ h2 คลิกขวา → Terminal เพื่อเรียกใช้คำสั่งต่าง ๆ
root@ — ในเทอร์มินัลของโฮสต์คือ root อยู่แล้ว ไม่ต้องพิมพ์ sudo)
ifconfig (มีแค่ 2 อินเตอร์เฟซ: h1-eth0 กับ lo เพราะอยู่คนละ namespace กับเครื่องจริง)การตรวจสอบการเชื่อมต่อทำได้โดยใช้คำสั่ง ping ตามด้วย IP address ของโหนดปลายทาง
อ่านผล ping ให้เป็น — ตัวไหนคือ delay ตัวไหนคือ jitter ตัวไหนคือ loss
--- 192.3.128.3 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5126ms
rtt min/avg/max/mdev = 0.047/0.127/0.206/0.051 ms
# ↑ ↑ ↑ ↑
# เร็วสุด avg = DELAY ช้าสุด mdev = JITTER| อยากได้ค่าอะไร | ดูตัวเลขไหน | อธิบาย |
|---|---|---|
| Delay (RTT) | avg ในบรรทัด rtt min/avg/max/mdev | เวลาเฉลี่ยไป-กลับของทุกแพ็กเก็ตที่ได้คำตอบ · นี่คือค่าที่ใบแลปสั่งให้บันทึก ในข้อ 8.1 |
| Jitter | mdev ตัวสุดท้าย | ความแปรปรวนของ RTT ในชุดนี้ · ยิ่งมากยิ่งไม่สม่ำเสมอ · ping ไม่ได้พิมพ์คำว่า "jitter" ตรง ๆ ต้องอ่านจาก mdev |
| Packet Loss | % packet loss ในบรรทัดก่อนหน้า | คิดจาก (transmitted − received) / transmitted · จะแม่นก็ต่อเมื่อยิงแพ็กเก็ตเยอะพอ (ใบแลปจึงสั่ง -c 150) |
| min / max | ตัวแรกและตัวที่สาม | ใช้ดูว่าค่ากระจายกว้างแค่ไหน · ช่วง max − min กว้างมาก = jitter สูง |
mdev ไม่เท่ากับตัวเลข jitter ที่สั่ง netem
ตั้ง delay 100ms 10ms แล้วคาดว่าจะเห็น mdev = 10 — ไม่ใช่ · 10ms ที่ใส่คือครึ่งความกว้างของช่วงสุ่ม (แต่ละแพ็กเก็ตหน่วงสุ่มระหว่าง 90–110 ms) ส่วน mdev คือส่วนเบี่ยงเบนของค่าเหล่านั้น ซึ่งจะได้ราว ๆ 5–6 ms ไม่ใช่ 10 · ดูภาพเคลื่อนไหวใน §3.8 ประกอบ
3.8Traffic Control (tc/netem)
Traffic Control (tc) เป็นยูทิลิตีของลินุกซ์ที่ใช้กำหนดค่า Packet Scheduler ของ Kernel ทำให้สามารถจำลองสภาวะเน็ตเวิร์คที่หลากหลาย เช่น การหน่วงเวลา การสูญหายของแพ็กเก็ต และการจำกัด Bandwidth
sudo tc qdisc [add|del|replace|change|show] dev dev_id root netem opts| ส่วนของคำสั่ง | คืออะไร |
|---|---|
sudo | รันคำสั่งด้วยสิทธิ์ผู้ดูแลระบบ (ใน Mininet CLI และใน xterm ของโฮสต์เป็น root อยู่แล้ว จะพิมพ์หรือไม่ก็ได้) |
tc | คำสั่งสำหรับจัดการ NETEM |
qdisc | queue discipline คือกฎที่กำหนดลำดับการส่งแพ็กเก็ตที่มาจาก IP protocol output |
add | del | replace | change | show | การกระทำต่อ qdisc — add เพื่อเพิ่ม delay, change/del เพื่อเปลี่ยนหรือลบ delay |
dev_id | อินเตอร์เฟซที่ต้องการจำลองสภาวะ เช่น h1-eth0 |
root | ติดกฎไว้ที่รากของคิวขาออก (egress) ของอินเตอร์เฟซนั้น |
netem | Network Emulator — โมดูลที่ทำหน้าที่หน่วง/ทิ้ง/ทำซ้ำแพ็กเก็ต |
opts | ค่าของ delay, packet loss, duplication, corruption และอื่น ๆ |
6.1 การเพิ่มค่าต่าง ๆ — คำสั่งครบชุดตามใบแลป
# ── เพิ่ม Delay 100 ms (add) ─────────────────────────────
sudo tc qdisc add dev h1-eth0 root netem delay 100ms
# ── แก้ไขค่าเดิมเป็น 50 ms (change) — ไม่ต้องลบก่อน ──────
sudo tc qdisc change dev h1-eth0 root netem delay 50ms
# ── ลบค่าที่ติดตั้งทั้งหมด (del) ─────────────────────────
sudo tc qdisc del dev h1-eth0 root netem
# ── เพิ่ม Jitter ±10 ms (delay 100 ms, jitter 10 ms) ────
sudo tc qdisc add dev h1-eth0 root netem delay 100ms 10ms
# ── เพิ่ม Packet Loss 10% ────────────────────────────────
sudo tc qdisc add dev h1-eth0 root netem loss 10%
# ── ตรวจว่าติดจริงไหม (ส่วนขยาย — ควรทำทุกครั้ง) ────────
sudo tc qdisc show dev h1-eth0
# qdisc netem 8001: root refcnt 2 limit 1000 delay 100ms 10ms| คำสั่งย่อย | ใช้ตอนไหน | ข้อควรระวัง |
|---|---|---|
add | ยังไม่มี qdisc อยู่บน interface นั้น | ถ้ามีอยู่แล้วจะขึ้น RTNETLINK answers: File exists → ใช้ change หรือ del ก่อน |
change | มี qdisc อยู่แล้วและอยากเปลี่ยนค่า | ถ้ายังไม่มีจะขึ้น No such file or directory |
replace | ไม่อยากคิดว่ามีอยู่หรือยัง ปลอดภัยที่สุด | ทำงานได้ทั้งสองกรณี — ในห้องสอบใช้อันนี้เลย |
del | ล้างค่าก่อนวัดรอบใหม่ | ถ้าไม่มีอะไรอยู่จะขึ้น No such file or directory — ไม่ใช่ error ร้ายแรง ข้ามได้ |
show | ยืนยันว่าค่าติดแล้ว | ถ้าเห็นแค่ qdisc noqueue หรือ qdisc fq_codel = netem ยังไม่ติด |
root ทำงานเฉพาะขาออก
กฎที่ติดด้วย root อยู่บนคิวขาออก (egress) ของ h1-eth0 เท่านั้น — ICMP echo request ที่ h1 ส่งออกไปจะโดนหน่วง 100 ms แต่ reply ที่วิ่งกลับเข้ามา ไม่โดนหน่วง
→ RTT ที่ ping รายงานจึงเพิ่มขึ้นราว 100 ms ไม่ใช่ 200 ms · ถ้าอยากให้ครบ 200 ms ต้องไปใส่ที่ปลายทางด้วย (h3 tc qdisc add dev h3-eth0 root netem delay 100ms)
--link tc,delay=100ms ให้ผลคนละเรื่องกับข้อสอบ
ถ้าสั่ง sudo mn --topo … --link tc,delay=100ms มินิเน็ตจะใส่ netem ให้ ปลายทั้งสองข้างของทุกลิงก์ · เส้นทาง h1→h3 ผ่าน 3 ลิงก์ ไป-กลับจึงโดนหน่วง 6 ครั้ง = 600 ms ไม่ใช่ 100 ms
ข้อสอบสั่งว่า "ใส่ delay บน h1-eth0" → ต้องใช้ tc ใส่เองที่ interface เดียว ห้ามใช้ --link tc,delay=
การ์ดและไดรเวอร์สมัยใหม่มีฟีเจอร์ TSO / GSO / GRO ที่รวมแพ็กเก็ตหลายใบเป็นก้อนใหญ่ก้อนเดียว (ได้ถึง 64 KB) ก่อนส่งให้เคอร์เนล — netem จึงเห็นเป็น "1 แพ็กเก็ต" แล้วหน่วง/ทิ้งทั้งก้อน ทำให้ค่า delay และ loss ที่วัดได้ไม่ตรงกับที่ตั้งไว้
mininet> h1 ethtool -K h1-eth0 tso off gso off gro off
mininet> h3 ethtool -K h3-eth0 tso off gso off gro offถ้าทำบนการ์ดจริงใน Ubuntu VM (หัวข้อ 8.5) ชื่อ interface จะเป็นแบบ enxaca7f1a9ff44 ไม่ใช่ eth0
$ ip -br a # หาชื่อจริงก่อนเสมอ
$ IF=enxaca7f1a9ff44
$ sudo ethtool -K $IF tso off gso off gro offเจาะลึก jitter — ทำไม mdev ถึงไม่ใช่ 10
delay 100ms 10ms ทำให้ netem สุ่มค่าหน่วงแบบสม่ำเสมอ (uniform) ในช่วง 90–110 ms · ค่าเบี่ยงเบนมาตรฐานของการแจกแจงสม่ำเสมอที่มีครึ่งความกว้าง a คือ a/√3
อยากให้กระจายแบบโค้งระฆังเหมือนเน็ตจริงมากกว่า ให้เติม distribution normal ต่อท้าย · อยากให้ค่าติดกันเป็นช่วง ๆ (correlation) เติมเปอร์เซ็นต์ตัวที่สาม เช่น delay 100ms 10ms 25%
mininet> h1 tc qdisc replace dev h1-eth0 root netem delay 100ms 10ms distribution normalicmp_seq สลับที่
netem สุ่มเวลาหน่วงให้แต่ละแพ็กเก็ตแยกกัน แพ็กเก็ตที่ได้เลขน้อยจึงแซงแพ็กเก็ตที่ได้เลขมากได้ — ใน ping จะเห็น icmp_seq ไม่เรียง เช่น 4, 6, 5, 7 · นี่คืออาการปกติของ jitter ไม่ใช่ของเสีย และเป็นเหตุผลว่าทำไม jitter ถึงทำร้ายแอปเรียลไทม์ (ต้องเรียงลำดับใหม่ก่อนเล่น)
3.9Iperf3
Iperf3 เป็นเครื่องมือวัดและทดสอบประสิทธิภาพของเครือข่าย โดยเฉพาะความเร็วของการส่งและรับข้อมูล พัฒนาโดยกลุ่มวิศวกรรมคอมพิวเตอร์ที่มหาวิทยาลัย California เป็นซอฟต์แวร์โอเพนซอร์ส ทดสอบได้ทั้งแบบทิศทางเดียวหรือสองทิศทาง บน TCP หรือ UDP และกำหนดระยะเวลา ขนาดข้อมูล และพารามิเตอร์อื่น ๆ ได้ตามต้องการ ทำงานในรูปแบบไคลเอนต์ (-c) และเซิร์ฟเวอร์ (-s)
iperf3 -s ค้างไว้ก่อน แล้วฝั่งขวาถึงจะต่อได้ · ตัวเลข 44.5 Gbits/sec คือ throughput ของลิงก์เสมือนที่ไม่ได้จำกัดอะไรเลย)iperf3 [-s | -c] [ options ]
# ── ฝั่งเซิร์ฟเวอร์ ─────────────────────────────
iperf3 -s
# ── ฝั่งไคลเอนต์ (เซิร์ฟเวอร์อยู่ที่ 10.0.0.2) ──
iperf3 -c 10.0.0.2
# ── ไคลเอนต์ ทดสอบเป็นเวลา 5 วินาที ────────────
iperf3 -c 10.0.0.2 -t 5ผลลัพธ์ที่ได้ประกอบด้วย 6 คอลัมน์ตามที่ใบแลประบุ
| คอลัมน์ | ความหมายตามใบแลป | ใช้ตอบอะไรในการทดลอง |
|---|---|---|
ID | หมายเลขการเชื่อมต่อ | ไม่ต้องสนใจ ถ้าเปิดสตรีมเดียวจะมีเลขเดียว |
Interval | ช่วงเวลาการแสดงผล | บรรทัดสุดท้ายที่เขียน 0.00-5.00 sec คือสรุปรวม — ใช้บรรทัดนี้กรอกตาราง |
Transfer | ปริมาณข้อมูลที่ส่งในช่วงเวลานั้น | ช่องที่ 1 ของตารางที่ 1 |
Bitrate | ทรูพุต (throughput) ที่ได้ | ช่องที่ 2 ของตารางที่ 1 — ตัวเลขหลักที่ต้องเทียบทุกกรณี |
Retr | จำนวนแพ็กเก็ตที่ส่งใหม่ (retransmission) | ช่องที่ 3 ของตารางที่ 1 — ตัวชี้วัดว่ามี loss เกิดขึ้นจริง ยิ่ง loss สูง Retr ยิ่งพุ่ง |
Cwnd | ขนาดของ congestion window (เฉพาะ TCP) | ดูได้โดยตรงว่า Congestion Control หด window ลงจริงไหมเมื่อมี loss |
iperf3 -s จะค้างรอไปเรื่อย ๆ ถ้าพิมพ์ใน Mininet CLI ตรง ๆ จะกด Ctrl-C ออกยาก · ให้ใส่ -D (daemon) หรือ & ต่อท้าย แล้วค่อยสั่งฝั่งไคลเอนต์
mininet> h2 iperf3 -s -D # เปิดเซิร์ฟเวอร์ค้างไว้เบื้องหลัง
mininet> h1 iperf3 -c 192.3.128.2 -t 5 # ยิงจาก h1 ไปหา h2 นาน 5 วินาที
mininet> h2 pkill iperf3 # ปิดเซิร์ฟเวอร์เมื่อเลิกใช้3.10การทดลอง — โทโพโลยีตามรูปที่ 17
ใบแลปหัวข้อ 8 เขียนสั้น ๆ ว่า "จากรูปที่ 17 ให้นักศึกษาสร้างเน็ตเวิร์คและทดสอบการตั้งค่าต่อไปนี้" — รูปนี้คือโจทย์ทั้งข้อ และเป็นรูปเดียวกับที่ข้อสอบข้อ 4 อ้างถึง
h1-eth0 (ทดสอบ delay/jitter/loss) ในรูปหมายถึงอินเตอร์เฟซของ h1 คือจุดที่จะติด netem ไม่ใช่ชื่อของสายระหว่างสวิตช์| สิ่งที่ต้องสร้าง | จำนวน | รายละเอียด |
|---|---|---|
| โฮสต์ (Host) | 4 | h1, h2 อยู่ฝั่งซ้าย · h3, h4 อยู่ฝั่งขวา |
| สวิตช์ (Switch) | 2 | s1 ฝั่งซ้าย · s2 ฝั่งขวา |
| ลิงก์ (Link) | 5 | h1–s1 · h2–s1 · h3–s2 · h4–s2 · s1–s2 (เส้นกลางที่เชื่อมสองฝั่งเข้าด้วยกัน) |
| Router | 0 | ทุกโหนดอยู่วง 192.3.128.0/24 เดียวกัน → ไม่ต้องมี router ไม่ต้องตั้ง gateway |
| Controller | 0 | ใช้สวิตช์แบบ failMode=standalone ให้ทำงานเป็นสวิตช์เรียนรู้ MAC ธรรมดา → §3.19 |
วิธีที่ 1 — สคริปต์ Python แนะนำสำหรับห้องสอบ
วิธีนี้ดีที่สุดเพราะได้ชื่อโหนดเป็น h1–h4 เป๊ะตามรูป จึงมี h1-eth0 ให้ใส่ netem ตามที่โจทย์สั่ง และตั้ง IP ตามรหัสนักศึกษาไปในตัว · ก็อปทั้งบล็อกนี้วางในเทอร์มินัลได้เลย มันจะสร้างไฟล์ให้เอง
lab3.pycat > ~/lab3.py <<'EOF'
#!/usr/bin/env python3
# Lab 3 — topology ตามรูปที่ 17 : h1,h2 -- s1 -- s2 -- h3,h4
from mininet.net import Mininet
from mininet.node import OVSKernelSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel
def run():
net = Mininet(controller=None, switch=OVSKernelSwitch, autoSetMacs=True)
# ── โฮสต์ 4 ตัว · IP จากรหัส 673040128-3 → 192.3.128.0/24 ──
h1 = net.addHost('h1', ip='192.3.128.1/24')
h2 = net.addHost('h2', ip='192.3.128.2/24')
h3 = net.addHost('h3', ip='192.3.128.3/24')
h4 = net.addHost('h4', ip='192.3.128.4/24')
# ── สวิตช์ 2 ตัว · standalone = ทำงานเองได้ ไม่ต้องมี controller ──
s1 = net.addSwitch('s1', failMode='standalone')
s2 = net.addSwitch('s2', failMode='standalone')
# ── ลิงก์ 5 เส้น · ลำดับนี้ทำให้ได้ h1-eth0 และ s1-eth1..3 ──
net.addLink(h1, s1) # h1-eth0 <-> s1-eth1
net.addLink(h2, s1) # h2-eth0 <-> s1-eth2
net.addLink(h3, s2) # h3-eth0 <-> s2-eth1
net.addLink(h4, s2) # h4-eth0 <-> s2-eth2
net.addLink(s1, s2) # s1-eth3 <-> s2-eth3
net.start()
# ปิด offload ทุกโฮสต์ ไม่งั้น netem วัดค่าเพี้ยน
for h in (h1, h2, h3, h4):
h.cmd('ethtool -K %s-eth0 tso off gso off gro off' % h.name)
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel('info')
run()
EOF$ sudo mn -c # ล้างของค้างจากรอบก่อนเสมอ
$ sudo python3 ~/lab3.py
# *** Adding hosts: h1 h2 h3 h4
# *** Adding switches: s1 s2
# *** Adding links: (h1, s1) (h2, s1) (h3, s2) (h4, s2) (s1, s2)
# *** Starting CLI:
mininet>วิธีที่ 2 — คำสั่ง mn บรรทัดเดียว
$ sudo mn --topo linear,2,2 --controller none \
--switch ovsk,failMode=standalone --ipbase 192.3.128.0/24 --maclinear,2,2 ตั้งชื่อโฮสต์ไม่เหมือนรูป
--topo linear,k,n = สวิตช์ k ตัวเรียงกัน แต่ละตัวมีโฮสต์ n ตัว → รูปร่างตรงกับรูปที่ 17 พอดี แต่เมื่อ n มากกว่า 1 มินิเน็ตจะตั้งชื่อโฮสต์เป็น h1s1, h2s1, h1s2, h2s2 ไม่ใช่ h1–h4
ผลคือ ไม่มีอินเตอร์เฟซชื่อ h1-eth0 — พอสั่ง tc … dev h1-eth0 จะได้ Cannot find device "h1-eth0" ซึ่งเป็นสิ่งที่ข้อสอบสั่งตรง ๆ
→ ในห้องสอบใช้วิธีที่ 1 (สคริปต์ Python) · ถ้าจำเป็นต้องใช้วิธีนี้จริง ๆ ให้เปลี่ยนคำสั่งเป็น dev h1s1-eth0 แทน
วิธีที่ 3 — MiniEdit (GUI)
วางไอคอน Host 4 ตัว, Legacy switch 2 ตัว แล้วลาก Link 5 เส้นตามรูป · ตั้ง IP ทีละตัวด้วยคลิกขวา → Properties หรือเปลี่ยน IP Base ที่ Edit → Preferences ก่อน แล้วกด Run · ต้องมีหน้าจอกราฟิก ดูข้อจำกัดของ Mac ที่ §3.5
ตรวจว่าโทโพโลยีถูกก่อนไปต่อ
mininet> net
# h1 h1-eth0:s1-eth1
# h2 h2-eth0:s1-eth2
# h3 h3-eth0:s2-eth1
# h4 h4-eth0:s2-eth2
# s1 lo: s1-eth1:h1-eth0 s1-eth2:h2-eth0 s1-eth3:s2-eth3
# s2 lo: s2-eth1:h3-eth0 s2-eth2:h4-eth0 s2-eth3:s1-eth3
mininet> dump
# <Host h1: h1-eth0:192.3.128.1 pid=...> ← ตรวจว่า IP ถูกทุกตัว
mininet> pingall
# *** Results: 0% dropped (12/12 received) ← 4 โฮสต์ = 4x3 = 12 คู่pingall ยิงจากทุกโหนดไปทุกโหนดที่เหลือ — โฮสต์ 4 ตัว ได้ 4 × 3 = 12 คู่ · ถ้าเห็น 0% dropped (12/12 received) แปลว่าข้อกำหนด "ping ได้ทุกโหนด" ของข้อสอบผ่านแล้ว ให้ถ่ายรูป/คัดลอกบรรทัดนี้เก็บไว้ทันที
พิมพ์ h1 ping -c 4 h3 ได้เลย ไม่ต้องจำ IP — CLI จะแทน h3 ด้วย 192.3.128.3 ให้อัตโนมัติ · แต่ในรายงานควรเขียน IP เต็ม เพื่อให้เห็นว่าตั้ง IP ตามรหัสนักศึกษาจริง
3.11การทดลอง 8.1 — ทดสอบ Delay
ใบแลปสั่งไว้ 7 ขั้น ทำตามลำดับนี้แล้วบันทึกค่าทุกครั้ง
- กำหนด IP address ของเน็ตเวิร์คตามหมายเลขรหัสนักศึกษา — ทำไปแล้วในสคริปต์ (
192.3.128.1–.4) - ตรวจสอบข้อมูลอินเตอร์เฟซของทุกโหนดด้วย
ifconfig[mininet>]mininet> h1 ifconfig mininet> h2 ifconfig mininet> h3 ifconfig mininet> h4 ifconfig # ต้องเห็น h1-eth0 มี inet 192.3.128.1 netmask 255.255.255.0 (เทียบรูปที่ 14) # ถ้าไม่มี net-tools ให้ใช้ h1 ip -br a แทน ได้ผลเหมือนกัน - ping จาก h1 ไป h3 — บันทึก min/avg/max/mdev baseline
[mininet>] — ก่อนใส่ netem
mininet> h1 ping -c 10 192.3.128.3 # --- 192.3.128.3 ping statistics --- # 10 packets transmitted, 10 received, 0% packet loss, time 9200ms # rtt min/avg/max/mdev = 0.047/0.127/0.206/0.051 ms ← ระดับที่ควรเห็น - ping จาก h2 ไป h4 — บันทึกค่า
[mininet>]
mininet> h2 ping -c 10 192.3.128.4 - เพิ่ม delay ที่
h1-eth0เป็น 100 ms แล้ว ping h1 → h3 อีกครั้ง[mininet>] — หัวใจของข้อสอบข้อ 4(a)mininet> h1 tc qdisc add dev h1-eth0 root netem delay 100ms mininet> h1 tc qdisc show dev h1-eth0 # ยืนยันว่าติดแล้ว mininet> h1 ping -c 10 192.3.128.3 # rtt min/avg/max/mdev = 100.0/100.1/100.3/0.08 ms ← เพิ่มขึ้น ~100 ไม่ใช่ ~200 - ping h1 → h3 พร้อมกับ ping h2 → h3 ในเวลาเดียวกัน แล้วเทียบกับข้อ 3
[mininet>] — ใส่ & ให้ตัวแรกวิ่งเบื้องหลัง
mininet> h2 ping -c 20 192.3.128.3 > /tmp/h2.txt & mininet> h1 ping -c 20 192.3.128.3 mininet> h2 cat /tmp/h2.txt # อ่านผลของ h2 ทีหลัง - ลบค่า delay ที่ตั้งไว้ทั้งหมด
[mininet>] — ต้องทำก่อนเริ่มข้อ 8.2 เสมอ
mininet> h1 tc qdisc del dev h1-eth0 root netem mininet> h1 tc qdisc show dev h1-eth0 # ต้องไม่เหลือ netem แล้ว
คำถามท้ายข้อ 8.1
1. ค่า delay พื้นฐาน (ไม่ตั้งค่าใด ๆ) ที่วัดได้ระหว่าง h1–h3 ใกล้เคียง 0 ms หรือไม่ เพราะเหตุใด
ใกล้ 0 มาก แต่ไม่เป็น 0 พอดี — จากรูปที่ 15 ของใบแลปเองค่า avg อยู่ที่ 0.127 ms คือระดับเศษหนึ่งส่วนสิบของมิลลิวินาที
เพราะเหตุใดถึงเกือบ 0 — Mininet ไม่มีสายจริง ทุกลิงก์เป็น veth pair ในหน่วยความจำของเครื่องเดียวกัน ฉะนั้นเมื่อเทียบกับสูตรความหน่วงในหัวข้อ 2.1
- Propagation delay ≈ 0 — ระยะทาง
dเป็นศูนย์ ไม่มีสายให้สัญญาณวิ่ง - Transmission delay ≈ 0 —
Rคือความเร็วของหน่วยความจำ ระดับหลายสิบ Gbit/s (รูปที่ 16 วัดได้ 44.5 Gbit/s) - Queuing delay ≈ 0 — ping ยิงแค่ 1 แพ็กเก็ต/วินาที ไม่มีคิว
เพราะเหตุใดถึงไม่เป็น 0 เป๊ะ — ยังเหลือ Processing delay จริง ๆ อยู่ คือเวลาที่เคอร์เนลใช้สลับ network namespace, คัดลอกแพ็กเก็ตข้าม veth, ให้ Open vSwitch ตัดสินใจส่งต่อ และปลุกโปรเซส ping ขึ้นมาอ่านคำตอบ — งานพวกนี้กินเวลาระดับไมโครวินาทีถึงร้อยไมโครวินาที จึงได้ตัวเลข 0.05–0.2 ms
2. เมื่อเพิ่ม delay 100 ms บน h1-eth0 ค่า RTT ที่วัดได้จาก ping ควรมีค่าประมาณเท่าใด (คำนวณและเปรียบเทียบกับผลจริง)
คำตอบ: ประมาณ 100 ms (ไม่ใช่ 200 ms)
root หน่วงเฉพาะขาออกของ h1-eth0
เหตุผล — qdisc ที่ติดด้วยคำว่า root อยู่บนคิวขาออก (egress) ของ h1-eth0 เท่านั้น
- ICMP echo request ออกจาก h1 → โดนหน่วง 100 ms
- ICMP echo reply จาก h3 วิ่งกลับเข้า h1-eth0 (ingress) → ไม่โดนหน่วง
รวมไป-กลับจึงโดนหน่วงแค่ครั้งเดียว = +100 ms
ถ้าอยากได้ 200 ms จริง ๆ ต้องใส่ที่ปลายทางด้วย: h3 tc qdisc add dev h3-eth0 root netem delay 100ms — คราวนี้ reply ก็โดนหน่วงด้วย รวมเป็น 200 ms
3. การ ping พร้อมกันจาก h1 และ h2 ไปยัง h3 ทำให้เกิด queuing delay เพิ่มขึ้นหรือไม่ สังเกตได้จากอะไร
ทางทฤษฎีเกิด แต่ในทางปฏิบัติบน Mininet มักวัดแทบไม่ได้
สังเกตได้จาก ตัวเลข avg, max และ mdev ที่สูงขึ้นเมื่อเทียบกับตอน ping ตัวเดียว โดยเฉพาะ max ที่จะโดดขึ้นเป็นบางแพ็กเก็ต (แพ็กเก็ตที่บังเอิญมาต่อคิวหลังแพ็กเก็ตของอีกฝั่งพอดี)
ทำไมถึงมักไม่ขยับ — จากสูตรในหัวข้อ 2.1 queuing delay เกิดเมื่ออัตราขาเข้าเกินอัตราขาออก · แต่ ping ยิงแค่ 1 แพ็กเก็ต × 64 ไบต์ ต่อวินาที สองเครื่องรวมกันก็ราว 1 kbit/s ขณะที่ลิงก์ veth วิ่งได้หลายสิบ Gbit/s → โหลดต่ำกว่าความจุประมาณ 7 หลัก คิวจึงว่างตลอด
มี 2 ทาง ① บีบความจุลิงก์ ตอนสร้าง topology (net.addLink(h1, s1, cls=TCLink, bw=1) = 1 Mbit/s) ② อัดโหลดให้เต็มลิงก์ ด้วย h2 iperf3 -c 192.3.128.3 -t 20 & แล้ว ping ไปพร้อมกัน — จะเห็น avg และ max พุ่งขึ้นชัดเจน นี่คือ bufferbloat ที่หนังสือพูดถึง
3.12การทดลอง 8.2 — ทดสอบ Jitter
- เพิ่ม delay 100 ms และ jitter 10 ms ที่
h1-eth0แล้ว ping h1 → h3[mininet>] — คำสั่งตรงกับข้อสอบข้อ 4(a) เป๊ะ ๆmininet> h1 tc qdisc add dev h1-eth0 root netem delay 100ms 10ms mininet> h1 tc qdisc show dev h1-eth0 # qdisc netem 8001: root refcnt 2 limit 1000 delay 100ms 10ms # ↑ ↑ # delay jitter mininet> h1 ping -c 20 192.3.128.3 # rtt min/avg/max/mdev = 90.3/100.4/109.8/5.8 ms # ↑ ↑ ↑ # ~ 100-10 ~100+10 jitter ที่วัดได้ - ping h1 → h3 พร้อมกับ ping h2 → h3 เปรียบเทียบผลกับข้อที่แล้ว
[mininet>]
mininet> h2 ping -c 20 192.3.128.3 > /tmp/h2j.txt & mininet> h1 ping -c 20 192.3.128.3 mininet> h2 cat /tmp/h2j.txtคาดหวัง: h2 แทบไม่เปลี่ยน เพราะ netem อยู่ที่
h1-eth0ไม่ได้อยู่ที่h2-eth0— เป็นการยืนยันว่ากฎtcผูกกับ interface ตัวเดียว ไม่ใช่กับทั้งเน็ตเวิร์ค - ลบค่าเดิมทั้งหมด
[mininet>]
mininet> h1 tc qdisc del dev h1-eth0 root netem
คำถามท้ายข้อ 8.2
1. ค่า mdev (mean deviation) ที่ได้จาก ping สัมพันธ์กับค่า jitter ที่กำหนดไว้อย่างไร
สัมพันธ์กันแบบแปรผันตรง แต่ตัวเลขไม่เท่ากัน — mdev จะได้ประมาณครึ่งหนึ่งของค่า jitter ที่ตั้ง
10msที่ใส่ให้ netem = ครึ่งความกว้างของช่วงสุ่ม → แต่ละแพ็กเก็ตถูกหน่วงด้วยค่าสุ่มระหว่าง 90–110 msmdevที่ ping รายงาน = ค่าเบี่ยงเบนของ RTT ทั้งชุด ซึ่งของการแจกแจงสม่ำเสมอกว้าง ±10 ms จะได้ 10/√3 ≈ 5.8 ms
ทดสอบความสัมพันธ์ได้ — ตั้ง jitter เป็น 2 เท่า (delay 100ms 20ms) แล้ว mdev จะขึ้นเป็น 2 เท่าตาม (~11.5 ms) · ส่วน max − min จะเข้าใกล้ 2 × jitter = 20 ms
สรุปคำตอบที่เขียนลงรายงานได้เลย: "mdev แปรผันตรงกับค่า jitter ที่กำหนด แต่มีค่าประมาณ 0.58 เท่า (1/√3) เพราะ netem สุ่มค่าหน่วงแบบสม่ำเสมอในช่วง ±jitter ขณะที่ mdev คือส่วนเบี่ยงเบนของค่าเหล่านั้น ไม่ใช่ความกว้างของช่วง"
2. หากเป็นแอปพลิเคชันแบบเรียลไทม์ เช่น VoIP ค่า jitter ระดับ 10 ms จะส่งผลกระทบต่อคุณภาพเสียงอย่างไร
ระดับ 10 ms ยังถือว่ารับได้ ไม่ทำให้เสียงขาด เพราะโปรแกรม VoIP ทุกตัวมี jitter buffer คอยกันไว้อยู่แล้ว
กลไกที่เกิดขึ้น — VoIP ส่งเสียงเป็นแพ็กเก็ตเล็ก ๆ ทุก 20 ms และต้องเล่นออกลำโพงให้ต่อเนื่องพอดี ๆ เมื่อแพ็กเก็ตมาถึงไม่สม่ำเสมอ (ตามรูปที่ 2 ของใบแลป) ฝั่งรับจึงต้อง
- พักแพ็กเก็ตไว้ในบัฟเฟอร์ก่อน แล้วค่อยทยอยเล่น — ต้องพักนานอย่างน้อยเท่ากับ jitter ที่คาดไว้
- ผลข้างเคียงคือ ความหน่วงปลายทางเพิ่มขึ้น (บัฟเฟอร์ยิ่งใหญ่ ยิ่งกันกระตุกได้ดี แต่ยิ่งพูดสวนกันลำบาก)
- แพ็กเก็ตที่มาช้าเกินคิวเล่นจะถูกทิ้ง กลายเป็น loss ทั้งที่เน็ตเวิร์คส่งถึงแล้ว
ตัวเลขอ้างอิงที่เขียนลงรายงานได้ — เกณฑ์ที่นิยมใช้กันในอุตสาหกรรมคือ jitter ควร ต่ำกว่า 30 ms และ one-way delay ควรต่ำกว่า 150 ms · ที่ 10 ms จึงอยู่ในเกณฑ์ดี เสียงจะยังเรียบ แต่ถ้าดันขึ้นเป็น 50–100 ms จะเริ่มได้ยินเสียงกระตุก ขาดหาย หรือคำซ้อนกัน (เกณฑ์ตัวเลขนี้เป็นส่วนขยาย ไม่ได้อยู่ในใบแลป)
3.13การทดลอง 8.3 — ทดสอบ Packet Loss
- เพิ่มค่า loss ที่
h1-eth0เป็น 5%[mininet>]mininet> h1 tc qdisc add dev h1-eth0 root netem loss 5% - ping 150 ครั้งจาก h1 ไป h3 บันทึกอัตราการสูญหายจริง
[mininet>] — ใบแลปสั่ง
-c 150ตรง ๆmininet> h1 ping -c 150 192.3.128.3 # --- 192.3.128.3 ping statistics --- # 150 packets transmitted, 143 received, 4.67% packet loss, time 152300ms # ↑↑↑↑↑ ตัวเลขนี้คือคำตอบที่ต้องบันทึกเตือน:
ping -c 150แบบค่าเริ่มต้นยิงวินาทีละครั้ง = ใช้เวลา 150 วินาที · ถ้าเวลาไม่พอ ให้เติม-i 0.2(ยิงทุก 0.2 วินาที เหลือ 30 วินาที) — ส่วนขยาย ผลทางสถิติเหมือนกัน - เปลี่ยนเป็น 10% และ 15% แล้วเปรียบเทียบผล
[mininet>] — ใช้
changeไม่ต้องลบก่อนmininet> h1 tc qdisc change dev h1-eth0 root netem loss 10% mininet> h1 ping -c 150 -i 0.2 192.3.128.3 mininet> h1 tc qdisc change dev h1-eth0 root netem loss 15% mininet> h1 ping -c 150 -i 0.2 192.3.128.3 # ── ค่าที่ข้อสอบข้อ 4(b) สั่ง ── mininet> h1 tc qdisc change dev h1-eth0 root netem loss 20% mininet> h1 ping -c 150 -i 0.2 192.3.128.3 mininet> h1 tc qdisc del dev h1-eth0 root netem # ล้างก่อนไปข้อ 8.4
คำถามท้ายข้อ 8.3
1. อัตราการสูญหายจริงที่วัดได้จาก ping ใกล้เคียงกับค่าที่กำหนดไว้ใน tc/netem หรือไม่
ใกล้เคียงมาก แต่ไม่ตรงเป๊ะ และจะยิ่งใกล้เมื่อยิงแพ็กเก็ตมากขึ้น — นี่คือเหตุผลที่ใบแลปสั่งให้ ping -c 150 ไม่ใช่ -c 10
เพราะเหตุใด — netem ตัดสินใจทิ้งแพ็กเก็ตทีละใบแบบสุ่มอิสระ ด้วยความน่าจะเป็นที่ตั้งไว้ ผลรวมจึงเป็นการแจกแจงทวินาม (binomial) ค่าที่วัดได้จะแกว่งรอบค่าที่ตั้ง
| ตั้งไว้ | ยิง 10 ครั้ง | ยิง 150 ครั้ง |
|---|---|---|
| 5% | ได้ 0% หรือ 10% หรือ 20% เท่านั้น — ละเอียดสุดแค่ 10% | ได้ราว 3–8% ใกล้ 5% พอสมควร |
| 20% | ได้ 10–40% แกว่งมาก | ได้ราว 16–24% |
อีกเหตุผลที่ตัวเลขตรงพอดีกว่าที่คิด — netem อยู่ที่ ขาออก ของ h1 อย่างเดียว ทิ้งได้แค่ request ส่วน reply ที่วิ่งกลับเข้ามาไม่โดนทิ้ง · ถ้าโดนทั้งสองทางที่ 20% ค่าที่วัดจะเป็น 1 − (0.8 × 0.8) = 36% ไม่ใช่ 20%
2. เมื่อ loss เพิ่มจาก 5% เป็น 15% ค่า RTT เฉลี่ยเปลี่ยนแปลงหรือไม่ เพราะเหตุใด
แทบไม่เปลี่ยน — avg ยังอยู่ที่ระดับเดิม
เพราะเหตุใด — สองข้อ
- netem ทิ้งแพ็กเก็ตทิ้งไปเลย ไม่ได้ถ่วงเวลา — แพ็กเก็ตที่ถูกเลือกให้หาย จะหายทันทีที่ต้นทาง ไม่ได้ไปนั่งรอในคิวก่อน จึงไม่มี delay เพิ่มให้ใคร
pingคำนวณmin/avg/max/mdevจากแพ็กเก็ตที่ได้คำตอบกลับมาเท่านั้น — แพ็กเก็ตที่หายไม่มี RTT ให้เอามาเฉลี่ย จึงไม่ถูกนับ
สิ่งที่เปลี่ยนแทน คือตัวเลข received และ % packet loss เท่านั้น
ICMP ไม่สนใจว่าแพ็กเก็ตหาย แต่ TCP ต้องส่งซ้ำ — เวลาที่ผู้ใช้รู้สึกว่า "ช้า" จึงพุ่งขึ้นมหาศาลทั้งที่ RTT ของ ping ยังนิ่ง · ดูผลจริงในข้อ 8.4 ที่ค่า Retr จะพุ่งและ Bitrate จะตก
3.14การทดลอง 8.4 — ทดสอบด้วย Iperf3
ใบแลปสั่งให้ทดสอบ ระหว่าง h1 กับ h2 (ทั้งคู่อยู่ใต้ s1) แล้วสรุป Transfer, Bitrate และ Retr ของทุกกรณีลงในตารางเดียว
# ── เตรียม: เปิดเซิร์ฟเวอร์ที่ h2 ค้างไว้ครั้งเดียว ──────────────
mininet> h2 iperf3 -s -D
# ── ① baseline: ไม่กำหนดอะไรเลย ────────────────────────────────
mininet> h1 tc qdisc del dev h1-eth0 root netem # กันของค้าง (ไม่มีก็ไม่เป็นไร)
mininet> h1 iperf3 -c 192.3.128.2 -t 5
# ── ② delay 100 ms ─────────────────────────────────────────────
mininet> h1 tc qdisc replace dev h1-eth0 root netem delay 100ms
mininet> h1 iperf3 -c 192.3.128.2 -t 5
# ── ③ delay 100 ms + jitter 10 ms ──────────────────────────────
mininet> h1 tc qdisc replace dev h1-eth0 root netem delay 100ms 10ms
mininet> h1 iperf3 -c 192.3.128.2 -t 5
# ── ④ loss 1% ──────────────────────────────────────────────────
mininet> h1 tc qdisc replace dev h1-eth0 root netem loss 1%
mininet> h1 iperf3 -c 192.3.128.2 -t 5
# ── ⑤ loss 5% ──────────────────────────────────────────────────
mininet> h1 tc qdisc replace dev h1-eth0 root netem loss 5%
mininet> h1 iperf3 -c 192.3.128.2 -t 5
# ── ⑥ UDP (คำถามข้อ 3) ─────────────────────────────────────────
mininet> h1 iperf3 -c 192.3.128.2 -t 5 -u -b 100M
# ── ล้าง ───────────────────────────────────────────────────────
mininet> h1 tc qdisc del dev h1-eth0 root netem
mininet> h2 pkill iperf3อ่านผล iperf3 ให้เป็น
sender[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 5.18 GBytes 44.5 Gbits/sec 0 843 KBytes
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-5.00 sec 25.9 GBytes 44.5 Gbits/sec 0 sender
[ 5] 0.00-5.00 sec 25.9 GBytes 44.5 Gbits/sec receiver
# ↑ Transfer ↑ Bitrate ↑ Retr
# ช่องที่ 1 ช่องที่ 2 ช่องที่ 3 ของตารางiperf3 พิมพ์ผลรายวินาทีก่อน แล้วค่อยสรุปท้ายเป็น 2 บรรทัด (sender / receiver) · ให้จดจากบรรทัด sender เพราะเป็นบรรทัดเดียวที่มีคอลัมน์ Retr · อย่าจดบรรทัดรายวินาทีบรรทัดใดบรรทัดหนึ่งไปกรอกตาราง
คำถามท้ายข้อ 8.4
1. Throughput ลดลงมากที่สุดเมื่อเพิ่ม delay, jitter หรือ loss เพราะเหตุใด
เรียงจากกระทบมากไปน้อย: delay ≫ loss > jitter — และเหตุผลของแต่ละตัวไม่เหมือนกัน
| พารามิเตอร์ | ผลต่อ Bitrate | กลไก |
|---|---|---|
| delay 100 ms | ตกแรงที่สุด จากระดับ Gbit/s เหลือหลักร้อย Mbit/s หรือน้อยกว่า | TCP ส่งได้ไม่เกิน 1 หน้าต่างต่อ 1 RTT — พอ RTT โตจาก 0.13 ms เป็น 100 ms (770 เท่า) เพดานก็ตกลงตามสัดส่วนนั้นทันที โดยยังไม่มี loss สักแพ็กเก็ต · และช่วง slow start ก็ยาวขึ้น 770 เท่าด้วย |
| loss 1% → 5% | ตกซ้ำอีก และ Retr พุ่ง | ทุกครั้งที่มี loss TCP ตีความว่าเน็ตแออัด → หด Cwnd ลงครึ่งหนึ่ง แล้วค่อย ๆ ไต่ขึ้นใหม่ · จากสูตร Mathis throughput แปรผกผันกับ √Loss → loss เพิ่ม 5 เท่า throughput เหลือ 1/√5 ≈ 45% |
| jitter 10 ms | กระทบน้อยสุด | TCP ไม่สนใจว่าแพ็กเก็ตมาไม่สม่ำเสมอ ตราบใดที่ยังมาครบ · ผลที่มีคือ RTO ประมาณการยากขึ้นเล็กน้อย และแพ็กเก็ตสลับลำดับทำให้เกิด duplicate ACK บ้าง แต่ throughput แทบไม่ขยับ · (jitter จะไปทำร้าย VoIP แทน ดู 8.2) |
คำตอบสั้นที่เขียนลงรายงาน: "delay กระทบมากที่สุด เพราะ throughput ของ TCP ถูกจำกัดด้วย window/RTT โดยตรง ส่วน loss กระทบรองลงมาผ่านกลไก congestion control (แปรผกผันกับ √loss) และ jitter กระทบน้อยที่สุดเพราะ TCP ไม่ได้ต้องการความสม่ำเสมอของเวลามาถึง"
2. ผลที่ได้สอดคล้องกับสูตรความสัมพันธ์ระหว่าง Throughput, RTT และ Loss ในรูปที่ 3 หรือไม่ อธิบายเชิงปริมาณ
เอาสูตร Mathis มาแทนค่าแล้วเทียบกับที่วัดได้จริง
| กรณี | RTT | Loss | แทนค่า | ทำนาย |
|---|---|---|---|---|
| delay 100 ms + loss 1% | 0.1 s | 0.01 | 11680 / (0.1 × 0.100) | 1.17 Mbit/s |
| delay 100 ms + loss 5% | 0.1 s | 0.05 | 11680 / (0.1 × 0.224) | 0.52 Mbit/s |
เชิงปริมาณที่ตรวจสอบได้ง่ายที่สุด — loss เพิ่มจาก 1% เป็น 5% คือ 5 เท่า สูตรทำนายว่า throughput ควรเหลือ 1/√5 = 0.447 หรือ ประมาณ 45% ของเดิม · เอาตัวเลข Bitrate สองแถวนี้จากตารางมาหารกันดู ถ้าได้ราว ๆ 0.4–0.5 ก็ถือว่าสอดคล้อง
① กรณี loss = 0 สูตรใช้ไม่ได้ (หารด้วยศูนย์) ตัวจำกัดกลายเป็น Window / RTT แทน ② สูตร Mathis เป็นค่าประมาณสำหรับ TCP Reno ส่วน Linux สมัยใหม่ใช้ CUBIC ซึ่งฟื้นตัวเร็วกว่า → ค่าที่วัดได้จริงมักสูงกว่าที่สูตรทำนาย ③ ค่าที่ทำนายไว้ในตารางเป็นตัวเลขระดับ Mbit/s แต่ลิงก์ veth ไม่มีเพดาน จึงเห็นความต่างชัด ไม่โดนความจุลิงก์บัง
3. หากทดสอบด้วย UDP (iperf3 -u) แทน TCP ผลลัพธ์ในกรณี loss จะแตกต่างจาก TCP อย่างไร
ต่างกันสิ้นเชิง เพราะ UDP ไม่มี congestion control และไม่ส่งซ้ำ
| หัวข้อ | TCP (iperf3 -c) | UDP (iperf3 -c -u -b 100M) |
|---|---|---|
| เมื่อมี loss 5% | ลดความเร็วตัวเองลง — หด Cwnd แล้วส่งซ้ำ | ยิงเท่าเดิมไม่สนใจ — ยังคง 100 Mbit/s ตามที่สั่งด้วย -b |
| Bitrate ฝั่งส่ง | ตกลงชัดเจน | คงที่ ตาม -b ที่ตั้ง |
| ข้อมูลที่ถึงปลายทาง | ครบ 100% เสมอ (ส่งซ้ำจนกว่าจะถึง) | หายไป ~5% ถาวร ไม่มีการส่งซ้ำ |
| คอลัมน์ในรายงาน | มี Retr และ Cwnd | ไม่มี Retr/Cwnd แต่มี Jitter และ Lost/Total Datagrams แทน |
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 5] 0.00-5.00 sec 59.6 MBytes 100 Mbits/sec 0.000 ms 0/43200 (0%) sender
[ 5] 0.00-5.00 sec 56.6 MBytes 95.0 Mbits/sec 0.412 ms 2160/43200 (5%) receiver
# ↑ jitter ↑ loss ที่ปลายทางเห็นประโยชน์ในการทดลอง — โหมด UDP เป็นวิธีเดียวที่ iperf3 รายงาน jitter ให้ตรง ๆ จึงเหมาะกับการยืนยันผลข้อ 8.2 · ลองรัน -u พร้อมกับตั้ง netem delay 100ms 10ms แล้วดูช่อง Jitter จะเห็นตัวเลขขยับขึ้นตามที่ตั้งไว้ (ส่วนขยาย)
3.15การทดลอง 8.5 — ติดตั้งอุปกรณ์จริงและทดสอบด้วย Iperf3
ข้อสุดท้ายให้ออกจากโลกจำลองไปทดสอบกับสวิตช์จริงในห้องปฏิบัติการ ใบแลปสั่งไว้ 4 ข้อ
- ต่อวงจรเช่นเดียวกับรูปที่ 17 โดยให้เหลือเพียง 2 เครื่องเท่านั้น (ตามคู่ของ Lab) — เครื่องเราเป็นโหนดหนึ่ง เครื่องเพื่อนเป็นอีกโหนด ผ่านสวิตช์ในห้อง
- กำหนด IP Address ของเครื่องตนเองโดยไม่ต้องเชื่อมต่ออินเทอร์เน็ต
[Ubuntu VM] — ตั้ง IP ให้การ์ด USB-C Ethernet ที่ passthrough เข้ามา
$ ip -br a # หาชื่อการ์ดจริงก่อนเสมอ # enp0s5 UP 10.211.55.7/24 <- การ์ดเสมือนของ Parallels (อย่าแตะ) # enxaca7f1a9ff44 UP <- USB-C Ethernet ตัวจริง $ IF=enxaca7f1a9ff44 $ sudo ip addr add 192.3.128.5/24 dev $IF $ sudo ip link set $IF up $ sudo ethtool -K $IF tso off gso off gro off # ปิด offload ก่อนวัด - ใช้สวิตซ์ในห้องปฏิบัติการทดสอบด้วย iperf3 โดยเปรียบเทียบระหว่างสวิตซ์ 2 รุ่นที่แตกต่างกัน บันทึกว่าแตกต่างกันหรือไม่ อย่างไร
[Ubuntu VM] — เครื่องหนึ่งเป็น server อีกเครื่องเป็น client
$ iperf3 -s # เครื่องที่เป็นเซิร์ฟเวอร์ $ iperf3 -c 192.3.128.6 -t 10 # เครื่องที่เป็นไคลเอนต์สวิตช์รุ่นเก่าที่พอร์ตเป็น FastEthernet (100 Mbit/s) จะได้ Bitrate ราว 94–95 Mbit/s ส่วนรุ่นใหม่ที่เป็น GigabitEthernet จะได้ราว 940 Mbit/s — ตัวเลขที่วัดได้จะต่ำกว่าตัวเลขบนกล่องเสมอ เพราะมี overhead ของ Ethernet + IP + TCP header
- สลับบทบาทระหว่างไคลเอนต์และเซิร์ฟเวอร์ระหว่างคู่ Lab เปรียบเทียบผลการทำงานว่าต่างกันหรือไม่ หากต่าง เพราะเหตุใด
[Ubuntu VM] — หรือใช้
-Rสลับทิศทางโดยไม่ต้องย้ายเครื่อง ส่วนขยาย$ iperf3 -c 192.3.128.6 -t 10 -R # reverse: server ส่ง client รับ
คำถามท้ายข้อ 8.5
1. ผลที่ได้จากอุปกรณ์จริงแตกต่างจากผลจำลองบนมินิเน็ตหรือไม่ เพราะเหตุใด
ต่างกันมาก และต่างในทางที่คาดเดาได้
| หัวข้อ | Mininet | อุปกรณ์จริง |
|---|---|---|
| Throughput | หลายสิบ Gbit/s (รูปที่ 16 = 44.5 Gbit/s) | ถูกจำกัดด้วยความเร็วพอร์ตจริง — ~95 Mbit/s หรือ ~940 Mbit/s |
| ที่มาของเพดาน | ความเร็วของ RAM และ CPU — ไม่มีสายไฟจริงให้ส่งสัญญาณ | ความเร็วของ PHY/สายทองแดง ตาม 100BASE-TX หรือ 1000BASE-T |
| Delay พื้นฐาน | ~0.1 ms (Processing อย่างเดียว) | สูงกว่าเล็กน้อย เพราะมี Transmission + Propagation จริง บวก store-and-forward ของสวิตช์ |
| Loss พื้นฐาน | 0% เสมอ ไม่มี bit error | อาจมี loss เล็กน้อยจากสัญญาณรบกวน สายไม่ดี หรือ buffer เต็ม |
| Jitter | ต่ำมาก ค่อนข้างนิ่ง | สูงกว่า เพราะมีทราฟฟิกอื่นในสวิตช์และการจัดคิวจริง |
สรุปที่เขียนลงรายงาน: "Mininet จำลอง พฤติกรรมของโปรโตคอล ได้ถูกต้อง แต่ไม่ได้จำลอง ข้อจำกัดทางกายภาพ ของสายและ PHY เพราะทุกลิงก์เป็น veth ในหน่วยความจำเดียวกัน ค่าที่วัดได้จึงถูกจำกัดด้วยความเร็วของ CPU/RAM แทนความเร็วของสาย"
2. ปัจจัยใดในอุปกรณ์จริง (เช่น NIC, สาย, driver) ที่อาจทำให้ผลต่างจากการจำลอง
- ความเร็วของ NIC และการเจรจา auto-negotiation — ถ้าฝั่งหนึ่งเป็น 1 Gbit/s อีกฝั่งเป็น 100 Mbit/s ลิงก์จะตกลงกันที่ตัวช้ากว่า · ตรวจด้วย
ethtool $IFดูบรรทัดSpeed:และDuplex: - Duplex mismatch — ถ้าฝั่งหนึ่งเป็น half duplex จะเกิด collision throughput ตกฮวบและ loss พุ่ง เป็นอาการคลาสสิกของการตั้งค่าพอร์ตไม่ตรงกัน
- คุณภาพสายและระยะ — สาย Cat5 เก่า หัวหลวม หรือยาวเกิน 100 เมตร ทำให้เกิด bit error → เฟรมเสียถูกทิ้ง → TCP ส่งซ้ำ (
Retrขึ้น) - Driver และฟีเจอร์ offload — TSO/GSO/GRO ทำให้เห็นตัวเลขสวยเกินจริง และทำให้ netem วัดค่าเพี้ยน · จึงต้อง
sudo ethtool -K $IF tso off gso off gro offก่อนวัดทุกครั้ง - ขนาดบัฟเฟอร์ของสวิตช์ — สวิตช์ราคาถูกบัฟเฟอร์เล็ก พอมีทราฟฟิกพุ่งจะทิ้งแพ็กเก็ตทันที (ตรงกับสาเหตุ buffer overflow ในหัวข้อ 2.3)
- CPU ของเครื่องปลายทาง — ที่ความเร็วระดับ Gbit/s ถ้าเครื่องช้าหรือรันอยู่ใน VM ตัว CPU จะกลายเป็นคอขวดแทนสาย
- ทราฟฟิกอื่นบนสวิตช์เดียวกัน — ห้องแลปมีหลายคู่ทดสอบพร้อมกัน ทำให้เกิด queuing delay และ jitter จริง ๆ ซึ่ง Mininet ที่รันคนเดียวไม่มี
เฉพาะของ MacBook Air M2 — เราต่อผ่าน USB-C → Ethernet adapter แล้ว passthrough เข้า VM อีกชั้น จึงมีคอขวดเพิ่มอีกสองจุดคือบัส USB และชั้น virtualization ของ Parallels · ตัวเลขที่วัดได้อาจต่ำกว่าเพื่อนที่เสียบพอร์ต RJ-45 ในตัวเครื่องโดยตรง — ควรเขียนข้อจำกัดนี้ลงในรายงานด้วย
3.16สรุปผลการทดลอง (ตารางที่ 1)
ใบแลปหัวข้อ 9 สั่งให้สรุปผลทั้งหมดในรูปแบบตารางเปรียบเทียบ พร้อมอภิปรายความสัมพันธ์ระหว่างพารามิเตอร์ที่ปรับ (Delay, Jitter, Loss) กับผลลัพธ์ที่วัดได้ (RTT, Throughput, Retransmission) โดยอ้างอิงหลักการทางทฤษฎีในหัวข้อ 2
| การตั้งค่า | RTT (ms) avg จาก ping | Throughput (Mbps) Bitrate จาก iperf3 | Retr จาก iperf3 | Loss จริง (%) จาก ping |
|---|---|---|---|---|
| ไม่ตั้งค่า (baseline) | … | … | … | … |
| Delay 100 ms | … | … | … | … |
| Delay 100 ms + Jitter 10 ms | … | … | … | … |
| Loss 1% | … | … | … | … |
| Loss 5% | … | … | … | … |
ตารางที่ 1 ของใบแลป (ให้นักศึกษากรอกผลที่วัดได้)
- RTT — baseline ต่ำกว่า 1 ms · แถว Delay ทั้งสองต้องอยู่ราว 100 ms · แถว Loss ต้องกลับมาต่ำเหมือน baseline (loss ไม่เพิ่ม RTT)
- Throughput — baseline สูงสุด (ระดับ Gbit/s) · ตกฮวบทันทีที่ใส่ delay · ตกต่อเมื่อใส่ loss และตกมากขึ้นเมื่อ loss มากขึ้น
- Retr — baseline และ delay ควรเป็น 0 หรือใกล้ 0 · แถว loss ต้องมีเลข และ loss 5% ต้องมากกว่า loss 1%
- Loss จริง — เป็น 0% ทุกแถวยกเว้นสองแถวล่าง ซึ่งต้องใกล้เคียง 1% และ 5% ตามที่ตั้ง
คำถามสรุป
1. พารามิเตอร์ใด (Delay, Jitter, Loss) ส่งผลกระทบต่อ Throughput ของ TCP มากที่สุด เพราะเหตุใด
Delay (RTT) มากที่สุด — ดูจากสูตร Mathis ในรูปที่ 3 จะเห็นว่า RTT อยู่ในตัวส่วนแบบเชิงเส้น ส่วน Loss อยู่ใต้รากที่สอง
| เปลี่ยนอะไร | Throughput เหลือเท่าไร |
|---|---|
| RTT เพิ่ม 2 เท่า | 1/2 = 50% |
| Loss เพิ่ม 2 เท่า | 1/√2 = 71% |
| Loss เพิ่ม 4 เท่า | 1/√4 = 50% — ต้องเพิ่มถึง 4 เท่าจึงกระทบเท่ากับ RTT 2 เท่า |
ในเชิงกลไก — TCP ส่งได้ไม่เกิน 1 หน้าต่างต่อ 1 RTT แล้วต้องรอ ACK ก่อนส่งต่อ ฉะนั้น RTT คือตัวคูณเวลาของทุกอย่าง ทั้งช่วง slow start และช่วง congestion avoidance ยาวขึ้นตามสัดส่วน · ส่วน loss แค่ทำให้ Cwnd หดเป็นครั้ง ๆ ซึ่ง TCP ไต่กลับขึ้นมาได้ · Jitter กระทบน้อยที่สุด เพราะ TCP ไม่ได้ต้องการความสม่ำเสมอของเวลามาถึง
2. ถ้าออกแบบเน็ตเวิร์คให้แอปที่ไวต่อ Jitter (VoIP) และแอปที่ไวต่อ Throughput (File Transfer) จะให้ความสำคัญกับพารามิเตอร์ใดก่อน
VoIP / วิดีโอคอล → คุม Jitter เป็นอันดับแรก
- Jitter — ต้องนิ่ง เพราะเสียงต้องเล่นออกทุก 20 ms ตรงเวลา (จากหัวข้อ 2.2)
- Delay — รองลงมา ต้องต่ำพอให้คุยสวนกันได้
- Throughput — สำคัญน้อยสุด เสียงใช้แค่หลักสิบ kbit/s
- วิธีทำ — ให้ QoS priority queue กับทราฟฟิกเสียง คุมขนาดคิวไม่ให้ยาว และเลือกเส้นทางที่เสถียร
File Transfer → คุม Loss และ Delay เป็นอันดับแรก
- Loss — ทุกแพ็กเก็ตที่หายทำให้ TCP หด Cwnd ทันที
- Delay (RTT) — เป็นตัวคูณของ throughput โดยตรง
- Jitter — แทบไม่มีผล ข้อมูลมาช้าก็แค่รอในบัฟเฟอร์
- วิธีทำ — เพิ่ม bandwidth ให้ไม่แออัด ทำให้ buffer พอไม่ให้ล้น และวางเซิร์ฟเวอร์ใกล้ผู้ใช้เพื่อลด RTT
ประโยคสรุปสำหรับรายงาน: "VoIP ให้ความสำคัญกับ jitter แล้วจึง delay ส่วน throughput แทบไม่สำคัญ · File transfer ให้ความสำคัญกับ loss และ delay เพราะทั้งคู่กระทบ throughput ของ TCP โดยตรงตามสูตรของ Mathis ส่วน jitter แทบไม่มีผล"
3. มินิเน็ตเหมาะสมกับการศึกษาประสิทธิภาพเครือข่ายในระดับใด และมีข้อจำกัดใดที่ควรระวัง
เหมาะมากในระดับ "เข้าใจพฤติกรรมและแนวโน้ม" แต่ไม่เหมาะกับการอ้างตัวเลขสัมบูรณ์
เหมาะกับ
- ศึกษาพฤติกรรมของโปรโตคอล — TCP congestion control, ARP, STP, OpenFlow ทำงานด้วยโค้ดจริงของลินุกซ์
- ดูแนวโน้มเชิงเปรียบเทียบ เช่น "เพิ่ม RTT 2 เท่า throughput ลดครึ่ง"
- ทดลองซ้ำได้เป๊ะ ๆ เพราะควบคุมทุกตัวแปรได้ และสร้าง topology ใหญ่ ๆ ได้ในไม่กี่วินาที
- ไม่ต้องมีอุปกรณ์ — เรียนได้จากโน้ตบุ๊กเครื่องเดียว
ข้อจำกัดที่ต้องระวัง
- ไม่มีชั้นกายภาพจริง — ไม่มี propagation delay, bit error, duplex mismatch, สัญญาณรบกวน
- ตัวเลขความเร็วสูงเกินจริง — 44.5 Gbit/s เป็นความเร็วของ RAM ไม่ใช่ของสาย
- ทุกโหนดแย่ง CPU ตัวเดียวกัน — ถ้าสร้างโหนดเยอะหรืออัดทราฟฟิกหนัก CPU จะกลายเป็นคอขวดปลอม ๆ
- ผลกระทบจาก offload — ถ้าไม่ปิด TSO/GSO/GRO ค่าที่ netem ให้จะเพี้ยน
- รันบน VM ซ้อนอีกชั้น (กรณี Mac) ทำให้ตัวเลขยิ่งแกว่ง
สรุป: ใช้ Mininet เพื่อตอบคำถามว่า "ทำไม" และ "แนวโน้มไปทางไหน" ได้ดีมาก แต่ถ้าต้องตอบว่า "ระบบจริงจะได้กี่ Mbit/s" ต้องไปวัดบนอุปกรณ์จริงตามหัวข้อ 8.5
3.17จุดที่ Mac ต่างจากที่ใบแลปเขียนไว้
| เรื่อง | ใบแลปเขียนไว้ (Windows) | ของ Mac ต้องทำแบบนี้ |
|---|---|---|
| ตัวรัน VM | VMware Workstation Player 16 (หรือ WSL) | ไม่มีทั้งคู่บน macOS → ใช้ Parallels Desktop (หรือ UTM ถ้าเอาฟรี) |
| ปิด Hyper-V | Turn Windows features on or off → เอาเครื่องหมายถูกหน้า Hyper-V ออก → รีสตาร์ท (รูปที่ 4) | ไม่มีขั้นตอนนี้ — macOS ไม่มี Hyper-V และไม่มี Windows Features · ข้ามไปได้เลย |
| ไฟล์ Ubuntu | ISO ubuntu-18.04-desktop-amd64 (รูปที่ 6) | ต้องเป็น arm64 เท่านั้น — amd64 บูตบน M2 ไม่ขึ้น · Parallels มีตัวเลือกดาวน์โหลด Ubuntu ARM ให้ในหน้าสร้าง VM |
| สั่งงาน Mininet | เปิดหน้าต่าง VM แล้วพิมพ์ในเทอร์มินัลของ Ubuntu | ssh ubuntu จาก Terminal ของ macOS — คัดลอกผลลัพธ์ไปแปะรายงานได้ง่ายกว่ามาก |
| MiniEdit (GUI) | sudo examples/miniedit.py แล้วหน้าต่างเด้งขึ้นมาเลย | เป็นหน้าต่าง X11 — ผ่าน ssh ธรรมดาจะขึ้น no display name and no $DISPLAY · ให้รันในเดสก์ท็อปของ VM หรือลง XQuartz แล้ว ssh -Y ubuntu · ในห้องสอบใช้สคริปต์ Python แทน |
| ชื่อการ์ด Ethernet ใน VM | eth0 | enxaca7f1a9ff44 (ชื่อสร้างจาก MAC ของการ์ด USB) · enp0s5 คือการ์ดเสมือนของ Parallels คนละใบ · ดูชื่อจริงด้วย ip -br a ก่อนเสมอ |
| พอร์ต Ethernet | โน้ตบุ๊ก Windows ส่วนใหญ่มีช่อง RJ-45 ในตัว | MacBook Air M2 ไม่มีช่อง Ethernet → ใช้ USB-C → Ethernet adapter แล้วต้องทำ USB passthrough: Parallels → Devices → USB & Bluetooth → เลือกการ์ด |
| ก่อนวัดค่าด้วย netem | ใบแลปไม่ได้เขียนไว้ | sudo ethtool -K $IF tso off gso off gro off ทุกครั้ง ไม่งั้น delay/loss ที่วัดได้เพี้ยน ส่วนขยายที่จำเป็น |
git clone | git://github.com/mininet/mininet | ต้องเป็น https://github.com/mininet/mininet — GitHub ปิด git:// ไปแล้ว (ไม่ใช่เรื่องของ Mac แต่ใบแลปเก่าแล้ว) |
| ติดตั้ง Mininet | ./mininet/util/install.sh -a | บน ARM ใช้ sudo apt install -y mininet openvswitch-switch iperf3 net-tools ethtool ง่ายและชัวร์กว่า |
| คัดลอกผลลัพธ์ | ลากเมาส์ในหน้าต่าง VM | ssh ubuntu '…' | tee ~/Desktop/lab3_result.txt — เก็บลง Mac ตรง ๆ ใช้แนบรายงานได้เลย ส่วนขยาย |
3.18เช็คว่าทำถูกไหม
| คำสั่ง | ต้องได้ผลอะไร |
|---|---|
sudo mn --test pingall | ทดสอบว่า Mininet เองยังทำงาน — ต้องได้ *** Results: 0% dropped (2/2 received) |
mininet> net | ต้องเห็น h1-eth0:s1-eth1 … s1-eth3:s2-eth3 ครบ 5 ลิงก์ตามรูปที่ 17 |
mininet> dump | ทุกโฮสต์ต้องมี IP 192.3.128.1–.4 ตรงตามตารางใน §3.1 |
mininet> pingall | *** Results: 0% dropped (12/12 received) — ข้อสอบสั่งข้อนี้ตรง ๆ ("ping ได้ทุกโหนด") |
mininet> h1 ifconfig | เห็น h1-eth0 มี inet 192.3.128.1 netmask 255.255.255.0 (เทียบรูปที่ 14) |
mininet> h1 tc qdisc show dev h1-eth0 | หลังใส่ค่าต้องเห็น qdisc netem … delay 100ms 10ms · ถ้าเห็นแต่ noqueue / fq_codel = ยังไม่ติด |
mininet> h1 ping -c 10 192.3.128.3 | baseline avg < 1 ms · หลัง delay 100 ms ต้องได้ avg ≈ 100 ms (ไม่ใช่ 200) |
mininet> h1 iperf3 -c 192.3.128.2 -t 5 | ต้องได้บรรทัดสรุป sender ที่มีคอลัมน์ Retr — baseline ระดับ Gbit/s และ Retr = 0 |
ip -br a (ใน Ubuntu ไม่ใช่ใน mininet) | เห็น s1-eth1, s1-eth2, s1-eth3 ใน root namespace แต่ ไม่เห็น h1-eth0 — ถูกต้องแล้ว เพราะอยู่คนละ namespace (§3.6) |
3.19ถ้าไม่ผ่าน ให้ไล่ตามนี้
| อาการ | สาเหตุ | คำสั่งแก้ |
|---|---|---|
pingall ได้ 100% dropped ทั้งที่ topology ถูก | สวิตช์รอ controller อยู่ — OVS โหมด secure จะไม่ส่งอะไรเลยถ้าไม่มี controller | ใช้ failMode='standalone' ในสคริปต์ หรือเติม --controller none --switch ovsk,failMode=standalone ท้ายคำสั่ง mn |
Exception: Error creating interface pair (s1-eth1,h1-eth0): RTNETLINK answers: File exists | ของค้างจากรอบก่อน — ปิด Mininet ไม่สนิท (ปิดหน้าต่างเฉย ๆ หรือ Ctrl-C ตอนกำลังสร้าง) | sudo mn -c แล้วรันใหม่ — คำสั่งนี้ต้องจำไปห้องสอบ |
Cannot find device "h1-eth0" | ① พิมพ์ tc ในเทอร์มินัลของ Ubuntu ไม่ใช่ใน namespace ของ h1 ② หรือใช้ --topo linear,2,2 ซึ่งโฮสต์ชื่อ h1s1 | สั่งผ่าน mininet> h1 tc qdisc … หรือใน xterm h1 · ถ้าใช้ linear,2,2 ให้เปลี่ยนเป็น dev h1s1-eth0 → §3.10 |
RTNETLINK answers: File exists ตอนสั่ง tc qdisc add | มี netem อยู่บน interface นั้นแล้ว | ใช้ tc qdisc replace แทน add หรือ tc qdisc del … root netem ก่อน |
RTNETLINK answers: No such file or directory ตอนสั่ง tc qdisc del | ไม่มี qdisc ให้ลบอยู่แล้ว | ไม่ใช่ปัญหา ข้ามได้เลย — เป็นแค่การยืนยันว่าสะอาดอยู่แล้ว |
| ใส่ delay 100 ms แล้ว RTT ได้ ~600 ms | ใช้ --link tc,delay=100ms ซึ่งใส่ให้ทุกปลายของทุกลิงก์ เส้นทาง h1→h3 ผ่าน 3 ลิงก์ ไป-กลับ = 6 ครั้ง | สร้าง topology ไม่ใส่ --link tc แล้วใช้ tc qdisc ใส่เองที่ h1-eth0 ตัวเดียว → §3.8 |
| ใส่ delay 100 ms แล้ว RTT ได้ ~200 ms | เผลอใส่ netem ที่ ปลายทางด้วย (เช่นลืมลบของ h3 จากรอบก่อน) | h3 tc qdisc show dev h3-eth0 ตรวจดู แล้ว h3 tc qdisc del dev h3-eth0 root netem |
| ค่าที่วัดได้แกว่งมาก / loss ไม่ตรงกับที่ตั้ง | ยังไม่ปิด TSO/GSO/GRO — เคอร์เนลรวมแพ็กเก็ตเป็นก้อนใหญ่ก่อนถึง netem | h1 ethtool -K h1-eth0 tso off gso off gro off ทำกับทุกโฮสต์ที่วัด |
iperf3: error - unable to connect to server | ยังไม่ได้เปิดฝั่ง server หรือปิดไปแล้ว | h2 iperf3 -s -D ก่อน แล้วค่อยสั่งฝั่ง client · เช็กว่ารันอยู่ด้วย h2 pgrep -a iperf3 |
iperf3: error - the server is busy running a test | เทสต์เดิมยังไม่จบ หรือมี process ค้าง | h2 pkill iperf3 แล้วเปิดใหม่ |
miniedit.py ขึ้น no display name and no $DISPLAY environment variable | รันผ่าน ssh ธรรมดา ซึ่งไม่มีหน้าจอกราฟิก | รันในเดสก์ท็อปของ VM · หรือลง XQuartz บน Mac แล้ว ssh -Y ubuntu · หรือใช้สคริปต์ Python แทน (เร็วกว่า) |
ifconfig: command not found | Ubuntu รุ่นใหม่ไม่ได้ลง net-tools มาให้ | sudo apt install net-tools (ใบแลปเขียนไว้แล้ว) หรือใช้ ip -br a แทน |
git clone ค้าง / unauthenticated git protocol … no longer supported | ใบแลปใช้ git:// ซึ่ง GitHub ปิดไปแล้ว | เปลี่ยนเป็น https://github.com/mininet/mininet หรือ sudo apt install mininet ไปเลย |
ssh ubuntu ไม่ติด | VM ยังไม่บูต หรือ IP ของ VM เปลี่ยน | เปิดหน้าต่าง Parallels ดูว่า Ubuntu บูตแล้ว แล้ว ip -br a ใน VM เอา IP ใหม่ไปแก้ ~/.ssh/config |
| ออกจาก Mininet แล้วเน็ตของ Ubuntu รวน | ปิดไม่สนิท เหลือ veth และ bridge ค้างในระบบ | พิมพ์ exit ใน Mininet CLI ให้เรียบร้อย แล้ว sudo mn -c |
3.20ถ้าออกสอบ ต้องทำอะไรได้บ้าง
"ใช้ Mininet สร้าง network ตามรูป ให้ทุกโหนด ping ได้ แล้ว (a) ใส่ delay 100 ms + jitter 10 ms บน h1-eth0 เทียบผล ping ก่อน/หลัง (b) ใส่ loss 20% แล้วทดสอบ ping"
รันบอร์ดสำหรับห้องสอบ — ทำตามลำดับนี้ ไม่ต้องคิดเอง
- เปิด VM แล้ว ssh เข้าไป · ล้างของค้างก่อนเสมอ
[macOS Terminal]
$ ssh ubuntu $ sudo mn -c - สร้างไฟล์ topology — คัดลอกทั้งบล็อกจาก §3.10 วิธีที่ 1 วางครั้งเดียว แล้ว
sudo python3 ~/lab3.py - พิสูจน์ว่า "ping ได้ทุกโหนด" — เก็บผลไว้เป็นหลักฐานทันที
[mininet>]
mininet> dump mininet> pingall # *** Results: 0% dropped (12/12 received) ← ถ่ายรูป/คัดลอกเก็บ - วัด baseline ก่อนใส่อะไร — ข้อสอบสั่ง "เทียบก่อน/หลัง" ถ้าไม่มีค่าก่อน จะเทียบไม่ได้
[mininet>] — ห้ามข้ามขั้นนี้
mininet> h1 ping -c 10 192.3.128.3 # rtt min/avg/max/mdev = 0.047/0.127/0.206/0.051 ms ← จดไว้ - (a) ใส่ delay 100 ms + jitter 10 ms บน
h1-eth0แล้ววัดใหม่[mininet>] — สามบรรทัดนี้คือคำตอบข้อ (a)mininet> h1 tc qdisc add dev h1-eth0 root netem delay 100ms 10ms mininet> h1 tc qdisc show dev h1-eth0 mininet> h1 ping -c 20 192.3.128.3 # rtt min/avg/max/mdev = 90.x/100.x/109.x/5.8 ms ← จดเทียบกับ baselineต้องอธิบายให้ได้ 3 อย่าง ①
avgขึ้นจาก 0.13 → ~100 ms ②mdevขึ้นจาก 0.05 → ~5.8 ms คือ jitter ③ ทำไมถึง ~100 ไม่ใช่ ~200 (netem หน่วงเฉพาะขาออก) - ล้างค่าก่อนทำข้อถัดไป
[mininet>]
mininet> h1 tc qdisc del dev h1-eth0 root netem - (b) ใส่ loss 20% แล้ว ping
[mininet>] — คำตอบข้อ (b)
mininet> h1 tc qdisc add dev h1-eth0 root netem loss 20% mininet> h1 tc qdisc show dev h1-eth0 mininet> h1 ping -c 100 -i 0.2 192.3.128.3 # 100 packets transmitted, 81 received, 19% packet loss # ↑ ใกล้ 20% = ถูกต้องต้องอธิบายให้ได้ 2 อย่าง ① ยิงน้อยเกินจะไม่แม่น (จึงยิง 100–150 ครั้ง) ②
avgRTT แทบไม่เปลี่ยน เพราะ netem ทิ้งแพ็กเก็ตเลย ไม่ได้หน่วง และ ping เฉลี่ยเฉพาะแพ็กเก็ตที่ได้คำตอบ - ล้างทุกอย่างและเก็บผล
[mininet>]
mininet> h1 tc qdisc del dev h1-eth0 root netem mininet> exit $ sudo mn -c
sudo mn -c # ล้างของค้าง
sudo python3 ~/lab3.py # สร้าง topology
pingall # พิสูจน์ว่า ping ได้ทุกโหนด
h1 tc qdisc add dev h1-eth0 root netem delay 100ms 10ms # (a)
h1 tc qdisc add dev h1-eth0 root netem loss 20% # (b)
h1 tc qdisc del dev h1-eth0 root netem # ล้าง① ลืมวัด baseline ก่อน — ข้อสอบสั่ง "เทียบก่อน/หลัง" ไม่มีค่าก่อน = เสียคะแนน ② ลืมลบ netem ระหว่างข้อ (a) กับ (b) — ค่าจะซ้อนกัน ③ ใช้ --topo linear,2,2 แล้วไม่มี h1-eth0 ④ ping แค่ 4–10 ครั้งตอนวัด loss 20% ทำให้ตัวเลขแกว่งจนอธิบายไม่ได้ ⑤ ลืม sudo mn -c ก่อนเริ่ม แล้วเจอ File exists ตอนตื่นเต้น
3.21เช็คความเข้าใจ
avg = 0.13 ms · จากนั้นสั่ง h1 tc qdisc add dev h1-eth0 root netem delay 100ms แล้ว ping ใหม่ — ค่า avg ควรออกมาประมาณเท่าไรroot หน่วงเฉพาะแพ็กเก็ตขาออกของ h1-eth0root อยู่บนคิวขาออก (egress) ของอินเตอร์เฟซนั้นอย่างเดียว · ICMP echo request ที่ h1 ส่งออกไปโดนหน่วง 100 ms แต่ echo reply ที่วิ่งกลับเข้า h1-eth0 เป็นทิศ ingress ไม่โดนหน่วง → RTT รวมเพิ่มขึ้นครั้งเดียว ได้ราว 100.1 ms · ถ้าอยากได้ 200 ms ต้องไปใส่ที่ h3-eth0 ด้วย · ระวังคนละเรื่องกับ --link tc,delay=100ms ซึ่งใส่ให้ทุกปลายของทุกลิงก์ เส้นทาง h1→h3 ผ่าน 3 ลิงก์จะได้ ~600 msh1 tc qdisc add dev h1-eth0 root netem delay 100ms 10ms แล้ว ping 20 ครั้ง ได้ rtt min/avg/max/mdev = 90.4/100.2/109.6/5.8 ms — ทำไม mdev ถึงไม่ใช่ 10mdev ลงครึ่งหนึ่งเสมอ20ms ถ้าอยากได้ 1010ms คือครึ่งความกว้างของช่วงสุ่ม (90–110 ms) ส่วน mdev คือส่วนเบี่ยงเบนของค่าเหล่านั้น ซึ่งได้ราว 10/√3 ≈ 5.8delay 100ms 10ms สั่งให้ netem สุ่มค่าหน่วงแบบสม่ำเสมอในช่วง 90–110 ms (ซึ่งตรงกับ min ≈ 90.4 และ max ≈ 109.6 ที่วัดได้พอดี) ส่วน mdev ที่ ping รายงานคือส่วนเบี่ยงเบนของ RTT ทั้งชุด ซึ่งของการแจกแจงสม่ำเสมอครึ่งความกว้าง a จะเท่ากับ a/√3 = 10/1.732 ≈ 5.8 ms · ทดสอบได้ ถ้าเปลี่ยนเป็น 20ms ค่า mdev จะขึ้นเป็นสองเท่า (~11.5 ms) แสดงว่าแปรผันตรงกันจริง แต่ไม่ใช่ตัวเลขเดียวกันnet และ dump ถูกทุกอย่าง IP ครบ แต่ pingall ขึ้น *** Results: 100% dropped (0/12 received) — ควรแก้ยังไงfailMode=standalone (หรือเติม --controller none --switch ovsk,failMode=standalone) ให้ OVS ทำงานเป็นสวิตช์เรียนรู้ MAC เอง192.3.128.254h1-eth0 ออกก่อน เพราะมันบล็อกทั้งเน็ตเวิร์ค10.0.0.0/8 เพราะ Mininet รองรับแค่วงนี้secure ซึ่งไม่ยอมส่งต่อเฟรมใด ๆ จนกว่าจะมี controller มาสั่ง — ถ้าสร้าง topology โดยไม่มี controller สวิตช์จะเงียบสนิท ทุกอย่างจึง drop หมด · แก้ด้วยการตั้ง failMode='standalone' ให้สวิตช์กลับไปทำตัวเป็น L2 learning switch ธรรมดาเหมือน Legacy switch ใน MiniEdit · ข้ออื่นผิดเพราะ ทุกโหนดอยู่ /24 เดียวกันจึงไม่ต้องมี gateway · netem ที่ h1-eth0 กระทบแค่ทราฟฟิกที่ออกจาก h1 ไม่ทำให้ h2↔h3 พังด้วย · และ Mininet ใช้วงไหนก็ได้ผ่าน --ipbase หรือกำหนดเองในสคริปต์netem loss 15% ที่ h1-eth0 แล้ว ping -c 150 — พบว่า % packet loss ขึ้นเป็น ~15% แต่ avg RTT เท่าเดิมกับตอนไม่มี loss ทั้งที่ iperf3 กลับช้าลงมาก อธิบายอย่างไรavg จึงนิ่ง · ส่วน TCP ตีความทุก loss ว่าเป็นสัญญาณความแออัด จึงหด Congestion Window ลงครึ่งหนึ่ง แล้วยังต้องส่งซ้ำ (เห็นเป็นคอลัมน์ Retr ที่พุ่งขึ้น) ผลคือ Bitrate ตกตามสูตร Mathis ที่ throughput แปรผกผันกับ √Loss · บทเรียน: "RTT นิ่ง" ไม่ได้แปลว่า "เน็ตยังดี"① Mininet รันบน Linux เท่านั้น — Mac ต้องใช้ Ubuntu ARM ใน Parallels แล้ว ssh ubuntu (VMware Player/Hyper-V/WSL ในใบแลปใช้ไม่ได้) ② โฮสต์อยู่ใน namespace แยก → h1-eth0 มองเห็นได้เฉพาะผ่าน mininet> h1 … หรือ xterm h1 ③ รูปที่ 17 = โฮสต์ 4 · สวิตช์ 2 · ลิงก์ 5 · ไม่มี router ไม่มี controller ④ pingall ต้องได้ 0% dropped (12/12) ⑤ tc qdisc add dev h1-eth0 root netem delay 100ms 10ms และ … netem loss 20% คือสองบรรทัดของข้อสอบ ⑥ netem ที่ root = ขาออกอย่างเดียว → RTT เพิ่ม ~100 ไม่ใช่ 200 ⑦ อ่านผล ping: avg = delay · mdev = jitter (≈ jitter/√3) · % packet loss = loss ⑧ iperf3: Bitrate = throughput · Retr = ส่งซ้ำ · จดจากบรรทัด sender ⑨ ก่อนวัดต้อง ethtool -K … tso off gso off gro off ⑩ พังเมื่อไร sudo mn -c