โปรโตคอลเครือข่าย (Network Protocol) คือชุดของกฎเกณฑ์และมาตรฐานที่กำหนดวิธีการสื่อสารระหว่างอุปกรณ์ในเครือข่ายคอมพิวเตอร์ โปรโตคอลกำหนดรูปแบบข้อมูล (Data Format), ลำดับการส่งข้อมูล (Sequence), และวิธีการตอบสนองต่อข้อผิดพลาด (Error Handling)
การทำความเข้าใจโปรโตคอลเครือข่ายจำเป็นต้องเข้าใจ แบบจำลองชั้น (Layered Model) ที่ใช้ในการออกแบบและอธิบายการทำงานของเครือข่าย
graph TB
subgraph OSI["แบบจำลอง OSI (OSI Model)"]
direction TB
L7["ชั้นที่ 7: Application
แอปพลิเคชัน"]
L6["ชั้นที่ 6: Presentation
การนำเสนอ"]
L5["ชั้นที่ 5: Session
เซสชัน"]
L4["ชั้นที่ 4: Transport
ขนส่ง"]
L3["ชั้นที่ 3: Network
เครือข่าย"]
L2["ชั้นที่ 2: Data Link
เชื่อมต่อข้อมูล"]
L1["ชั้นที่ 1: Physical
กายภาพ"]
L7 --> L6 --> L5 --> L4 --> L3 --> L2 --> L1
end
subgraph TCPIP["แบบจำลอง TCP/IP"]
direction TB
T4["Application Layer
ชั้นแอปพลิเคชัน"]
T3["Transport Layer
ชั้นขนส่ง"]
T2["Internet Layer
ชั้นอินเทอร์เน็ต"]
T1["Network Access Layer
ชั้นเข้าถึงเครือข่าย"]
T4 --> T3 --> T2 --> T1
end
L7 -.-> T4
L6 -.-> T4
L5 -.-> T4
L4 -.-> T3
L3 -.-> T2
L2 -.-> T1
L1 -.-> T1
style L7 fill:#458588,stroke:#83a598,color:#ebdbb2
style L6 fill:#458588,stroke:#83a598,color:#ebdbb2
style L5 fill:#458588,stroke:#83a598,color:#ebdbb2
style L4 fill:#d79921,stroke:#fabd2f,color:#282828
style L3 fill:#98971a,stroke:#b8bb26,color:#282828
style L2 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style L1 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style T4 fill:#458588,stroke:#83a598,color:#ebdbb2
style T3 fill:#d79921,stroke:#fabd2f,color:#282828
style T2 fill:#98971a,stroke:#b8bb26,color:#282828
style T1 fill:#b16286,stroke:#d3869b,color:#ebdbb2
flowchart LR
subgraph Era1["ยุคบุกเบิก (1960s-1970s)"]
A1["1969: ARPANET
เครือข่ายแรก"]
A2["1974: TCP/IP
ถูกออกแบบ"]
A3["1978: IPv4
เริ่มพัฒนา"]
A1 --> A2 --> A3
end
subgraph Era2["ยุคมาตรฐาน (1980s-1990s)"]
B1["1981: IPv4
RFC 791"]
B2["1983: ARPANET
ใช้ TCP/IP"]
B3["1995: IPv6
เริ่มพัฒนา"]
B1 --> B2 --> B3
end
subgraph Era3["ยุคปัจจุบัน (2000s-ปัจจุบัน)"]
C1["2004: IPv6
มาตรฐานสมบูรณ์"]
C2["2011: IPv4
หมดช่วงที่อยู่"]
C3["ปัจจุบัน: Dual Stack
IPv4/IPv6"]
C1 --> C2 --> C3
end
Era1 --> Era2 --> Era3
style A1 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style A2 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style A3 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style B1 fill:#d79921,stroke:#fabd2f,color:#282828
style B2 fill:#d79921,stroke:#fabd2f,color:#282828
style B3 fill:#d79921,stroke:#fabd2f,color:#282828
style C1 fill:#98971a,stroke:#b8bb26,color:#282828
style C2 fill:#98971a,stroke:#b8bb26,color:#282828
style C3 fill:#98971a,stroke:#b8bb26,color:#282828
ชั้นขนส่ง (Transport Layer) เป็นชั้นที่รับผิดชอบการส่งข้อมูลระหว่างกระบวนการ (Process-to-Process Communication) บนโฮสต์ต้นทางและปลายทาง โดยโปรโตคอลหลักในชั้นนี้คือ TCP และ UDP
TCP (Transmission Control Protocol) คือโปรโตคอลที่ให้บริการการส่งข้อมูลแบบ เชื่อมต่อ (Connection-Oriented) และ เชื่อถือได้ (Reliable) โดยมีคุณสมบัติหลักดังนี้:
graph TB
subgraph TCPHeader["โครงสร้างส่วนหัว TCP (TCP Header) - 20 ไบต์ขั้นต่ำ"]
direction TB
R1["Source Port (16 บิต) | Destination Port (16 บิต)"]
R2["Sequence Number (32 บิต)"]
R3["Acknowledgment Number (32 บิต)"]
R4["Data Offset (4 บิต) | Reserved (3 บิต) | Flags (9 บิต) | Window Size (16 บิต)"]
R5["Checksum (16 บิต) | Urgent Pointer (16 บิต)"]
R6["Options (ถ้ามี) | Padding"]
R1 --> R2 --> R3 --> R4 --> R5 --> R6
end
style R1 fill:#458588,stroke:#83a598,color:#ebdbb2
style R2 fill:#98971a,stroke:#b8bb26,color:#282828
style R3 fill:#98971a,stroke:#b8bb26,color:#282828
style R4 fill:#d79921,stroke:#fabd2f,color:#282828
style R5 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style R6 fill:#b16286,stroke:#d3869b,color:#ebdbb2
| ฟิลด์ | ขนาด | คำอธิบาย |
|---|---|---|
| Source Port | 16 บิต | หมายเลขพอร์ตต้นทาง (0-65535) |
| Destination Port | 16 บิต | หมายเลขพอร์ตปลายทาง (0-65535) |
| Sequence Number | 32 บิต | หมายเลขลำดับของไบต์แรกในเซกเมนต์ |
| Acknowledgment Number | 32 บิต | หมายเลขลำดับของไบต์ถัดไปที่คาดว่าจะได้รับ |
| Data Offset | 4 บิต | ความยาวของส่วนหัว (หน่วยเป็น 32-bit words) |
| Flags | 9 บิต | ธง URG, ACK, PSH, RST, SYN, FIN และอื่นๆ |
| Window Size | 16 บิต | ขนาดหน้าต่างรับ (Receive Window) |
| Checksum | 16 บิต | ค่าตรวจสอบความถูกต้อง |
| Urgent Pointer | 16 บิต | ชี้ไปยังข้อมูลเร่งด่วน (ถ้า URG=1) |
Three-Way Handshake คือกระบวนการสร้างการเชื่อมต่อ TCP ประกอบด้วย 3 ขั้นตอน:
sequenceDiagram
participant C as ไคลเอนต์ (Client)
participant S as เซิร์ฟเวอร์ (Server)
Note over C,S: กระบวนการสร้างการเชื่อมต่อ (Connection Establishment)
C->>S: SYN (seq=x)
Note right of C: ขั้นที่ 1: ส่ง SYN
ขอสร้างการเชื่อมต่อ
S->>C: SYN-ACK (seq=y, ack=x+1)
Note left of S: ขั้นที่ 2: ตอบรับ SYN
และส่ง SYN กลับ
C->>S: ACK (seq=x+1, ack=y+1)
Note right of C: ขั้นที่ 3: ยืนยัน SYN
ของเซิร์ฟเวอร์
Note over C,S: การเชื่อมต่อสำเร็จ (ESTABLISHED)
C->>S: ข้อมูล (Data)
S->>C: ACK
S->>C: ข้อมูล (Data)
C->>S: ACK
Note over C,S: กระบวนการยุติการเชื่อมต่อ (Connection Termination)
C->>S: FIN (seq=m)
S->>C: ACK (ack=m+1)
S->>C: FIN (seq=n)
C->>S: ACK (ack=n+1)
Note over C,S: การเชื่อมต่อถูกปิด (CLOSED)
คำอธิบายกระบวนการ:
TCP ใช้กลไก Sliding Window เพื่อควบคุมอัตราการส่งข้อมูล
graph LR
subgraph Sender["ผู้ส่ง (Sender)"]
S1["ส่งแล้ว
รอ ACK"]
S2["ส่งได้
(Window)"]
S3["ยังส่งไม่ได้"]
end
subgraph Receiver["ผู้รับ (Receiver)"]
R1["รับแล้ว
ส่ง ACK"]
R2["Buffer
ว่าง"]
R3["รอข้อมูล"]
end
S1 --> |"ACK"| R1
S2 --> |"Data"| R2
style S1 fill:#98971a,stroke:#b8bb26,color:#282828
style S2 fill:#d79921,stroke:#fabd2f,color:#282828
style S3 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style R1 fill:#98971a,stroke:#b8bb26,color:#282828
style R2 fill:#d79921,stroke:#fabd2f,color:#282828
style R3 fill:#458588,stroke:#83a598,color:#ebdbb2
สูตรคำนวณ Throughput สูงสุดของ TCP:
โดยที่:
TCP ใช้อัลกอริทึมหลายตัวในการควบคุมความคับคั่ง:
| อัลกอริทึม | คำอธิบาย | การทำงาน |
|---|---|---|
| Slow Start | เริ่มต้นช้า | เพิ่ม cwnd เป็นสองเท่าทุกๆ RTT จนถึง ssthresh |
| Congestion Avoidance | หลีกเลี่ยงความคับคั่ง | เพิ่ม cwnd ทีละ 1 MSS ต่อ RTT |
| Fast Retransmit | ส่งซ้ำเร็ว | ส่งซ้ำเมื่อได้รับ 3 Duplicate ACKs |
| Fast Recovery | ฟื้นตัวเร็ว | ลด cwnd ลงครึ่งหนึ่งแทนที่จะเริ่มใหม่ |
graph TD
subgraph CongestionControl["อัลกอริทึมควบคุมความคับคั่ง"]
A["เริ่มต้น
cwnd = 1 MSS"]
B{"cwnd < ssthresh?"}
C["Slow Start
cwnd = cwnd × 2"]
D["Congestion Avoidance
cwnd = cwnd + 1"]
E{"เกิด Timeout?"}
F{"3 Duplicate
ACKs?"}
G["ssthresh = cwnd/2
cwnd = 1 MSS"]
H["Fast Recovery
ssthresh = cwnd/2
cwnd = ssthresh + 3"]
A --> B
B -->|ใช่| C
B -->|ไม่| D
C --> E
D --> E
E -->|ใช่| G
E -->|ไม่| F
F -->|ใช่| H
F -->|ไม่| B
G --> A
H --> D
end
style A fill:#458588,stroke:#83a598,color:#ebdbb2
style B fill:#d79921,stroke:#fabd2f,color:#282828
style C fill:#98971a,stroke:#b8bb26,color:#282828
style D fill:#98971a,stroke:#b8bb26,color:#282828
style E fill:#d79921,stroke:#fabd2f,color:#282828
style F fill:#d79921,stroke:#fabd2f,color:#282828
style G fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style H fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
สูตรคำนวณ Congestion Window:
โดยที่:
"""
ตัวอย่างการสร้าง TCP Server และ Client ด้วย Python
แสดงการทำงานพื้นฐานของโปรโตคอล TCP
"""
import socket
import threading
from datetime import datetime
class TCPServer:
"""
คลาสสำหรับสร้าง TCP Server
รองรับการเชื่อมต่อหลายไคลเอนต์พร้อมกัน (Multi-threaded)
"""
def __init__(self, host: str = '127.0.0.1', port: int = 8080):
"""
กำหนดค่าเริ่มต้นสำหรับ TCP Server
พารามิเตอร์:
host: ที่อยู่ IP ที่จะรับฟัง (default: localhost)
port: หมายเลขพอร์ต (default: 8080)
"""
self.host = host
self.port = port
# สร้าง socket แบบ TCP (SOCK_STREAM)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# อนุญาตให้ใช้พอร์ตซ้ำได้ทันที
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def handle_client(self, client_socket: socket.socket, address: tuple):
"""
จัดการการสื่อสารกับไคลเอนต์แต่ละราย
พารามิเตอร์:
client_socket: socket ของไคลเอนต์
address: (IP, port) ของไคลเอนต์
"""
print(f"[{datetime.now()}] การเชื่อมต่อจาก {address}")
try:
while True:
# รับข้อมูลจากไคลเอนต์ (buffer size = 1024 bytes)
data = client_socket.recv(1024)
if not data:
# ไคลเอนต์ปิดการเชื่อมต่อ
break
message = data.decode('utf-8')
print(f"[{address}] ได้รับ: {message}")
# ส่งข้อความตอบกลับ
response = f"เซิร์ฟเวอร์ได้รับ: {message}"
client_socket.send(response.encode('utf-8'))
except Exception as e:
print(f"[ข้อผิดพลาด] {address}: {e}")
finally:
client_socket.close()
print(f"[{datetime.now()}] ปิดการเชื่อมต่อจาก {address}")
def start(self):
"""
เริ่มต้นการทำงานของ TCP Server
"""
# ผูก socket กับ host และ port
self.socket.bind((self.host, self.port))
# เริ่มรับฟังการเชื่อมต่อ (backlog = 5)
self.socket.listen(5)
print(f"[TCP Server] กำลังรับฟังที่ {self.host}:{self.port}")
try:
while True:
# รอรับการเชื่อมต่อใหม่
client_socket, address = self.socket.accept()
# สร้าง thread ใหม่สำหรับไคลเอนต์แต่ละราย
client_thread = threading.Thread(
target=self.handle_client,
args=(client_socket, address)
)
client_thread.start()
except KeyboardInterrupt:
print("\n[TCP Server] กำลังปิดเซิร์ฟเวอร์...")
finally:
self.socket.close()
class TCPClient:
"""
คลาสสำหรับสร้าง TCP Client
"""
def __init__(self, server_host: str = '127.0.0.1', server_port: int = 8080):
"""
กำหนดค่าเริ่มต้นสำหรับ TCP Client
พารามิเตอร์:
server_host: ที่อยู่ IP ของเซิร์ฟเวอร์
server_port: หมายเลขพอร์ตของเซิร์ฟเวอร์
"""
self.server_host = server_host
self.server_port = server_port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect(self):
"""
สร้างการเชื่อมต่อไปยังเซิร์ฟเวอร์ (Three-Way Handshake)
"""
try:
self.socket.connect((self.server_host, self.server_port))
print(f"[TCP Client] เชื่อมต่อกับ {self.server_host}:{self.server_port} สำเร็จ")
return True
except Exception as e:
print(f"[ข้อผิดพลาด] ไม่สามารถเชื่อมต่อได้: {e}")
return False
def send_message(self, message: str) -> str:
"""
ส่งข้อความไปยังเซิร์ฟเวอร์และรับการตอบกลับ
พารามิเตอร์:
message: ข้อความที่ต้องการส่ง
คืนค่า:
ข้อความตอบกลับจากเซิร์ฟเวอร์
"""
try:
# ส่งข้อมูล
self.socket.send(message.encode('utf-8'))
# รอรับการตอบกลับ
response = self.socket.recv(1024)
return response.decode('utf-8')
except Exception as e:
return f"[ข้อผิดพลาด]: {e}"
def close(self):
"""
ปิดการเชื่อมต่อ (Four-Way Handshake)
"""
self.socket.close()
print("[TCP Client] ปิดการเชื่อมต่อแล้ว")
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'server':
# รัน: python tcp_example.py server
server = TCPServer()
server.start()
else:
# รัน: python tcp_example.py
client = TCPClient()
if client.connect():
# ส่งข้อความทดสอบ
messages = ["สวัสดี", "ทดสอบ TCP", "ลาก่อน"]
for msg in messages:
response = client.send_message(msg)
print(f"ตอบกลับ: {response}")
client.close()
ผลลัพธ์การทำงาน:
# เซิร์ฟเวอร์:
[TCP Server] กำลังรับฟังที่ 127.0.0.1:8080
[2024-01-15 10:30:45] การเชื่อมต่อจาก ('127.0.0.1', 54321)
[('127.0.0.1', 54321)] ได้รับ: สวัสดี
[('127.0.0.1', 54321)] ได้รับ: ทดสอบ TCP
[('127.0.0.1', 54321)] ได้รับ: ลาก่อน
[2024-01-15 10:30:46] ปิดการเชื่อมต่อจาก ('127.0.0.1', 54321)
# ไคลเอนต์:
[TCP Client] เชื่อมต่อกับ 127.0.0.1:8080 สำเร็จ
ตอบกลับ: เซิร์ฟเวอร์ได้รับ: สวัสดี
ตอบกลับ: เซิร์ฟเวอร์ได้รับ: ทดสอบ TCP
ตอบกลับ: เซิร์ฟเวอร์ได้รับ: ลาก่อน
[TCP Client] ปิดการเชื่อมต่อแล้ว
UDP (User Datagram Protocol) คือโปรโตคอลที่ให้บริการการส่งข้อมูลแบบ ไม่เชื่อมต่อ (Connectionless) และ ไม่รับประกันการส่ง (Unreliable) โดยมีคุณสมบัติหลักดังนี้:
graph TB
subgraph UDPHeader["โครงสร้างส่วนหัว UDP (UDP Header) - 8 ไบต์"]
direction TB
U1["Source Port (16 บิต) | Destination Port (16 บิต)"]
U2["Length (16 บิต) | Checksum (16 บิต)"]
U1 --> U2
end
style U1 fill:#458588,stroke:#83a598,color:#ebdbb2
style U2 fill:#d79921,stroke:#fabd2f,color:#282828
| ฟิลด์ | ขนาด | คำอธิบาย |
|---|---|---|
| Source Port | 16 บิต | หมายเลขพอร์ตต้นทาง (optional สามารถเป็น 0) |
| Destination Port | 16 บิต | หมายเลขพอร์ตปลายทาง |
| Length | 16 บิต | ความยาวรวมของ UDP datagram (header + data) |
| Checksum | 16 บิต | ค่าตรวจสอบความถูกต้อง (optional ใน IPv4, บังคับใน IPv6) |
UDP เหมาะสำหรับแอปพลิเคชันที่:
| แอปพลิเคชัน | เหตุผลที่ใช้ UDP |
|---|---|
| DNS | การสอบถามขนาดเล็ก ต้องการความเร็ว |
| DHCP | การกำหนด IP อัตโนมัติ ไม่ต้องการการเชื่อมต่อ |
| VoIP | ส่งเสียงแบบ real-time ยอมรับการสูญหายเล็กน้อย |
| Video Streaming | ส่งวิดีโอต่อเนื่อง ยอมรับการสูญเฟรม |
| Online Gaming | ต้องการ latency ต่ำ |
| SNMP | การจัดการเครือข่าย ข้อความขนาดเล็ก |
| TFTP | โอนไฟล์ง่ายๆ มีกลไก ACK ของตัวเอง |
"""
ตัวอย่างการสร้าง UDP Server และ Client ด้วย Python
แสดงการทำงานพื้นฐานของโปรโตคอล UDP
"""
import socket
from datetime import datetime
class UDPServer:
"""
คลาสสำหรับสร้าง UDP Server
รับและตอบกลับ datagram จากหลายไคลเอนต์
"""
def __init__(self, host: str = '127.0.0.1', port: int = 9090):
"""
กำหนดค่าเริ่มต้นสำหรับ UDP Server
พารามิเตอร์:
host: ที่อยู่ IP ที่จะรับฟัง
port: หมายเลขพอร์ต
"""
self.host = host
self.port = port
# สร้าง socket แบบ UDP (SOCK_DGRAM)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def start(self):
"""
เริ่มต้นการทำงานของ UDP Server
"""
# ผูก socket กับ host และ port
self.socket.bind((self.host, self.port))
print(f"[UDP Server] กำลังรับฟังที่ {self.host}:{self.port}")
try:
while True:
# รับ datagram และที่อยู่ของผู้ส่ง
# UDP ไม่ต้อง accept() เพราะไม่มีการเชื่อมต่อ
data, client_address = self.socket.recvfrom(1024)
message = data.decode('utf-8')
print(f"[{datetime.now()}] จาก {client_address}: {message}")
# ส่งข้อความตอบกลับไปยังผู้ส่ง
response = f"ได้รับ: {message}"
self.socket.sendto(response.encode('utf-8'), client_address)
except KeyboardInterrupt:
print("\n[UDP Server] กำลังปิดเซิร์ฟเวอร์...")
finally:
self.socket.close()
class UDPClient:
"""
คลาสสำหรับสร้าง UDP Client
"""
def __init__(self, server_host: str = '127.0.0.1', server_port: int = 9090):
"""
กำหนดค่าเริ่มต้นสำหรับ UDP Client
พารามิเตอร์:
server_host: ที่อยู่ IP ของเซิร์ฟเวอร์
server_port: หมายเลขพอร์ตของเซิร์ฟเวอร์
"""
self.server_address = (server_host, server_port)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# กำหนด timeout เพื่อป้องกันการรอไม่สิ้นสุด
self.socket.settimeout(5.0)
def send_message(self, message: str) -> str:
"""
ส่งข้อความไปยังเซิร์ฟเวอร์และรอรับการตอบกลับ
พารามิเตอร์:
message: ข้อความที่ต้องการส่ง
คืนค่า:
ข้อความตอบกลับจากเซิร์ฟเวอร์ หรือข้อความแจ้งเตือน
"""
try:
# ส่ง datagram ไปยังเซิร์ฟเวอร์
# UDP ไม่ต้อง connect() เพราะไม่มีการเชื่อมต่อ
self.socket.sendto(message.encode('utf-8'), self.server_address)
# รอรับการตอบกลับ
data, server = self.socket.recvfrom(1024)
return data.decode('utf-8')
except socket.timeout:
return "[หมดเวลา] ไม่ได้รับการตอบกลับจากเซิร์ฟเวอร์"
except Exception as e:
return f"[ข้อผิดพลาด]: {e}"
def close(self):
"""
ปิด socket (UDP ไม่มี graceful shutdown)
"""
self.socket.close()
print("[UDP Client] ปิด socket แล้ว")
def measure_latency(client: UDPClient, iterations: int = 10) -> dict:
"""
วัดค่า latency ของการส่งข้อมูล UDP
พารามิเตอร์:
client: UDP client object
iterations: จำนวนครั้งที่ทดสอบ
คืนค่า:
dictionary ที่มีค่าสถิติ latency
"""
import time
latencies = []
for i in range(iterations):
start_time = time.time()
response = client.send_message(f"ping-{i}")
end_time = time.time()
if not response.startswith("["):
latency = (end_time - start_time) * 1000 # แปลงเป็น ms
latencies.append(latency)
if latencies:
return {
'min': min(latencies),
'max': max(latencies),
'avg': sum(latencies) / len(latencies),
'success_rate': len(latencies) / iterations * 100
}
return {'error': 'ไม่สามารถวัดค่า latency ได้'}
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'server':
# รัน: python udp_example.py server
server = UDPServer()
server.start()
else:
# รัน: python udp_example.py
client = UDPClient()
# ส่งข้อความทดสอบ
messages = ["สวัสดี UDP", "ทดสอบ Datagram", "ข้อมูล real-time"]
for msg in messages:
response = client.send_message(msg)
print(f"ตอบกลับ: {response}")
# วัด latency
print("\n--- ผลการวัด Latency ---")
stats = measure_latency(client, 10)
if 'error' not in stats:
print(f"ต่ำสุด: {stats['min']:.2f} ms")
print(f"สูงสุด: {stats['max']:.2f} ms")
print(f"เฉลี่ย: {stats['avg']:.2f} ms")
print(f"อัตราสำเร็จ: {stats['success_rate']:.1f}%")
client.close()
| คุณสมบัติ | TCP | UDP |
|---|---|---|
| ประเภทการเชื่อมต่อ | Connection-oriented | Connectionless |
| ความน่าเชื่อถือ | รับประกันการส่ง | ไม่รับประกัน |
| การเรียงลำดับ | รับประกันลำดับ | ไม่รับประกัน |
| ขนาดส่วนหัว | 20-60 bytes | 8 bytes |
| Flow Control | มี (Sliding Window) | ไม่มี |
| Congestion Control | มี | ไม่มี |
| ความเร็ว | ช้ากว่า | เร็วกว่า |
| Overhead | สูง | ต่ำ |
| Broadcast/Multicast | ไม่รองรับ | รองรับ |
| ตัวอย่างการใช้งาน | HTTP, FTP, SMTP, SSH | DNS, DHCP, VoIP, Gaming |
graph LR
subgraph TCP_Flow["การทำงานของ TCP"]
T1["สร้างการเชื่อมต่อ
(3-Way Handshake)"]
T2["ส่งข้อมูล"]
T3["รอ ACK"]
T4["ส่งซ้ำ
(ถ้าไม่ได้ ACK)"]
T5["ปิดการเชื่อมต่อ
(4-Way Handshake)"]
T1 --> T2 --> T3 --> T4
T3 --> T5
end
subgraph UDP_Flow["การทำงานของ UDP"]
U1["ส่ง Datagram"]
U2["จบ"]
U1 --> U2
end
style T1 fill:#458588,stroke:#83a598,color:#ebdbb2
style T2 fill:#98971a,stroke:#b8bb26,color:#282828
style T3 fill:#d79921,stroke:#fabd2f,color:#282828
style T4 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style T5 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style U1 fill:#98971a,stroke:#b8bb26,color:#282828
style U2 fill:#458588,stroke:#83a598,color:#ebdbb2
ชั้นเครือข่าย (Network Layer) รับผิดชอบการส่งข้อมูลระหว่างโฮสต์ (Host-to-Host Communication) ข้ามเครือข่ายต่างๆ โดยใช้การกำหนดที่อยู่แบบ Logical (IP Address) และการจัดเส้นทาง (Routing)
IPv4 (Internet Protocol version 4) คือโปรโตคอลหลักในการส่งข้อมูลระดับเครือข่าย ถูกกำหนดใน RFC 791 (1981) มีคุณสมบัติหลักดังนี้:
graph TB
subgraph IPv4Header["โครงสร้างส่วนหัว IPv4 - 20-60 ไบต์"]
direction TB
I1["Version (4) | IHL (4) | Type of Service (8) | Total Length (16)"]
I2["Identification (16) | Flags (3) | Fragment Offset (13)"]
I3["Time to Live (8) | Protocol (8) | Header Checksum (16)"]
I4["Source IP Address (32 บิต)"]
I5["Destination IP Address (32 บิต)"]
I6["Options (ถ้ามี) | Padding"]
I1 --> I2 --> I3 --> I4 --> I5 --> I6
end
style I1 fill:#458588,stroke:#83a598,color:#ebdbb2
style I2 fill:#d79921,stroke:#fabd2f,color:#282828
style I3 fill:#98971a,stroke:#b8bb26,color:#282828
style I4 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style I5 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style I6 fill:#b16286,stroke:#d3869b,color:#ebdbb2
| ฟิลด์ | ขนาด (บิต) | คำอธิบาย |
|---|---|---|
| Version | 4 | เวอร์ชันของ IP (4 สำหรับ IPv4) |
| IHL (Internet Header Length) | 4 | ความยาวของส่วนหัว (หน่วยเป็น 32-bit words) |
| Type of Service (ToS) | 8 | ระบุความสำคัญและประเภทบริการ |
| Total Length | 16 | ความยาวรวมของแพ็กเก็ต (bytes) |
| Identification | 16 | ใช้ระบุ fragments ของแพ็กเก็ตเดียวกัน |
| Flags | 3 | ธงควบคุมการแบ่ง fragment |
| Fragment Offset | 13 | ตำแหน่งของ fragment ในแพ็กเก็ตต้นฉบับ |
| TTL (Time to Live) | 8 | จำนวน hop สูงสุดก่อนถูกทิ้ง |
| Protocol | 8 | โปรโตคอลชั้นบน (6=TCP, 17=UDP, 1=ICMP) |
| Header Checksum | 16 | ค่าตรวจสอบความถูกต้องของส่วนหัว |
| Source IP | 32 | ที่อยู่ IP ต้นทาง |
| Destination IP | 32 | ที่อยู่ IP ปลายทาง |
ระบบ Classful Addressing ถูกกำหนดขึ้นในปี 1981 ตาม RFC 791 เพื่อจัดสรรที่อยู่ IP ให้กับองค์กรต่างๆ อย่างเป็นระบบ โดยแบ่งที่อยู่ IP ออกเป็น 5 คลาส (Class A ถึง Class E) ตามบิตแรกๆ ของที่อยู่
หลักการพื้นฐาน:
graph TB
subgraph IPv4Structure["โครงสร้างที่อยู่ IPv4 (32 บิต)"]
direction LR
O1["Octet 1
8 บิต
(0-255)"]
DOT1["."]
O2["Octet 2
8 บิต
(0-255)"]
DOT2["."]
O3["Octet 3
8 บิต
(0-255)"]
DOT3["."]
O4["Octet 4
8 บิต
(0-255)"]
O1 --- DOT1 --- O2 --- DOT2 --- O3 --- DOT3 --- O4
end
subgraph Example["ตัวอย่าง: 192.168.1.100"]
E1["192
11000000"]
ED1["."]
E2["168
10101000"]
ED2["."]
E3["1
00000001"]
ED3["."]
E4["100
01100100"]
E1 --- ED1 --- E2 --- ED2 --- E3 --- ED3 --- E4
end
IPv4Structure --> Example
style O1 fill:#458588,stroke:#83a598,color:#ebdbb2
style O2 fill:#458588,stroke:#83a598,color:#ebdbb2
style O3 fill:#458588,stroke:#83a598,color:#ebdbb2
style O4 fill:#458588,stroke:#83a598,color:#ebdbb2
style E1 fill:#98971a,stroke:#b8bb26,color:#282828
style E2 fill:#98971a,stroke:#b8bb26,color:#282828
style E3 fill:#d79921,stroke:#fabd2f,color:#282828
style E4 fill:#d79921,stroke:#fabd2f,color:#282828
Class A ถูกออกแบบสำหรับองค์กรขนาดใหญ่มากที่ต้องการที่อยู่ IP จำนวนมหาศาล
graph TB
subgraph ClassADetail["Class A - รายละเอียด"]
direction TB
subgraph BitPattern["รูปแบบบิต"]
BP["0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx"]
BP_DESC["บิตแรก = 0 (ระบุว่าเป็น Class A)"]
end
subgraph Structure["โครงสร้าง"]
NET["Network ID
8 บิต (1 ออกเตต)"]
HOST["Host ID
24 บิต (3 ออกเตต)"]
NET --> HOST
end
subgraph Range["ช่วงที่อยู่"]
R1["เริ่มต้น: 1.0.0.0"]
R2["สิ้นสุด: 126.255.255.255"]
R3["ยกเว้น: 0.x.x.x และ 127.x.x.x"]
end
subgraph Subnet["Subnet Mask"]
SM["255.0.0.0"]
SM_BIN["11111111.00000000.00000000.00000000"]
SM_CIDR["/8"]
end
end
style BP fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style NET fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style HOST fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style SM fill:#458588,stroke:#83a598,color:#ebdbb2
คุณสมบัติ Class A:
| คุณสมบัติ | ค่า | คำอธิบาย |
|---|---|---|
| บิตแรก | 0 | ระบุว่าเป็น Class A |
| ช่วง Octet แรก | 1-126 | 0 และ 127 สงวนไว้ |
| Default Subnet Mask | 255.0.0.0 | /8 ใน CIDR notation |
| จำนวน Network | 126 | 2⁷ - 2 (ลบ 0 และ 127) |
| จำนวน Host ต่อ Network | 16,777,214 | 2²⁴ - 2 |
| ผู้ใช้งาน | รัฐบาล, องค์กรขนาดใหญ่มาก | เช่น Apple, MIT, US DoD |
สูตรคำนวณจำนวน Host สำหรับ Class A:
โดยที่:
ตัวอย่างที่อยู่ Class A:
| ที่อยู่ IP | Network ID | Host ID | ประเภท |
|---|---|---|---|
| 10.0.0.0 | 10 | 0.0.0 | Network Address |
| 10.0.0.1 | 10 | 0.0.1 | Host Address แรก |
| 10.255.255.254 | 10 | 255.255.254 | Host Address สุดท้าย |
| 10.255.255.255 | 10 | 255.255.255 | Broadcast Address |
| 8.8.8.8 | 8 | 8.8.8 | Google DNS |
| 17.0.0.1 | 17 | 0.0.1 | Apple Network |
Class B ถูกออกแบบสำหรับองค์กรขนาดกลางถึงขนาดใหญ่
graph TB
subgraph ClassBDetail["Class B - รายละเอียด"]
direction TB
subgraph BitPattern["รูปแบบบิต"]
BP["10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx"]
BP_DESC["2 บิตแรก = 10 (ระบุว่าเป็น Class B)"]
end
subgraph Structure["โครงสร้าง"]
NET["Network ID
16 บิต (2 ออกเตต)"]
HOST["Host ID
16 บิต (2 ออกเตต)"]
NET --> HOST
end
subgraph Range["ช่วงที่อยู่"]
R1["เริ่มต้น: 128.0.0.0"]
R2["สิ้นสุด: 191.255.255.255"]
end
subgraph Subnet["Subnet Mask"]
SM["255.255.0.0"]
SM_BIN["11111111.11111111.00000000.00000000"]
SM_CIDR["/16"]
end
end
style BP fill:#d79921,stroke:#fabd2f,color:#282828
style NET fill:#d79921,stroke:#fabd2f,color:#282828
style HOST fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style SM fill:#458588,stroke:#83a598,color:#ebdbb2
คุณสมบัติ Class B:
| คุณสมบัติ | ค่า | คำอธิบาย |
|---|---|---|
| 2 บิตแรก | 10 | ระบุว่าเป็น Class B |
| ช่วง Octet แรก | 128-191 | ค่าที่ขึ้นต้นด้วย 10xxxxxx |
| Default Subnet Mask | 255.255.0.0 | /16 ใน CIDR notation |
| จำนวน Network | 16,384 | 2¹⁴ |
| จำนวน Host ต่อ Network | 65,534 | 2¹⁶ - 2 |
| ผู้ใช้งาน | มหาวิทยาลัย, บริษัทขนาดใหญ่ | เช่น Microsoft, IBM |
สูตรคำนวณจำนวน Network สำหรับ Class B:
โดยที่:
สูตรคำนวณจำนวน Host สำหรับ Class B:
ตัวอย่างที่อยู่ Class B:
| ที่อยู่ IP | Network ID | Host ID | ประเภท |
|---|---|---|---|
| 172.16.0.0 | 172.16 | 0.0 | Network Address (Private) |
| 172.16.0.1 | 172.16 | 0.1 | Host Address แรก |
| 172.16.255.254 | 172.16 | 255.254 | Host Address สุดท้าย |
| 172.16.255.255 | 172.16 | 255.255 | Broadcast Address |
| 128.0.0.1 | 128.0 | 0.1 | Class B แรก |
| 191.255.0.1 | 191.255 | 0.1 | Class B สุดท้าย |
Class C ถูกออกแบบสำหรับองค์กรขนาดเล็กที่ต้องการที่อยู่ IP จำนวนไม่มาก
graph TB
subgraph ClassCDetail["Class C - รายละเอียด"]
direction TB
subgraph BitPattern["รูปแบบบิต"]
BP["110xxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx"]
BP_DESC["3 บิตแรก = 110 (ระบุว่าเป็น Class C)"]
end
subgraph Structure["โครงสร้าง"]
NET["Network ID
24 บิต (3 ออกเตต)"]
HOST["Host ID
8 บิต (1 ออกเตต)"]
NET --> HOST
end
subgraph Range["ช่วงที่อยู่"]
R1["เริ่มต้น: 192.0.0.0"]
R2["สิ้นสุด: 223.255.255.255"]
end
subgraph Subnet["Subnet Mask"]
SM["255.255.255.0"]
SM_BIN["11111111.11111111.11111111.00000000"]
SM_CIDR["/24"]
end
end
style BP fill:#98971a,stroke:#b8bb26,color:#282828
style NET fill:#98971a,stroke:#b8bb26,color:#282828
style HOST fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style SM fill:#458588,stroke:#83a598,color:#ebdbb2
คุณสมบัติ Class C:
| คุณสมบัติ | ค่า | คำอธิบาย |
|---|---|---|
| 3 บิตแรก | 110 | ระบุว่าเป็น Class C |
| ช่วง Octet แรก | 192-223 | ค่าที่ขึ้นต้นด้วย 110xxxxx |
| Default Subnet Mask | 255.255.255.0 | /24 ใน CIDR notation |
| จำนวน Network | 2,097,152 | 2²¹ |
| จำนวน Host ต่อ Network | 254 | 2⁸ - 2 |
| ผู้ใช้งาน | SME, สำนักงานขนาดเล็ก | เครือข่ายส่วนใหญ่ในปัจจุบัน |
สูตรคำนวณจำนวน Network สำหรับ Class C:
สูตรคำนวณจำนวน Host สำหรับ Class C:
ตัวอย่างที่อยู่ Class C:
| ที่อยู่ IP | Network ID | Host ID | ประเภท |
|---|---|---|---|
| 192.168.1.0 | 192.168.1 | 0 | Network Address (Private) |
| 192.168.1.1 | 192.168.1 | 1 | Host Address แรก (มักเป็น Gateway) |
| 192.168.1.254 | 192.168.1 | 254 | Host Address สุดท้าย |
| 192.168.1.255 | 192.168.1 | 255 | Broadcast Address |
| 203.0.113.50 | 203.0.113 | 50 | Documentation Range |
graph TB
subgraph SpecialClasses["Class D และ Class E"]
direction TB
subgraph ClassD["Class D - Multicast"]
D1["1110xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx"]
D2["224.0.0.0 - 239.255.255.255"]
D3["ใช้สำหรับ Multicast Groups"]
D4["ไม่มี Network/Host แยก"]
end
subgraph ClassE["Class E - Reserved"]
E1["1111xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx"]
E2["240.0.0.0 - 255.255.255.255"]
E3["สงวนไว้สำหรับการทดลอง"]
E4["ไม่ใช้ในการทำงานจริง"]
end
end
style D1 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style D2 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style D3 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style D4 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style E1 fill:#928374,stroke:#a89984,color:#ebdbb2
style E2 fill:#928374,stroke:#a89984,color:#ebdbb2
style E3 fill:#928374,stroke:#a89984,color:#ebdbb2
style E4 fill:#928374,stroke:#a89984,color:#ebdbb2
Class D - Multicast:
| คุณสมบัติ | ค่า |
|---|---|
| 4 บิตแรก | 1110 |
| ช่วงที่อยู่ | 224.0.0.0 - 239.255.255.255 |
| วัตถุประสงค์ | ส่งข้อมูลไปยังกลุ่มของโฮสต์พร้อมกัน |
| Subnet Mask | ไม่มี (ไม่แบ่ง Network/Host) |
ที่อยู่ Multicast ที่สำคัญ:
| ที่อยู่ | ชื่อ | คำอธิบาย |
|---|---|---|
| 224.0.0.1 | All Hosts | ทุกโฮสต์ใน local network |
| 224.0.0.2 | All Routers | ทุกเราเตอร์ใน local network |
| 224.0.0.5 | OSPF Routers | เราเตอร์ที่ใช้ OSPF |
| 224.0.0.6 | OSPF DR | OSPF Designated Routers |
| 224.0.0.9 | RIPv2 | RIP version 2 |
| 224.0.0.251 | mDNS | Multicast DNS |
| 224.0.1.1 | NTP | Network Time Protocol |
| 239.255.255.250 | SSDP | Simple Service Discovery |
Class E - Reserved:
| คุณสมบัติ | ค่า |
|---|---|
| 4 บิตแรก | 1111 |
| ช่วงที่อยู่ | 240.0.0.0 - 255.255.255.254 |
| วัตถุประสงค์ | สงวนไว้สำหรับการวิจัยและทดลอง |
| สถานะ | ไม่สามารถใช้งานบนอินเทอร์เน็ตสาธารณะ |
หมายเหตุ: 255.255.255.255 เป็น Limited Broadcast Address ซึ่งใช้ส่ง broadcast ไปยังทุกโฮสต์ในเครือข่ายท้องถิ่น
| คุณสมบัติ | Class A | Class B | Class C | Class D | Class E |
|---|---|---|---|---|---|
| บิตนำหน้า | 0 | 10 | 110 | 1110 | 1111 |
| Octet แรก | 1-126 | 128-191 | 192-223 | 224-239 | 240-255 |
| Default Mask | /8 | /16 | /24 | N/A | N/A |
| Network bits | 8 | 16 | 24 | N/A | N/A |
| Host bits | 24 | 16 | 8 | N/A | N/A |
| จำนวน Networks | 126 | 16,384 | 2,097,152 | N/A | N/A |
| Hosts/Network | 16,777,214 | 65,534 | 254 | N/A | N/A |
| การใช้งาน | องค์กรยักษ์ใหญ่ | องค์กรขนาดใหญ่ | องค์กรทั่วไป | Multicast | วิจัย |
graph LR
subgraph AddressSpace["พื้นที่ที่อยู่ IPv4 ทั้งหมด (0-255)"]
direction LR
A["Class A
1-126
50%"]
B["Class B
128-191
25%"]
C["Class C
192-223
12.5%"]
D["Class D
224-239
6.25%"]
E["Class E
240-255
6.25%"]
A --> B --> C --> D --> E
end
style A fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style B fill:#d79921,stroke:#fabd2f,color:#282828
style C fill:#98971a,stroke:#b8bb26,color:#282828
style D fill:#b16286,stroke:#d3869b,color:#ebdbb2
style E fill:#928374,stroke:#a89984,color:#ebdbb2
graph TB
subgraph SpecialAddresses["ที่อยู่ IPv4 พิเศษ"]
direction TB
subgraph Private["Private Address Ranges (RFC 1918)"]
P1["10.0.0.0/8
Class A Private
16.7 ล้านที่อยู่"]
P2["172.16.0.0/12
Class B Private
1 ล้านที่อยู่"]
P3["192.168.0.0/16
Class C Private
65,536 ที่อยู่"]
end
subgraph Loopback["Loopback"]
L1["127.0.0.0/8
ทดสอบภายในเครื่อง
127.0.0.1 = localhost"]
end
subgraph LinkLocal["Link-Local (APIPA)"]
LL1["169.254.0.0/16
กำหนดอัตโนมัติ
เมื่อไม่มี DHCP"]
end
subgraph Documentation["Documentation"]
DOC1["192.0.2.0/24 (TEST-NET-1)"]
DOC2["198.51.100.0/24 (TEST-NET-2)"]
DOC3["203.0.113.0/24 (TEST-NET-3)"]
end
end
style P1 fill:#458588,stroke:#83a598,color:#ebdbb2
style P2 fill:#458588,stroke:#83a598,color:#ebdbb2
style P3 fill:#458588,stroke:#83a598,color:#ebdbb2
style L1 fill:#98971a,stroke:#b8bb26,color:#282828
style LL1 fill:#d79921,stroke:#fabd2f,color:#282828
style DOC1 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style DOC2 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style DOC3 fill:#b16286,stroke:#d3869b,color:#ebdbb2
ตารางที่อยู่พิเศษทั้งหมด:
| ช่วงที่อยู่ | ชื่อ | RFC | คำอธิบาย |
|---|---|---|---|
| 0.0.0.0/8 | This Network | RFC 1122 | ระบุเครือข่ายปัจจุบัน |
| 10.0.0.0/8 | Private-Use | RFC 1918 | เครือข่ายส่วนตัว Class A |
| 100.64.0.0/10 | Shared Address | RFC 6598 | Carrier-Grade NAT |
| 127.0.0.0/8 | Loopback | RFC 1122 | ทดสอบภายในเครื่อง |
| 169.254.0.0/16 | Link-Local | RFC 3927 | APIPA |
| 172.16.0.0/12 | Private-Use | RFC 1918 | เครือข่ายส่วนตัว Class B |
| 192.0.0.0/24 | IETF Protocol | RFC 6890 | IETF Protocol Assignments |
| 192.0.2.0/24 | Documentation | RFC 5737 | TEST-NET-1 |
| 192.88.99.0/24 | 6to4 Relay | RFC 3068 | IPv6 to IPv4 relay |
| 192.168.0.0/16 | Private-Use | RFC 1918 | เครือข่ายส่วนตัว Class C |
| 198.18.0.0/15 | Benchmarking | RFC 2544 | ทดสอบประสิทธิภาพ |
| 198.51.100.0/24 | Documentation | RFC 5737 | TEST-NET-2 |
| 203.0.113.0/24 | Documentation | RFC 5737 | TEST-NET-3 |
| 224.0.0.0/4 | Multicast | RFC 5771 | Class D Multicast |
| 240.0.0.0/4 | Reserved | RFC 1112 | Class E Reserved |
| 255.255.255.255/32 | Limited Broadcast | RFC 919 | Broadcast ทุกเครื่องใน LAN |
"""
โมดูลวิเคราะห์ที่อยู่ IPv4 และ Class
แสดงการระบุ Class, Network ID, Host ID และคุณสมบัติต่างๆ
"""
from dataclasses import dataclass
from typing import Optional, Tuple
from enum import Enum
class IPClass(Enum):
"""
Enum สำหรับ Class ของที่อยู่ IPv4
"""
CLASS_A = "A"
CLASS_B = "B"
CLASS_C = "C"
CLASS_D = "D" # Multicast
CLASS_E = "E" # Reserved
SPECIAL = "Special" # ที่อยู่พิเศษ
@dataclass
class IPv4Analysis:
"""
คลาสเก็บผลการวิเคราะห์ที่อยู่ IPv4
"""
ip_address: str # ที่อยู่ IP
ip_binary: str # รูปแบบ binary
ip_class: IPClass # Class ของ IP
default_subnet_mask: str # Subnet mask ปกติ
network_id: str # Network ID
host_id: str # Host ID
network_bits: int # จำนวนบิต Network
host_bits: int # จำนวนบิต Host
max_hosts: int # จำนวน host สูงสุด
is_private: bool # เป็นที่อยู่ private หรือไม่
is_loopback: bool # เป็น loopback หรือไม่
is_multicast: bool # เป็น multicast หรือไม่
special_purpose: Optional[str] = None # วัตถุประสงค์พิเศษ
def ip_to_binary(ip: str) -> str:
"""
แปลงที่อยู่ IP เป็น binary string
พารามิเตอร์:
ip: ที่อยู่ IP ในรูปแบบ dotted decimal
คืนค่า:
binary string คั่นด้วยจุด
ตัวอย่าง:
>>> ip_to_binary("192.168.1.1")
'11000000.10101000.00000001.00000001'
"""
octets = ip.split('.')
binary_octets = [format(int(octet), '08b') for octet in octets]
return '.'.join(binary_octets)
def binary_to_ip(binary: str) -> str:
"""
แปลง binary string เป็นที่อยู่ IP
พารามิเตอร์:
binary: binary string (มีหรือไม่มีจุดก็ได้)
คืนค่า:
ที่อยู่ IP ในรูปแบบ dotted decimal
"""
# ลบจุดออก
binary_clean = binary.replace('.', '')
# แบ่งเป็น 4 ส่วน
octets = [binary_clean[i:i+8] for i in range(0, 32, 8)]
decimal_octets = [str(int(octet, 2)) for octet in octets]
return '.'.join(decimal_octets)
def determine_class(first_octet: int) -> Tuple[IPClass, int, int, str]:
"""
ระบุ Class จาก octet แรก
พารามิเตอร์:
first_octet: ค่า octet แรก (0-255)
คืนค่า:
tuple ของ (IPClass, network_bits, host_bits, default_mask)
"""
if first_octet == 0:
return (IPClass.SPECIAL, 0, 0, "N/A")
elif first_octet == 127:
return (IPClass.SPECIAL, 8, 24, "255.0.0.0")
elif 1 <= first_octet <= 126:
return (IPClass.CLASS_A, 8, 24, "255.0.0.0")
elif 128 <= first_octet <= 191:
return (IPClass.CLASS_B, 16, 16, "255.255.0.0")
elif 192 <= first_octet <= 223:
return (IPClass.CLASS_C, 24, 8, "255.255.255.0")
elif 224 <= first_octet <= 239:
return (IPClass.CLASS_D, 0, 0, "N/A")
elif 240 <= first_octet <= 255:
return (IPClass.CLASS_E, 0, 0, "N/A")
else:
return (IPClass.SPECIAL, 0, 0, "N/A")
def check_special_purpose(ip: str) -> Optional[str]:
"""
ตรวจสอบว่าที่อยู่ IP มีวัตถุประสงค์พิเศษหรือไม่
พารามิเตอร์:
ip: ที่อยู่ IP
คืนค่า:
คำอธิบายวัตถุประสงค์พิเศษ หรือ None
"""
octets = [int(x) for x in ip.split('.')]
first = octets[0]
# ตรวจสอบ Private Addresses
if first == 10:
return "Private Address (10.0.0.0/8)"
if first == 172 and 16 <= octets[1] <= 31:
return "Private Address (172.16.0.0/12)"
if first == 192 and octets[1] == 168:
return "Private Address (192.168.0.0/16)"
# ตรวจสอบ Loopback
if first == 127:
return "Loopback Address (127.0.0.0/8)"
# ตรวจสอบ Link-Local
if first == 169 and octets[1] == 254:
return "Link-Local / APIPA (169.254.0.0/16)"
# ตรวจสอบ Documentation
if first == 192 and octets[1] == 0 and octets[2] == 2:
return "Documentation (TEST-NET-1)"
if first == 198 and octets[1] == 51 and octets[2] == 100:
return "Documentation (TEST-NET-2)"
if first == 203 and octets[1] == 0 and octets[2] == 113:
return "Documentation (TEST-NET-3)"
# ตรวจสอบ Carrier-Grade NAT
if first == 100 and 64 <= octets[1] <= 127:
return "Shared Address Space / CGNAT (100.64.0.0/10)"
# ตรวจสอบ Benchmarking
if first == 198 and octets[1] in [18, 19]:
return "Benchmarking (198.18.0.0/15)"
# ตรวจสอบ Multicast
if 224 <= first <= 239:
return "Multicast Address"
# ตรวจสอบ Reserved
if 240 <= first <= 255:
return "Reserved for Future Use"
# ตรวจสอบ Broadcast
if ip == "255.255.255.255":
return "Limited Broadcast"
return None
def get_network_and_host_id(ip: str, ip_class: IPClass) -> Tuple[str, str]:
"""
แยก Network ID และ Host ID
พารามิเตอร์:
ip: ที่อยู่ IP
ip_class: Class ของ IP
คืนค่า:
tuple ของ (network_id, host_id)
"""
octets = ip.split('.')
if ip_class == IPClass.CLASS_A:
network_id = octets[0]
host_id = '.'.join(octets[1:])
elif ip_class == IPClass.CLASS_B:
network_id = '.'.join(octets[:2])
host_id = '.'.join(octets[2:])
elif ip_class == IPClass.CLASS_C:
network_id = '.'.join(octets[:3])
host_id = octets[3]
else:
network_id = ip
host_id = "N/A"
return network_id, host_id
def analyze_ipv4(ip: str) -> IPv4Analysis:
"""
วิเคราะห์ที่อยู่ IPv4 อย่างละเอียด
พารามิเตอร์:
ip: ที่อยู่ IP ในรูปแบบ dotted decimal
คืนค่า:
IPv4Analysis object ที่มีข้อมูลครบถ้วน
ตัวอย่าง:
>>> result = analyze_ipv4("192.168.1.100")
>>> print(result.ip_class)
IPClass.CLASS_C
"""
# แยก octets
octets = [int(x) for x in ip.split('.')]
first_octet = octets[0]
# แปลงเป็น binary
ip_binary = ip_to_binary(ip)
# ระบุ Class
ip_class, network_bits, host_bits, default_mask = determine_class(first_octet)
# แยก Network ID และ Host ID
network_id, host_id = get_network_and_host_id(ip, ip_class)
# คำนวณจำนวน host สูงสุด
max_hosts = (2 ** host_bits - 2) if host_bits > 0 else 0
# ตรวจสอบประเภทพิเศษ
special_purpose = check_special_purpose(ip)
is_private = "Private" in (special_purpose or "")
is_loopback = first_octet == 127
is_multicast = 224 <= first_octet <= 239
return IPv4Analysis(
ip_address=ip,
ip_binary=ip_binary,
ip_class=ip_class,
default_subnet_mask=default_mask,
network_id=network_id,
host_id=host_id,
network_bits=network_bits,
host_bits=host_bits,
max_hosts=max_hosts,
is_private=is_private,
is_loopback=is_loopback,
is_multicast=is_multicast,
special_purpose=special_purpose
)
def calculate_network_range(ip: str, ip_class: IPClass) -> Tuple[str, str, str]:
"""
คำนวณช่วง Network Address, First Host, Last Host, Broadcast
พารามิเตอร์:
ip: ที่อยู่ IP
ip_class: Class ของ IP
คืนค่า:
tuple ของ (network_address, first_host, last_host, broadcast)
"""
octets = [int(x) for x in ip.split('.')]
if ip_class == IPClass.CLASS_A:
network = f"{octets[0]}.0.0.0"
first_host = f"{octets[0]}.0.0.1"
last_host = f"{octets[0]}.255.255.254"
broadcast = f"{octets[0]}.255.255.255"
elif ip_class == IPClass.CLASS_B:
network = f"{octets[0]}.{octets[1]}.0.0"
first_host = f"{octets[0]}.{octets[1]}.0.1"
last_host = f"{octets[0]}.{octets[1]}.255.254"
broadcast = f"{octets[0]}.{octets[1]}.255.255"
elif ip_class == IPClass.CLASS_C:
network = f"{octets[0]}.{octets[1]}.{octets[2]}.0"
first_host = f"{octets[0]}.{octets[1]}.{octets[2]}.1"
last_host = f"{octets[0]}.{octets[1]}.{octets[2]}.254"
broadcast = f"{octets[0]}.{octets[1]}.{octets[2]}.255"
else:
return (ip, "N/A", "N/A", "N/A")
return (network, first_host, last_host, broadcast)
def print_analysis_report(analysis: IPv4Analysis):
"""
พิมพ์รายงานการวิเคราะห์
พารามิเตอร์:
analysis: ผลการวิเคราะห์
"""
print("=" * 60)
print(f"รายงานการวิเคราะห์ที่อยู่ IPv4: {analysis.ip_address}")
print("=" * 60)
print(f"\n📍 ข้อมูลพื้นฐาน:")
print(f" ที่อยู่ IP: {analysis.ip_address}")
print(f" Binary: {analysis.ip_binary}")
print(f" Class: {analysis.ip_class.value}")
if analysis.ip_class in [IPClass.CLASS_A, IPClass.CLASS_B, IPClass.CLASS_C]:
print(f"\n🔢 โครงสร้างที่อยู่:")
print(f" Default Mask: {analysis.default_subnet_mask}")
print(f" Network ID: {analysis.network_id}")
print(f" Host ID: {analysis.host_id}")
print(f" Network Bits: {analysis.network_bits}")
print(f" Host Bits: {analysis.host_bits}")
print(f" Max Hosts: {analysis.max_hosts:,}")
# คำนวณช่วงเครือข่าย
network, first, last, broadcast = calculate_network_range(
analysis.ip_address, analysis.ip_class
)
print(f"\n📊 ช่วงเครือข่าย:")
print(f" Network Address: {network}")
print(f" First Host: {first}")
print(f" Last Host: {last}")
print(f" Broadcast: {broadcast}")
print(f"\n🏷️ ประเภท:")
print(f" Private: {'✓' if analysis.is_private else '✗'}")
print(f" Loopback: {'✓' if analysis.is_loopback else '✗'}")
print(f" Multicast: {'✓' if analysis.is_multicast else '✗'}")
if analysis.special_purpose:
print(f"\n⚠️ วัตถุประสงค์พิเศษ:")
print(f" {analysis.special_purpose}")
print("\n" + "=" * 60)
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
# รายการที่อยู่ IP ทดสอบ
test_ips = [
"10.0.0.1", # Class A Private
"8.8.8.8", # Class A Public (Google DNS)
"172.16.0.100", # Class B Private
"150.100.50.25", # Class B Public
"192.168.1.1", # Class C Private
"203.0.113.50", # Class C Documentation
"127.0.0.1", # Loopback
"169.254.1.1", # Link-Local
"224.0.0.1", # Multicast
"240.0.0.1", # Reserved
]
for ip in test_ips:
print(f"\n{'='*60}")
analysis = analyze_ipv4(ip)
print_analysis_report(analysis)
ผลลัพธ์ตัวอย่าง:
============================================================
รายงานการวิเคราะห์ที่อยู่ IPv4: 192.168.1.100
============================================================
📍 ข้อมูลพื้นฐาน:
ที่อยู่ IP: 192.168.1.100
Binary: 11000000.10101000.00000001.01100100
Class: C
🔢 โครงสร้างที่อยู่:
Default Mask: 255.255.255.0
Network ID: 192.168.1
Host ID: 100
Network Bits: 24
Host Bits: 8
Max Hosts: 254
📊 ช่วงเครือข่าย:
Network Address: 192.168.1.0
First Host: 192.168.1.1
Last Host: 192.168.1.254
Broadcast: 192.168.1.255
🏷️ ประเภท:
Private: ✓
Loopback: ✗
Multicast: ✗
⚠️ วัตถุประสงค์พิเศษ:
Private Address (192.168.0.0/16)
============================================================
graph TB
subgraph Problems["ปัญหาของ Classful Addressing"]
P1["⚠️ สิ้นเปลืองที่อยู่
Class A มี 16.7 ล้าน Host
ไม่มีใครต้องการมากขนาดนั้น"]
P2["⚠️ ไม่ยืดหยุ่น
ขนาดเครือข่ายคงที่
ปรับแต่งไม่ได้"]
P3["⚠️ ที่อยู่หมดเร็ว
Class B หมดก่อน
เพราะเหมาะกับองค์กรส่วนใหญ่"]
P4["⚠️ Routing Table ใหญ่
ต้องเก็บ entry มาก
ไม่มี aggregation"]
end
subgraph Solution["วิธีแก้ไข"]
S1["✅ CIDR
(Classless Inter-Domain Routing)
RFC 4632"]
S2["✅ VLSM
(Variable Length Subnet Mask)"]
S3["✅ NAT
(Network Address Translation)"]
S4["✅ IPv6
(128-bit Address)"]
end
P1 --> S1
P2 --> S2
P3 --> S3
P4 --> S4
style P1 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style P2 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style P3 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style P4 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style S1 fill:#98971a,stroke:#b8bb26,color:#282828
style S2 fill:#98971a,stroke:#b8bb26,color:#282828
style S3 fill:#98971a,stroke:#b8bb26,color:#282828
style S4 fill:#98971a,stroke:#b8bb26,color:#282828
ปัญหาหลักของ Classful Addressing:
| ปัญหา | คำอธิบาย | ผลกระทบ |
|---|---|---|
| Address Wastage | Class A ให้ 16.7 ล้าน Host แต่องค์กรใหญ่สุดใช้แค่หลักแสน | สูญเสียที่อยู่ไปมหาศาล |
| Inflexibility | ขนาดเครือข่ายคงที่ 3 ขนาด | ไม่ตรงกับความต้องการจริง |
| Class B Depletion | Class B เหมาะสมที่สุด จึงถูกใช้หมดก่อน | ขาดแคลนที่อยู่ |
| Routing Inefficiency | ไม่สามารถรวม route ได้ | Routing table ใหญ่ |
ตัวอย่างความสิ้นเปลือง:
องค์กรที่มี 300 เครื่อง:
Timeline การเปลี่ยนแปลง:
flowchart LR
subgraph Era1["1981-1993"]
A1["Classful
Addressing"]
end
subgraph Era2["1993"]
B1["CIDR
RFC 1518/1519"]
end
subgraph Era3["1996"]
C1["NAT
RFC 1631"]
end
subgraph Era4["1998-ปัจจุบัน"]
D1["IPv6
RFC 2460"]
end
Era1 -->|"ที่อยู่เริ่มหมด"| Era2
Era2 -->|"ยังไม่พอ"| Era3
Era3 -->|"แก้ปัญหาระยะยาว"| Era4
style A1 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
style B1 fill:#d79921,stroke:#fabd2f,color:#282828
style C1 fill:#98971a,stroke:#b8bb26,color:#282828
style D1 fill:#458588,stroke:#83a598,color:#ebdbb2
ประเด็นสำคัญที่ต้องจำ:
การระบุ Class: ดูจากบิตแรกๆ ของที่อยู่
Default Subnet Mask:
สูตรคำนวณ:
ที่อยู่พิเศษ:
ปัจจุบัน: ใช้ CIDR แทน Classful เพื่อความยืดหยุ่น
CIDR เป็นวิธีการกำหนดที่อยู่ IP ที่ยืดหยุ่นกว่าระบบ Class โดยใช้ prefix length ระบุจำนวนบิตของ network portion
รูปแบบ: IP_Address/prefix_length
ตัวอย่าง: 192.168.1.0/24
สูตรคำนวณจำนวน Host:
โดยที่:
| CIDR | Subnet Mask | จำนวน Host | ตัวอย่างการใช้งาน |
|---|---|---|---|
| /8 | 255.0.0.0 | 16,777,214 | ISP ขนาดใหญ่ |
| /16 | 255.255.0.0 | 65,534 | องค์กรขนาดใหญ่ |
| /24 | 255.255.255.0 | 254 | สำนักงานขนาดเล็ก |
| /25 | 255.255.255.128 | 126 | แผนกงาน |
| /26 | 255.255.255.192 | 62 | ห้องประชุม |
| /27 | 255.255.255.224 | 30 | Server room |
| /28 | 255.255.255.240 | 14 | DMZ |
| /30 | 255.255.255.252 | 2 | Point-to-point link |
| /32 | 255.255.255.255 | 1 | Host route |
| ประเภท | ช่วงที่อยู่ | คำอธิบาย |
|---|---|---|
| Private Address | 10.0.0.0/8 | เครือข่ายส่วนตัวขนาดใหญ่ |
| 172.16.0.0/12 | เครือข่ายส่วนตัวขนาดกลาง | |
| 192.168.0.0/16 | เครือข่ายส่วนตัวขนาดเล็ก | |
| Loopback | 127.0.0.0/8 | ทดสอบภายในเครื่อง |
| Link-Local | 169.254.0.0/16 | APIPA (ไม่มี DHCP) |
| Multicast | 224.0.0.0/4 | ส่งถึงกลุ่มเครื่อง |
| Broadcast | 255.255.255.255 | ส่งถึงทุกเครื่องในเครือข่าย |
IPv6 (Internet Protocol version 6) คือโปรโตคอลรุ่นใหม่ที่ออกแบบมาเพื่อแทนที่ IPv4 โดยมีคุณสมบัติหลักดังนี้:
graph TB
subgraph IPv6Header["โครงสร้างส่วนหัว IPv6 - 40 ไบต์"]
direction TB
V1["Version (4) | Traffic Class (8) | Flow Label (20)"]
V2["Payload Length (16) | Next Header (8) | Hop Limit (8)"]
V3["Source Address (128 บิต)"]
V4["Destination Address (128 บิต)"]
V1 --> V2 --> V3 --> V4
end
style V1 fill:#458588,stroke:#83a598,color:#ebdbb2
style V2 fill:#d79921,stroke:#fabd2f,color:#282828
style V3 fill:#98971a,stroke:#b8bb26,color:#282828
style V4 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
| ฟิลด์ | ขนาด (บิต) | คำอธิบาย |
|---|---|---|
| Version | 4 | เวอร์ชันของ IP (6 สำหรับ IPv6) |
| Traffic Class | 8 | เทียบเท่า ToS ใน IPv4 |
| Flow Label | 20 | ระบุ flow สำหรับ QoS |
| Payload Length | 16 | ความยาวของ payload (ไม่รวมส่วนหัว) |
| Next Header | 8 | โปรโตคอลชั้นบนหรือ Extension Header |
| Hop Limit | 8 | เทียบเท่า TTL ใน IPv4 |
| Source Address | 128 | ที่อยู่ IPv6 ต้นทาง |
| Destination Address | 128 | ที่อยู่ IPv6 ปลายทาง |
ที่อยู่ IPv6 แสดงเป็น 8 กลุ่มของเลขฐาน 16 คั่นด้วยเครื่องหมาย colon (:)
รูปแบบเต็ม: 2001:0db8:0000:0000:0000:0000:0000:0001
กฎการย่อ:
2001:db8:0:0:0:0:0:1:: แทนกลุ่มที่เป็น 0 ติดกันได้ (ใช้ได้ครั้งเดียว): 2001:db8::1| ประเภทที่อยู่ | Prefix | ตัวอย่าง | คำอธิบาย |
|---|---|---|---|
| Global Unicast | 2000::/3 | 2001:db8::/32 | ที่อยู่สาธารณะ |
| Link-Local | fe80::/10 | fe80::1 | เฉพาะ link เดียว |
| Unique Local | fc00::/7 | fd00::/8 | เครือข่ายส่วนตัว |
| Multicast | ff00::/8 | ff02::1 | ส่งถึงกลุ่ม |
| Loopback | ::1/128 | ::1 | ทดสอบภายในเครื่อง |
| Unspecified | ::/128 | :: | ยังไม่กำหนดที่อยู่ |
ICMP (Internet Control Message Protocol) คือโปรโตคอลที่ใช้สำหรับส่งข้อความควบคุมและรายงานข้อผิดพลาดในชั้น Network โดย ICMP มีสองเวอร์ชัน:
หน้าที่หลักของ ICMP:
| Type | ชื่อ | คำอธิบาย |
|---|---|---|
| 0 | Echo Reply | ตอบกลับ Echo Request (ping) |
| 3 | Destination Unreachable | ไม่สามารถเข้าถึงปลายทางได้ |
| 4 | Source Quench | ขอให้ลดอัตราการส่ง (deprecated) |
| 5 | Redirect | แนะนำเส้นทางที่ดีกว่า |
| 8 | Echo Request | ขอให้ตอบกลับ (ping) |
| 9 | Router Advertisement | ประกาศตัวเราเตอร์ |
| 10 | Router Solicitation | ขอให้เราเตอร์ประกาศตัว |
| 11 | Time Exceeded | TTL หมดอายุ (ใช้ใน traceroute) |
| 12 | Parameter Problem | ปัญหาพารามิเตอร์ในส่วนหัว |
sequenceDiagram
participant H as โฮสต์ (Host)
participant R1 as เราเตอร์ 1
participant R2 as เราเตอร์ 2
participant D as ปลายทาง (Destination)
Note over H,D: กระบวนการ Ping (ICMP Echo)
H->>D: ICMP Echo Request (Type 8)
D->>H: ICMP Echo Reply (Type 0)
Note over H,D: กระบวนการ Traceroute
H->>R1: IP Packet (TTL=1)
R1->>H: ICMP Time Exceeded (Type 11)
Note right of H: บันทึก R1
H->>R2: IP Packet (TTL=2)
R2->>H: ICMP Time Exceeded (Type 11)
Note right of H: บันทึก R2
H->>D: IP Packet (TTL=3)
D->>H: ICMP Echo Reply (Type 0)
Note right of H: ถึงปลายทาง!
| ภัยคุกคาม | คำอธิบาย | การป้องกัน |
|---|---|---|
| ICMP Flood (Ping of Death) | ส่ง ICMP จำนวนมากเพื่อทำให้ระบบล่ม | จำกัดอัตรา ICMP ที่รับ |
| Smurf Attack | ส่ง ICMP Request ไปยัง broadcast address โดยปลอมที่อยู่ต้นทาง | บล็อก broadcast directed |
| ICMP Redirect Attack | ส่ง Redirect ปลอมเพื่อเปลี่ยนเส้นทาง | ปิดการรับ ICMP Redirect |
| Network Scanning | ใช้ ICMP ค้นหาโฮสต์ที่ใช้งาน | จำกัดการตอบ ICMP |
| คุณสมบัติ | IPv4 | IPv6 |
|---|---|---|
| ขนาดที่อยู่ | 32 บิต | 128 บิต |
| รูปแบบที่อยู่ | Dotted Decimal (192.168.1.1) | Hexadecimal (2001:db8::1) |
| จำนวนที่อยู่ | ~4.3 พันล้าน | ~3.4×10³⁸ |
| ขนาดส่วนหัว | 20-60 bytes | 40 bytes (คงที่) |
| Checksum | มี | ไม่มี (ใช้ของชั้นบน) |
| Fragmentation | ทำที่ Router ได้ | ทำที่ต้นทางเท่านั้น |
| Broadcast | มี | ไม่มี (ใช้ Multicast) |
| IPsec | Optional | Mandatory |
| Auto-configuration | DHCP | SLAAC + DHCPv6 |
| NAT | จำเป็น | ไม่จำเป็น |
การวิเคราะห์เครือข่าย (Network Analysis) คือกระบวนการตรวจสอบและทำความเข้าใจการทำงานของเครือข่าย โดยมีวัตถุประสงค์หลักดังนี้:
graph TB
subgraph Levels["ระดับการวิเคราะห์เครือข่าย"]
direction TB
L1["ระดับ 1: การเชื่อมต่อพื้นฐาน
(Connectivity Test)"]
L2["ระดับ 2: การวิเคราะห์เส้นทาง
(Path Analysis)"]
L3["ระดับ 3: การตรวจสอบบริการ
(Service Verification)"]
L4["ระดับ 4: การวิเคราะห์แพ็กเก็ต
(Packet Analysis)"]
L5["ระดับ 5: การวิเคราะห์เชิงลึก
(Deep Inspection)"]
L1 --> L2 --> L3 --> L4 --> L5
end
L1 -.- |"ping, arp"| T1["เครื่องมือ"]
L2 -.- |"traceroute, mtr"| T2["เครื่องมือ"]
L3 -.- |"ss, nc, curl"| T3["เครื่องมือ"]
L4 -.- |"tcpdump, Wireshark"| T4["เครื่องมือ"]
L5 -.- |"nmap, IDS/IPS"| T5["เครื่องมือ"]
style L1 fill:#98971a,stroke:#b8bb26,color:#282828
style L2 fill:#d79921,stroke:#fabd2f,color:#282828
style L3 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style L4 fill:#b16286,stroke:#d3869b,color:#ebdbb2
style L5 fill:#cc241d,stroke:#fb4934,color:#ebdbb2
| เมตริก | คำอธิบาย | สูตรคำนวณ/วิธีวัด | ค่าที่ดี |
|---|---|---|---|
| Latency | เวลาที่ใช้ส่งข้อมูลไป-กลับ | RTT จาก ping | < 100 ms |
| Bandwidth | ความจุของช่องสัญญาณ | iperf, speedtest | ตามข้อกำหนด |
| Throughput | ปริมาณข้อมูลที่ส่งได้จริง | iperf | ใกล้เคียง bandwidth |
| Packet Loss | เปอร์เซ็นต์แพ็กเก็ตที่หาย | ping -c 100 | < 1% |
| Jitter | ความแปรปรวนของ latency | mtr, iperf | < 30 ms |
| Availability | เปอร์เซ็นต์เวลาที่ใช้งานได้ | monitoring | > 99.9% |
สูตรคำนวณ Throughput:
สูตรคำนวณ Utilization:
คำสั่ง ip เป็นเครื่องมือหลักในการจัดการเครือข่ายบน Linux มาแทนที่คำสั่งเก่าอย่าง ifconfig, route, และ arp
"""
สคริปต์สำหรับจัดการ Network Interface ด้วย Python
ใช้ subprocess เรียกคำสั่ง ip
"""
import subprocess
import re
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class NetworkInterface:
"""
คลาสเก็บข้อมูล Network Interface
"""
name: str # ชื่อ interface
state: str # สถานะ (UP/DOWN)
mac_address: str # ที่อยู่ MAC
ipv4_address: Optional[str] = None # ที่อยู่ IPv4
ipv6_address: Optional[str] = None # ที่อยู่ IPv6
def run_command(command: List[str]) -> str:
"""
รันคำสั่งและคืนค่าผลลัพธ์
พารามิเตอร์:
command: รายการคำสั่งและอาร์กิวเมนต์
คืนค่า:
ผลลัพธ์จากคำสั่ง
"""
result = subprocess.run(
command,
capture_output=True,
text=True
)
return result.stdout
def get_interfaces() -> List[NetworkInterface]:
"""
ดึงข้อมูล Network Interface ทั้งหมด
คืนค่า:
รายการ NetworkInterface
"""
# รันคำสั่ง ip link show
output = run_command(['ip', 'link', 'show'])
interfaces = []
current_interface = None
for line in output.split('\n'):
# จับชื่อ interface และสถานะ
match = re.match(r'^\d+:\s+(\S+):.*<(.*)>', line)
if match:
name = match.group(1)
flags = match.group(2)
state = 'UP' if 'UP' in flags else 'DOWN'
current_interface = {'name': name, 'state': state}
# จับ MAC address
mac_match = re.search(r'link/ether\s+([0-9a-f:]+)', line)
if mac_match and current_interface:
current_interface['mac'] = mac_match.group(1)
interfaces.append(current_interface)
current_interface = None
# ดึงที่อยู่ IP สำหรับแต่ละ interface
result = []
for iface in interfaces:
addr_output = run_command(['ip', 'addr', 'show', iface['name']])
# หา IPv4
ipv4_match = re.search(r'inet\s+(\d+\.\d+\.\d+\.\d+/\d+)', addr_output)
# หา IPv6
ipv6_match = re.search(r'inet6\s+([0-9a-f:]+/\d+)', addr_output)
result.append(NetworkInterface(
name=iface['name'],
state=iface['state'],
mac_address=iface.get('mac', 'N/A'),
ipv4_address=ipv4_match.group(1) if ipv4_match else None,
ipv6_address=ipv6_match.group(1) if ipv6_match else None
))
return result
def get_routing_table() -> str:
"""
ดึงตาราง routing
คืนค่า:
ตาราง routing ในรูปแบบข้อความ
"""
return run_command(['ip', 'route', 'show'])
def get_arp_table() -> str:
"""
ดึงตาราง ARP (neighbor)
คืนค่า:
ตาราง ARP ในรูปแบบข้อความ
"""
return run_command(['ip', 'neighbor', 'show'])
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
print("=== Network Interfaces ===")
for iface in get_interfaces():
print(f"\nInterface: {iface.name}")
print(f" สถานะ: {iface.state}")
print(f" MAC: {iface.mac_address}")
print(f" IPv4: {iface.ipv4_address or 'ไม่มี'}")
print(f" IPv6: {iface.ipv6_address or 'ไม่มี'}")
print("\n=== Routing Table ===")
print(get_routing_table())
print("\n=== ARP Table ===")
print(get_arp_table())
| คำสั่ง | คำอธิบาย |
|---|---|
ip link show |
แสดง interface ทั้งหมด |
ip addr show |
แสดงที่อยู่ IP ทั้งหมด |
ip addr add 192.168.1.10/24 dev eth0 |
เพิ่มที่อยู่ IP |
ip addr del 192.168.1.10/24 dev eth0 |
ลบที่อยู่ IP |
ip link set eth0 up |
เปิด interface |
ip link set eth0 down |
ปิด interface |
ip route show |
แสดงตาราง routing |
ip route add default via 192.168.1.1 |
เพิ่ม default gateway |
ip neighbor show |
แสดงตาราง ARP |
คำสั่ง ping ใช้ส่ง ICMP Echo Request ไปยังโฮสต์ปลายทาง และรอรับ ICMP Echo Reply กลับมา เพื่อทดสอบการเชื่อมต่อและวัด latency
"""
สคริปต์ Ping ด้วย Python
ใช้ ICMP socket (ต้องรันด้วยสิทธิ์ root)
"""
import socket
import struct
import time
import os
from typing import Tuple, Optional
def calculate_checksum(data: bytes) -> int:
"""
คำนวณ ICMP checksum
พารามิเตอร์:
data: ข้อมูลที่ต้องการคำนวณ checksum
คืนค่า:
ค่า checksum 16 บิต
"""
checksum = 0
count_to = (len(data) // 2) * 2
# รวมทีละ 2 bytes
for i in range(0, count_to, 2):
checksum += (data[i] << 8) + data[i + 1]
# ถ้ามี byte เหลือ
if count_to < len(data):
checksum += data[-1] << 8
# พับ carry
checksum = (checksum >> 16) + (checksum & 0xFFFF)
checksum += checksum >> 16
# One's complement
return ~checksum & 0xFFFF
def create_icmp_packet(sequence: int, payload_size: int = 56) -> bytes:
"""
สร้าง ICMP Echo Request packet
พารามิเตอร์:
sequence: หมายเลขลำดับ
payload_size: ขนาด payload (default: 56 bytes)
คืนค่า:
ICMP packet ในรูปแบบ bytes
"""
icmp_type = 8 # Echo Request
icmp_code = 0
icmp_checksum = 0
icmp_id = os.getpid() & 0xFFFF
icmp_seq = sequence
# สร้าง payload
payload = bytes([i & 0xFF for i in range(payload_size)])
# สร้าง header (ยังไม่มี checksum)
header = struct.pack('!BBHHH',
icmp_type,
icmp_code,
icmp_checksum,
icmp_id,
icmp_seq)
# คำนวณ checksum
icmp_checksum = calculate_checksum(header + payload)
# สร้าง header ใหม่พร้อม checksum
header = struct.pack('!BBHHH',
icmp_type,
icmp_code,
icmp_checksum,
icmp_id,
icmp_seq)
return header + payload
def parse_icmp_reply(data: bytes) -> Tuple[int, int, int]:
"""
แยกวิเคราะห์ ICMP Reply
พารามิเตอร์:
data: ข้อมูลที่ได้รับ
คืนค่า:
(type, code, sequence)
"""
# ข้าม IP header (20 bytes)
icmp_header = data[20:28]
icmp_type, icmp_code, _, _, icmp_seq = struct.unpack('!BBHHH', icmp_header)
return icmp_type, icmp_code, icmp_seq
def ping(host: str, count: int = 4, timeout: float = 2.0) -> dict:
"""
ส่ง ping ไปยังโฮสต์
พารามิเตอร์:
host: ที่อยู่ IP หรือ hostname
count: จำนวนครั้งที่ส่ง
timeout: เวลารอสูงสุด (วินาที)
คืนค่า:
ผลลัพธ์การ ping
"""
try:
# แปลง hostname เป็น IP
dest_ip = socket.gethostbyname(host)
except socket.gaierror:
return {'error': f'ไม่พบโฮสต์: {host}'}
# สร้าง raw socket สำหรับ ICMP
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
sock.settimeout(timeout)
except PermissionError:
return {'error': 'ต้องรันด้วยสิทธิ์ root'}
results = {
'host': host,
'ip': dest_ip,
'sent': count,
'received': 0,
'lost': 0,
'rtt_list': [],
'min_rtt': None,
'max_rtt': None,
'avg_rtt': None
}
print(f"PING {host} ({dest_ip}): 56 data bytes")
for seq in range(count):
# สร้างและส่ง ICMP packet
packet = create_icmp_packet(seq)
send_time = time.time()
try:
sock.sendto(packet, (dest_ip, 0))
# รอรับการตอบกลับ
data, addr = sock.recvfrom(1024)
recv_time = time.time()
# วิเคราะห์การตอบกลับ
icmp_type, icmp_code, reply_seq = parse_icmp_reply(data)
if icmp_type == 0: # Echo Reply
rtt = (recv_time - send_time) * 1000 # แปลงเป็น ms
results['received'] += 1
results['rtt_list'].append(rtt)
print(f"64 bytes from {addr[0]}: icmp_seq={reply_seq} time={rtt:.3f} ms")
else:
print(f"ICMP type={icmp_type} code={icmp_code}")
except socket.timeout:
print(f"Request timeout for icmp_seq {seq}")
results['lost'] += 1
# รอก่อนส่งครั้งถัดไป
time.sleep(1)
sock.close()
# คำนวณสถิติ
if results['rtt_list']:
results['min_rtt'] = min(results['rtt_list'])
results['max_rtt'] = max(results['rtt_list'])
results['avg_rtt'] = sum(results['rtt_list']) / len(results['rtt_list'])
results['loss_rate'] = (results['lost'] / results['sent']) * 100
return results
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
import sys
target = sys.argv[1] if len(sys.argv) > 1 else '8.8.8.8'
result = ping(target, count=4)
if 'error' in result:
print(f"\nข้อผิดพลาด: {result['error']}")
else:
print(f"\n--- {result['host']} ping statistics ---")
print(f"{result['sent']} packets transmitted, "
f"{result['received']} received, "
f"{result['loss_rate']:.1f}% packet loss")
if result['avg_rtt']:
print(f"rtt min/avg/max = "
f"{result['min_rtt']:.3f}/"
f"{result['avg_rtt']:.3f}/"
f"{result['max_rtt']:.3f} ms")
| คำสั่ง | คำอธิบาย |
|---|---|
ping 8.8.8.8 |
ping ไปยัง Google DNS |
ping -c 5 google.com |
ping 5 ครั้ง |
ping -i 0.5 192.168.1.1 |
ping ทุก 0.5 วินาที |
ping -s 1000 host |
กำหนดขนาด payload 1000 bytes |
ping -t 10 host |
กำหนด TTL เป็น 10 |
ping -W 1 host |
timeout 1 วินาที |
ping6 ::1 |
ping IPv6 loopback |
คำสั่ง traceroute ใช้ติดตามเส้นทางที่แพ็กเก็ตเดินทางจากต้นทางไปยังปลายทาง โดยอาศัยหลักการของ TTL และ ICMP Time Exceeded
sequenceDiagram
participant S as ต้นทาง (Source)
participant R1 as Router 1
participant R2 as Router 2
participant R3 as Router 3
participant D as ปลายทาง (Destination)
Note over S,D: Traceroute Process
S->>R1: Probe 1 (TTL=1)
R1->>S: ICMP Time Exceeded
Note right of S: Hop 1: R1 ✓
S->>R1: Probe 2 (TTL=2)
R1->>R2: Forward (TTL=1)
R2->>S: ICMP Time Exceeded
Note right of S: Hop 2: R2 ✓
S->>R1: Probe 3 (TTL=3)
R1->>R2: Forward (TTL=2)
R2->>R3: Forward (TTL=1)
R3->>S: ICMP Time Exceeded
Note right of S: Hop 3: R3 ✓
S->>R1: Probe 4 (TTL=4)
R1->>R2: Forward (TTL=3)
R2->>R3: Forward (TTL=2)
R3->>D: Forward (TTL=1)
D->>S: ICMP Port Unreachable / Echo Reply
Note right of S: ถึงปลายทาง!
| คำสั่ง | คำอธิบาย |
|---|---|
traceroute google.com |
traceroute ปกติ (UDP) |
traceroute -I google.com |
ใช้ ICMP แทน UDP |
traceroute -T google.com |
ใช้ TCP SYN |
traceroute -m 20 host |
กำหนด max hops เป็น 20 |
traceroute -q 5 host |
ส่ง 5 probes ต่อ hop |
traceroute -n host |
ไม่ resolve DNS |
traceroute6 ipv6.google.com |
traceroute IPv6 |
คำสั่ง ss (Socket Statistics) ใช้แสดงข้อมูลเกี่ยวกับ socket และการเชื่อมต่อเครือข่าย มาแทนที่คำสั่ง netstat
"""
สคริปต์วิเคราะห์การเชื่อมต่อเครือข่ายด้วย Python
แยกวิเคราะห์ผลลัพธ์จากคำสั่ง ss
"""
import subprocess
import re
from dataclasses import dataclass
from typing import List, Dict
from collections import Counter
@dataclass
class SocketConnection:
"""
คลาสเก็บข้อมูลการเชื่อมต่อ Socket
"""
protocol: str # TCP, UDP
state: str # LISTEN, ESTABLISHED, etc.
recv_q: int # Receive queue
send_q: int # Send queue
local_address: str # ที่อยู่และพอร์ตภายใน
peer_address: str # ที่อยู่และพอร์ตของ peer
process: str = "" # ชื่อ process (ถ้ามี)
def get_socket_stats() -> List[SocketConnection]:
"""
ดึงข้อมูล socket ทั้งหมด
คืนค่า:
รายการ SocketConnection
"""
# รันคำสั่ง ss -tunap
# t = TCP, u = UDP, n = numeric, a = all, p = process
result = subprocess.run(
['ss', '-tunap'],
capture_output=True,
text=True
)
connections = []
lines = result.stdout.strip().split('\n')[1:] # ข้าม header
for line in lines:
parts = line.split()
if len(parts) >= 5:
conn = SocketConnection(
protocol=parts[0],
state=parts[1],
recv_q=int(parts[2]),
send_q=int(parts[3]),
local_address=parts[4],
peer_address=parts[5] if len(parts) > 5 else '*:*',
process=parts[-1] if 'users:' in line else ''
)
connections.append(conn)
return connections
def analyze_connections(connections: List[SocketConnection]) -> Dict:
"""
วิเคราะห์การเชื่อมต่อ
พารามิเตอร์:
connections: รายการการเชื่อมต่อ
คืนค่า:
ผลการวิเคราะห์
"""
analysis = {
'total': len(connections),
'by_protocol': Counter(),
'by_state': Counter(),
'listening_ports': [],
'established': [],
'high_recv_q': [], # connections ที่มี recv queue สูง
}
for conn in connections:
analysis['by_protocol'][conn.protocol] += 1
analysis['by_state'][conn.state] += 1
if conn.state == 'LISTEN':
# ดึงพอร์ตที่ listening
port = conn.local_address.split(':')[-1]
analysis['listening_ports'].append({
'port': port,
'address': conn.local_address,
'process': conn.process
})
elif conn.state == 'ESTAB':
analysis['established'].append({
'local': conn.local_address,
'peer': conn.peer_address,
'process': conn.process
})
# ตรวจสอบ recv queue ที่สูง
if conn.recv_q > 1000:
analysis['high_recv_q'].append({
'connection': f"{conn.local_address} -> {conn.peer_address}",
'recv_q': conn.recv_q
})
return analysis
def print_report(analysis: Dict):
"""
พิมพ์รายงานการวิเคราะห์
พารามิเตอร์:
analysis: ผลการวิเคราะห์
"""
print("=" * 50)
print("รายงานการวิเคราะห์การเชื่อมต่อเครือข่าย")
print("=" * 50)
print(f"\nจำนวนการเชื่อมต่อทั้งหมด: {analysis['total']}")
print("\n--- แยกตามโปรโตคอล ---")
for proto, count in analysis['by_protocol'].items():
print(f" {proto}: {count}")
print("\n--- แยกตามสถานะ ---")
for state, count in analysis['by_state'].items():
print(f" {state}: {count}")
print(f"\n--- พอร์ตที่ Listening ({len(analysis['listening_ports'])}) ---")
for port_info in analysis['listening_ports'][:10]:
print(f" {port_info['address']} {port_info['process']}")
if analysis['high_recv_q']:
print(f"\n--- การเชื่อมต่อที่มี Recv Queue สูง ---")
for conn in analysis['high_recv_q']:
print(f" {conn['connection']}: {conn['recv_q']} bytes")
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
connections = get_socket_stats()
analysis = analyze_connections(connections)
print_report(analysis)
| คำสั่ง | คำอธิบาย |
|---|---|
ss -t |
แสดง TCP connections |
ss -u |
แสดง UDP connections |
ss -l |
แสดงเฉพาะ listening sockets |
ss -a |
แสดงทั้งหมด (listening + non-listening) |
ss -n |
แสดงหมายเลขพอร์ต (ไม่ resolve) |
ss -p |
แสดง process ที่ใช้ socket |
ss -s |
แสดงสรุปสถิติ |
ss -t state established |
แสดงเฉพาะ ESTABLISHED |
ss 'sport = :22' |
กรองเฉพาะ source port 22 |
ss 'dport = :443' |
กรองเฉพาะ destination port 443 |
ARP (Address Resolution Protocol) ใช้แปลงที่อยู่ IP เป็นที่อยู่ MAC สำหรับการส่งข้อมูลในเครือข่ายท้องถิ่น (LAN)
sequenceDiagram
participant A as Host A
192.168.1.10
MAC: AA:AA:AA:AA:AA:AA
participant B as Host B
192.168.1.20
MAC: BB:BB:BB:BB:BB:BB
participant BC as Broadcast
Note over A,B: ARP Request/Reply Process
A->>BC: ARP Request (Broadcast)
Who has 192.168.1.20?
Tell 192.168.1.10
Note over A: ส่ง broadcast
ไปทุกเครื่องในเครือข่าย
B->>A: ARP Reply (Unicast)
192.168.1.20 is at
BB:BB:BB:BB:BB:BB
Note over A: บันทึกลง
ARP Cache
Note over A,B: ตอนนี้ Host A รู้ MAC ของ Host B แล้ว
A->>B: Data Frame
Src MAC: AA:AA...
Dst MAC: BB:BB...
| คำสั่ง | คำอธิบาย |
|---|---|
arp -a |
แสดง ARP table ทั้งหมด |
arp -n |
แสดง ARP table (ไม่ resolve) |
ip neighbor show |
แสดง neighbor table (แทน arp) |
ip neighbor add 192.168.1.100 lladdr AA:BB:CC:DD:EE:FF dev eth0 |
เพิ่ม static entry |
ip neighbor del 192.168.1.100 dev eth0 |
ลบ entry |
ip neighbor flush dev eth0 |
ล้าง ARP cache |
Wireshark คือเครื่องมือวิเคราะห์แพ็กเก็ตแบบกราฟิก (GUI) ที่ทรงพลังที่สุด สามารถ:
| Filter | คำอธิบาย |
|---|---|
ip.addr == 192.168.1.1 |
แพ็กเก็ตที่มี IP นี้ |
ip.src == 10.0.0.1 |
แพ็กเก็ตจาก IP นี้ |
ip.dst == 8.8.8.8 |
แพ็กเก็ตไปยัง IP นี้ |
tcp |
เฉพาะ TCP |
udp |
เฉพาะ UDP |
icmp |
เฉพาะ ICMP |
tcp.port == 80 |
TCP port 80 |
tcp.flags.syn == 1 |
TCP SYN packets |
http |
HTTP traffic |
dns |
DNS traffic |
tcp.analysis.retransmission |
TCP retransmissions |
frame.time >= "2024-01-01" |
หลังวันที่กำหนด |
"""
สคริปต์วิเคราะห์แพ็กเก็ตด้วย scapy
ต้องติดตั้ง: pip install scapy
"""
try:
from scapy.all import sniff, IP, TCP, UDP, ICMP, ARP
from scapy.layers.http import HTTPRequest
SCAPY_AVAILABLE = True
except ImportError:
SCAPY_AVAILABLE = False
from datetime import datetime
from collections import Counter
from typing import Dict, List
import time
class PacketAnalyzer:
"""
คลาสสำหรับวิเคราะห์แพ็กเก็ต
"""
def __init__(self):
"""
กำหนดค่าเริ่มต้น
"""
self.packets = []
self.stats = {
'total': 0,
'protocols': Counter(),
'src_ips': Counter(),
'dst_ips': Counter(),
'ports': Counter(),
'packet_sizes': []
}
def packet_callback(self, packet):
"""
Callback function สำหรับทุกแพ็กเก็ตที่จับได้
พารามิเตอร์:
packet: แพ็กเก็ตที่จับได้
"""
self.stats['total'] += 1
self.packets.append(packet)
# วิเคราะห์ IP layer
if IP in packet:
ip_layer = packet[IP]
self.stats['src_ips'][ip_layer.src] += 1
self.stats['dst_ips'][ip_layer.dst] += 1
self.stats['packet_sizes'].append(len(packet))
# ระบุโปรโตคอล
if TCP in packet:
self.stats['protocols']['TCP'] += 1
tcp_layer = packet[TCP]
self.stats['ports'][tcp_layer.dport] += 1
self._print_tcp_info(packet)
elif UDP in packet:
self.stats['protocols']['UDP'] += 1
udp_layer = packet[UDP]
self.stats['ports'][udp_layer.dport] += 1
self._print_udp_info(packet)
elif ICMP in packet:
self.stats['protocols']['ICMP'] += 1
self._print_icmp_info(packet)
elif ARP in packet:
self.stats['protocols']['ARP'] += 1
self._print_arp_info(packet)
def _print_tcp_info(self, packet):
"""แสดงข้อมูล TCP packet"""
ip = packet[IP]
tcp = packet[TCP]
flags = tcp.sprintf('%TCP.flags%')
print(f"[TCP] {ip.src}:{tcp.sport} -> {ip.dst}:{tcp.dport} "
f"[{flags}] Len={len(packet)}")
def _print_udp_info(self, packet):
"""แสดงข้อมูล UDP packet"""
ip = packet[IP]
udp = packet[UDP]
print(f"[UDP] {ip.src}:{udp.sport} -> {ip.dst}:{udp.dport} "
f"Len={len(packet)}")
def _print_icmp_info(self, packet):
"""แสดงข้อมูล ICMP packet"""
ip = packet[IP]
icmp = packet[ICMP]
print(f"[ICMP] {ip.src} -> {ip.dst} "
f"Type={icmp.type} Code={icmp.code}")
def _print_arp_info(self, packet):
"""แสดงข้อมูล ARP packet"""
arp = packet[ARP]
op = "Request" if arp.op == 1 else "Reply"
print(f"[ARP {op}] {arp.psrc} ({arp.hwsrc}) -> "
f"{arp.pdst} ({arp.hwdst})")
def start_capture(self, interface: str = None, count: int = 100,
filter_str: str = None):
"""
เริ่มจับแพ็กเก็ต
พารามิเตอร์:
interface: ชื่อ interface (None = ทั้งหมด)
count: จำนวนแพ็กเก็ตที่จะจับ
filter_str: BPF filter string
"""
if not SCAPY_AVAILABLE:
print("ต้องติดตั้ง scapy: pip install scapy")
return
print(f"เริ่มจับแพ็กเก็ต (จำนวน: {count})...")
print("=" * 60)
sniff(
iface=interface,
count=count,
filter=filter_str,
prn=self.packet_callback,
store=False
)
def print_summary(self):
"""
พิมพ์สรุปการวิเคราะห์
"""
print("\n" + "=" * 60)
print("สรุปการวิเคราะห์แพ็กเก็ต")
print("=" * 60)
print(f"\nจำนวนแพ็กเก็ตทั้งหมด: {self.stats['total']}")
print("\n--- โปรโตคอล ---")
for proto, count in self.stats['protocols'].most_common():
print(f" {proto}: {count}")
print("\n--- Top 5 Source IPs ---")
for ip, count in self.stats['src_ips'].most_common(5):
print(f" {ip}: {count}")
print("\n--- Top 5 Destination IPs ---")
for ip, count in self.stats['dst_ips'].most_common(5):
print(f" {ip}: {count}")
print("\n--- Top 5 Destination Ports ---")
for port, count in self.stats['ports'].most_common(5):
service = self._get_service_name(port)
print(f" {port} ({service}): {count}")
if self.stats['packet_sizes']:
avg_size = sum(self.stats['packet_sizes']) / len(self.stats['packet_sizes'])
print(f"\n--- ขนาดแพ็กเก็ต ---")
print(f" เฉลี่ย: {avg_size:.1f} bytes")
print(f" ต่ำสุด: {min(self.stats['packet_sizes'])} bytes")
print(f" สูงสุด: {max(self.stats['packet_sizes'])} bytes")
def _get_service_name(self, port: int) -> str:
"""แปลงหมายเลขพอร์ตเป็นชื่อบริการ"""
services = {
20: 'FTP-DATA', 21: 'FTP', 22: 'SSH', 23: 'TELNET',
25: 'SMTP', 53: 'DNS', 67: 'DHCP', 68: 'DHCP',
80: 'HTTP', 110: 'POP3', 143: 'IMAP', 443: 'HTTPS',
3306: 'MySQL', 5432: 'PostgreSQL', 6379: 'Redis'
}
return services.get(port, 'Unknown')
# ตัวอย่างการใช้งาน
if __name__ == "__main__":
analyzer = PacketAnalyzer()
# จับ 50 แพ็กเก็ต กรองเฉพาะ TCP
# ต้องรันด้วยสิทธิ์ root
try:
analyzer.start_capture(count=50, filter_str="tcp")
analyzer.print_summary()
except PermissionError:
print("ต้องรันด้วยสิทธิ์ root: sudo python script.py")
| คำสั่ง | คำอธิบาย |
|---|---|
tcpdump -i eth0 |
จับแพ็กเก็ตบน eth0 |
tcpdump -c 100 |
จับ 100 แพ็กเก็ต |
tcpdump -w capture.pcap |
บันทึกลงไฟล์ |
tcpdump -r capture.pcap |
อ่านจากไฟล์ |
tcpdump host 192.168.1.1 |
กรองตาม host |
tcpdump port 80 |
กรองตาม port |
tcpdump tcp |
เฉพาะ TCP |
tcpdump 'tcp[tcpflags] & tcp-syn != 0' |
เฉพาะ SYN packets |
tcpdump -n -v |
ไม่ resolve DNS, verbose |
เอกสารนี้ครอบคลุมหัวข้อสำคัญของ โปรโตคอลเครือข่ายและการวิเคราะห์ ดังนี้:
โปรโตคอลชั้นขนส่ง (Transport Layer)
TCP (Transmission Control Protocol): โปรโตคอลแบบ connection-oriented ที่ให้บริการส่งข้อมูลอย่างเชื่อถือได้ มีกลไก flow control และ congestion control เหมาะสำหรับแอปพลิเคชันที่ต้องการความถูกต้องของข้อมูล เช่น HTTP, FTP, SMTP
UDP (User Datagram Protocol): โปรโตคอลแบบ connectionless ที่เรียบง่ายและรวดเร็ว เหมาะสำหรับแอปพลิเคชันที่ต้องการความเร็วและทนต่อการสูญหายของข้อมูลได้ เช่น DNS, VoIP, Video Streaming
โปรโตคอลชั้นเครือข่าย (Network Layer)
IPv4: โปรโตคอลมาตรฐานที่ใช้ที่อยู่ 32 บิต รองรับประมาณ 4.3 พันล้านที่อยู่ มีระบบ class และ CIDR สำหรับการจัดสรรที่อยู่
IPv6: โปรโตคอลรุ่นใหม่ที่ใช้ที่อยู่ 128 บิต แก้ปัญหาที่อยู่หมด มีความปลอดภัยในตัว และรองรับ auto-configuration
ICMP: โปรโตคอลสำหรับส่งข้อความควบคุมและรายงานข้อผิดพลาด ใช้ในเครื่องมือวินิจฉัยอย่าง ping และ traceroute
เครื่องมือวิเคราะห์เครือข่าย
| เครื่องมือ | หน้าที่หลัก | ระดับการวิเคราะห์ |
|---|---|---|
ip |
จัดการ interface, routing, ARP | พื้นฐาน |
ping |
ทดสอบการเชื่อมต่อ | การเชื่อมต่อ |
traceroute |
ติดตามเส้นทาง | เส้นทาง |
ss |
ตรวจสอบ socket และการเชื่อมต่อ | บริการ |
arp |
จัดการ ARP table | การแปลงที่อยู่ |
Wireshark/tcpdump |
วิเคราะห์แพ็กเก็ตเชิงลึก | แพ็กเก็ต |
graph TB
subgraph Application["ชั้น Application"]
HTTP["HTTP/HTTPS"]
FTP["FTP/SFTP"]
DNS["DNS"]
VOIP["VoIP"]
end
subgraph Transport["ชั้น Transport"]
TCP["TCP
Connection-oriented
Reliable"]
UDP["UDP
Connectionless
Fast"]
end
subgraph Network["ชั้น Network"]
IPv4["IPv4
32-bit address"]
IPv6["IPv6
128-bit address"]
ICMP["ICMP
Control messages"]
end
subgraph Tools["เครื่องมือวิเคราะห์"]
PING["ping"]
TRACE["traceroute"]
SS["ss"]
WIRE["Wireshark"]
end
HTTP --> TCP
FTP --> TCP
DNS --> UDP
VOIP --> UDP
TCP --> IPv4
TCP --> IPv6
UDP --> IPv4
UDP --> IPv6
ICMP --> IPv4
ICMP --> IPv6
PING -.-> ICMP
TRACE -.-> ICMP
SS -.-> TCP
SS -.-> UDP
WIRE -.-> TCP
WIRE -.-> UDP
WIRE -.-> ICMP
style TCP fill:#458588,stroke:#83a598,color:#ebdbb2
style UDP fill:#98971a,stroke:#b8bb26,color:#282828
style IPv4 fill:#d79921,stroke:#fabd2f,color:#282828
style IPv6 fill:#d65d0e,stroke:#fe8019,color:#ebdbb2
style ICMP fill:#b16286,stroke:#d3869b,color:#ebdbb2
TCP vs UDP: เลือกใช้ตามความต้องการของแอปพลิเคชัน - TCP สำหรับความน่าเชื่อถือ, UDP สำหรับความเร็ว
IPv4 vs IPv6: IPv6 คืออนาคต แต่ปัจจุบันยังต้องใช้ Dual Stack
การวิเคราะห์เครือข่าย: เริ่มจากเครื่องมือง่ายๆ (ping) ก่อนใช้เครื่องมือซับซ้อน (Wireshark)
ความปลอดภัย: ICMP และ ARP เป็นช่องทางโจมตีที่พบบ่อย ควรจำกัดการใช้งาน
การเฝ้าระวัง: ตรวจสอบ Recv Queue, Packet Loss, และ Latency อย่างสม่ำเสมอ
| RFC | ชื่อ | คำอธิบาย |
|---|---|---|
| RFC 791 | Internet Protocol | IPv4 Specification |
| RFC 792 | Internet Control Message Protocol | ICMP for IPv4 |
| RFC 793 | Transmission Control Protocol | TCP Specification |
| RFC 768 | User Datagram Protocol | UDP Specification |
| RFC 8200 | Internet Protocol, Version 6 | IPv6 Specification |
| RFC 4443 | ICMPv6 | ICMP for IPv6 |
| RFC 5681 | TCP Congestion Control | TCP CC Algorithms |
| RFC 6335 | Port Numbers | IANA Port Assignments |
Computer Networking: A Top-Down Approach - James F. Kurose, Keith W. Ross
TCP/IP Illustrated, Volume 1 - W. Richard Stevens
Wireshark Network Analysis - Laura Chappell
Network Security Essentials - William Stallings
| เครื่องมือ | ลิงก์ | ใบอนุญาต |
|---|---|---|
| Wireshark | https://www.wireshark.org/ | GPL |
| Nmap | https://nmap.org/ | GPL |
| iPerf3 | https://iperf.fr/ | BSD |
| mtr | https://github.com/traviscross/mtr | GPL |
| Scapy | https://scapy.net/ | GPL |