TCP, HTTP & Web cho Backend/Module 1 — Tổng kết & cheat sheet
10/29
Bài 10 / 29~15 phútTCP & UDP Deep DiveMiễn phí lượt xem

Module 1 — Tổng kết & cheat sheet

Recap TCP/UDP deep dive: state machine đầy đủ, bảng so sánh TCP vs UDP, bảng tra lỗi mạng, glossary 20 thuật ngữ, pitfall tổng hợp và self-assessment.

TL;DR: Module 1 đào sâu tầng Transport — từ 3-way handshake đến TIME_WAIT, từ slow start đến PMTUD black-hole. Đây là một trang để bookmark: TCP state machine đầy đủ, bảng so sánh TCP vs UDP, bảng tra lỗi mạng (ECONNREFUSED/RESET/ETIMEDOUT), glossary 20 thuật ngữ và 5 pitfall lớn nhất. Nếu bạn giải thích được handshake, chẩn đoán được TIME_WAIT/CLOSE_WAIT và chọn đúng TCP vs UDP theo bài toán, bạn đã sẵn sàng cho Module 2 — HTTP & Web.

Đã đi qua những gì

Bạn bắt đầu từ bài 00 — Tổng quan module: tầng Transport không chỉ "gửi byte" — nó quyết định gửi như thế nào (tin cậy hay nhanh, có thứ tự hay không).

Bài 01 mổ xẻ 3-way handshake: ba gói SYN/SYN-ACK/ACK để đồng bộ ISN cho cả hai chiều full-duplex, tốn 1 RTT trước byte dữ liệu đầu tiên — động lực trực tiếp của keep-alive và connection pool.

Bài 02 đi vào TCP reliability: sequence number đánh dấu từng byte, ACK xác nhận đã nhận tới đâu, retransmission với exponential backoff khi mất gói. SACK giúp retransmit đúng mảnh thiếu thay vì retransmit toàn bộ.

Bài 03 giải thích flow control (rwnd — receiver nói "tôi chứa được bao nhiêu") và congestion control (cwnd — sender tự điều tiết theo tình trạng mạng): slow start, congestion avoidance, fast retransmit, CUBIC/BBR.

Bài 04 đào sâu TIME_WAIT và CLOSE_WAIT: tại sao kết nối đóng rồi vẫn chiếm port 2×MSL, CLOSE_WAIT sinh ra khi ứng dụng quên gọi close(), và hậu quả khi cạn ephemeral port ở tải cao.

Bài 05 so sánh TCP vs UDP: UDP không handshake, không retransmit, không thứ tự — đổi lại latency thấp và phù hợp với bài toán cần kiểm soát retransmit ở tầng ứng dụng (game, video, QUIC).

Bài 06 kết nối lý thuyết vào thực chiến: connection pool và HTTP keep-alive tái dùng kết nối để tránh trả handshake nhiều lần; TCP keep-alive phát hiện connection chết.

Bài 07 phân tích bốn lỗi mạng kinh điển: ECONNREFUSED (không ai listen, có RST ngay), ECONNRESET (kết nối bị phá giữa chừng), ETIMEDOUT (gói bị nuốt im lặng), EADDRINUSE (port bị chiếm). Mỗi lỗi chỉ về một chặng hỏng khác nhau.

Bài 08 giải thích tại sao ping được mà app timeout: MTU 1500 byte, fragmentation, PMTUD — và PMTUD black-hole khi firewall chặn ICMP "Fragmentation Needed" khiến gói lớn bị drop âm thầm.

🗺️ Cheat sheet

TCP state machine — toàn bộ vòng đời kết nối

stateDiagram-v2
    [*] --> CLOSED
    CLOSED --> LISTEN: passive open (server)
    CLOSED --> SYN_SENT: active open / SYN
    LISTEN --> SYN_RCVD: SYN / SYN-ACK
    SYN_SENT --> ESTABLISHED: SYN-ACK / ACK
    SYN_RCVD --> ESTABLISHED: ACK
    ESTABLISHED --> FIN_WAIT_1: close / FIN (chu dong dong)
    ESTABLISHED --> CLOSE_WAIT: FIN / ACK (thu dong)
    CLOSE_WAIT --> LAST_ACK: close / FIN
    FIN_WAIT_1 --> FIN_WAIT_2: ACK
    FIN_WAIT_1 --> CLOSING: FIN / ACK
    FIN_WAIT_2 --> TIME_WAIT: FIN / ACK
    CLOSING --> TIME_WAIT: ACK
    LAST_ACK --> CLOSED: ACK
    TIME_WAIT --> CLOSED: 2xMSL timeout

Đọc state machine với ss:

# Xem tat ca ket noi voi state
ss -tan
# State       Recv-Q  Send-Q  Local Address:Port  Peer Address:Port
# LISTEN      0       128     0.0.0.0:8080
# ESTABLISHED 0       0       10.0.0.5:8080       10.0.0.1:54321
# TIME_WAIT   0       0       10.0.0.5:8080       10.0.0.1:54320
# CLOSE_WAIT  42      0       10.0.0.5:8080       10.0.0.1:54319

# Loc theo state
ss -tan state time-wait | wc -l   # bao nhieu TIME_WAIT?
ss -tan state close-wait          # ung dung quen close()?

So sánh TCP vs UDP

Tiêu chíTCPUDP
Kết nốiCần handshake (1 RTT)Không cần
Tin cậyCó (ACK + retransmit)Không — ứng dụng tự xử lý
Thứ tựĐảm bảoKhông đảm bảo
Flow controlCó (rwnd)Không
Congestion controlCó (cwnd, slow start)Không
Overhead header20 byte8 byte
LatencyCao hơn (handshake + ACK)Thấp hơn
Dùng choHTTP, database, file transfer, SSHDNS, video stream, game, QUIC/HTTP3
RetransmitOS tự độngỨng dụng tự quyết định

Quy tắc chọn: dùng TCP khi mất một byte là không chấp nhận được. Dùng UDP khi gói cũ (stale) còn tệ hơn không có gói — như video call, game real-time, hoặc khi ứng dụng muốn kiểm soát hoàn toàn retransmit logic (QUIC).

Bảng tra lỗi mạng

LỗiTốc độ xuất hiệnNguyên nhân phổ biếnCông cụ xác nhận
ECONNREFUSEDTức thì (dưới 1s)Không có process LISTEN ở portss -tlnp, nc -zv
ECONNRESETBất kỳ lúcServer crash, LB idle timeout, pool connection chếttcpdump xem RST, check LB log
ETIMEDOUTSau 30-127s (SYN)Firewall DROP, route hỏng, backlog đầy, PMTUD black-holetcpdump không thấy SYN-ACK
EADDRINUSEKhi bind portTIME_WAIT hoặc process khác giữ portss -tlnp, lsof -i :<port>
EPIPEKhi writePeer đã đóng socket phía nhậnApplication log

MTU & PMTUD cheat sheet

Môi trườngMTU thường gặpGhi chú
Ethernet LAN1500 byteChuẩn IEEE 802.3
WireGuard VPN1420 byteTrừ 80 byte overhead
IPsec (ESP/UDP)1400-1450 byteTùy cipher suite
PPPoE (ADSL/FTTH)1492 byteTrừ 8 byte PPPoE header
AWS EC2 (Nitro)9001 byte (jumbo)Chỉ trong VPC, không ra Internet

Test MTU: ping -M do -s 1472 <host> — nếu fail → MTU nhỏ hơn 1500. Fix black-hole: iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

📖 Glossary module

Thuật ngữĐịnh nghĩa 1 câu
SYNCờ TCP "synchronize" — gói đầu tiên của handshake, mang ISN của sender.
ACKCờ TCP "acknowledge" — xác nhận đã nhận tới byte nào.
ISNInitial Sequence Number — số thứ tự byte đầu tiên, chọn ngẫu nhiên để chống tấn công đoán số thứ tự.
RTTRound-Trip Time — thời gian gói đi tới đích và nhận phản hồi về.
MSSMaximum Segment Size — kích thước tối đa của phần dữ liệu trong một TCP segment (thường 1460 byte).
MTUMaximum Transmission Unit — kích thước frame tối đa của một chặng mạng (Ethernet: 1500 byte).
cwndCongestion Window — giới hạn số byte sender gửi trước khi cần ACK, điều tiết theo tình trạng mạng.
rwndReceive Window — số byte receiver còn chứa được trong buffer, gửi về trong ACK để điều tiết sender.
Slow startPha đầu của TCP congestion control: cwnd tăng theo hàm mũ cho đến khi gặp ssthresh.
TIME_WAITTrạng thái sau khi chủ động đóng kết nối — giữ khoảng 2×MSL (60-120 giây) để đảm bảo ACK cuối không bị mất.
CLOSE_WAITTrạng thái khi nhận FIN từ peer nhưng ứng dụng chưa gọi close() — thường do bug ứng dụng.
Ephemeral portPort tạm thời do OS cấp cho kết nối outbound client (thường 32768-60999 trên Linux).
Keep-aliveTCP keep-alive: probe định kỳ để phát hiện connection chết. HTTP keep-alive: tái dùng TCP connection cho nhiều HTTP request.
SACKSelective ACK — cho phép receiver báo chính xác mảnh nào nhận được, giúp retransmit đúng mảnh thiếu thay vì toàn bộ.
PMTUDPath MTU Discovery — cơ chế tìm MTU nhỏ nhất trên toàn tuyến đường, dùng cờ DF=1 và ICMP Fragmentation Needed.
PMTUD black-holeTình trạng PMTUD bị phá vỡ do firewall chặn ICMP type 3 code 4 — gói lớn bị drop âm thầm.
QUICGiao thức transport của Google (chuẩn hoá RFC 9000) — chạy trên UDP, tích hợp TLS, multiplexing không HOL blocking, thay TCP cho HTTP/3.
RSTCờ TCP "reset" — buộc đóng kết nối ngay lập tức, không qua 4-way handshake.
BacklogHàng đợi kết nối SYN đang chờ accept() — giới hạn bởi tham số listen() và sysctl net.core.somaxconn.
FragmentationPhân mảnh gói IP thành nhiều mảnh nhỏ hơn MTU để qua được chặng mạng — reassembly ở đích.

⚠️ Pitfall tổng hợp

Pitfall 1 — Nhầm ECONNREFUSED với bị firewall chặn. ECONNREFUSED đến tức thì và có RST — nghĩa là gói đã đến được server OS, firewall không chặn. Vấn đề là không có process LISTEN ở port đó. Firewall chặn gây ETIMEDOUT (im lặng, chậm). Hai hướng debug hoàn toàn khác nhau.

Pitfall 2 — Connection pool không cấu hình keep-alive, giữ connection chết. LB có idle timeout (thường 60-300s). Pool giữ connection lâu hơn timeout đó mà không kiểm tra → pool cho mượn connection đã bị LB close → ECONNRESET. Fix: maxLifetime của pool phải ngắn hơn LB idle timeout ít nhất 30 giây. HikariCP: keepaliveTime, Apache HttpClient: validateAfterInactivity.

Pitfall 3 — CLOSE_WAIT tích lũy do ứng dụng không gọi close(). Khi peer gửi FIN, ứng dụng nhận được sự kiện "đối tác đóng" nhưng quên gọi close() trên socket → kết nối kẹt ở CLOSE_WAIT mãi mãi. Mỗi kết nối CLOSE_WAIT chiếm file descriptor. Ứng dụng node/Java/Go không dùng try-with-resources hay bỏ sót error handler là nguyên nhân phổ biến. Dấu hiệu: ss -tan state close-wait | wc -l tăng dần.

Pitfall 4 — Ping thành công nhầm tưởng network ổn. Ping dùng ICMP — không liên quan TCP. Firewall có thể allow ICMP nhưng DROP TCP port cụ thể. PMTUD black-hole cũng thế: ping (gói nhỏ) thông, TCP data lớn (TLS certificate, HTTP response) timeout. Test TCP thật bằng nc -zv host port hoặc curl -v. Test MTU bằng ping -M do -s 1472.

Pitfall 5 — TIME_WAIT gây EADDRINUSE khi restart server tải cao. Server bị tải cao, xử lý nhiều kết nối ngắn → nhiều TIME_WAIT tích lũy → restart → bind() báo EADDRINUSE. Fix tức thì: SO_REUSEADDR trên server socket. Fix căn gốc: dùng connection pool để tái dùng kết nối, tránh open/close quá nhiều. Hiểu cơ chế: bài 04 giải thích tại sao TIME_WAIT phải kéo dài 2×MSL.

✅ Self-assessment

Bạn đã đạt module này nếu trả lời được:

  • Explain được 3-way handshake và cách TCP đảm bảo dữ liệu đúng thứ tự — SYN/SYN-ACK/ACK đồng bộ ISN hai chiều, sequence number đánh dấu từng byte, ACK xác nhận, retransmit khi mất.
    • Nếu chưa: đọc lại bài 01 (handshake, mục 2-3) và bài 02 (reliability, mục sequence + ACK).
  • Diagnose được TIME_WAIT, CLOSE_WAIT và cạn ephemeral port — dùng ss -tan đọc state, biết nguyên nhân và cách fix từng trường hợp.
    • Nếu chưa: đọc lại bài 04 (TIME_WAIT & CLOSE_WAIT), bài 07 (EADDRINUSE).
  • Choose được giữa TCP và UDP theo bài toán — biết khi nào cần tin cậy (TCP), khi nào latency quan trọng hơn reliability (UDP/QUIC).
    • Nếu chưa: đọc lại bài 05 (TCP vs UDP, mục "Khi nào dùng UDP").

🚀 What's next

Module 1 cho bạn hiểu tầng Transport — cái nền mọi ứng dụng web đều đặt lên đó. Module 2 — HTTP & Web phóng to tầng Application: HTTP/1.1 hoạt động thế nào (pipelining, HOL blocking), HTTP/2 giải quyết gì (multiplexing, header compression, server push), HTTP/3 trên QUIC tránh được gì. Hiểu Module 2, bạn đọc được Network tab của DevTools, biết vì sao request thứ 4 phải chờ request thứ 3, và chọn đúng HTTP version cho use case.

Bài tiếp theo: Module 2 — HTTP & Web: tổng quan

📚 Tài liệu mở rộng

  • Sách: TCP/IP Illustrated, Vol. 1: The Protocols — W. Richard Stevens. Cuốn kinh điển nhất về TCP/IP, mổ xẻ từng packet với tcpdump thật. Chapters 17-24 bao gồm mọi concept trong module này.
  • Sách: High Performance Browser Networking — Ilya Grigorik (O'Reilly, đọc miễn phí tại hpbn.co). Chapter 2 về TCP, chapter 4 về TLS, chapter 10-12 về HTTP/1-2-3. Góc nhìn performance thực tế, nhiều số liệu đo lường.
  • RFC 9293 — Transmission Control Protocol (2022): bản hợp nhất mới nhất của TCP, thay thế RFC 793. Tra cứu khi cần câu trả lời chính thức về hành vi TCP.
  • RFC 9000 — QUIC: A UDP-Based Multiplexed and Secure Transport: đặc tả QUIC — giao thức thay TCP cho HTTP/3. Đọc phần Introduction để hiểu motivation.
  • Blog: Cloudflare Blog — "How to receive a million packets per second" và "We have seen things you people wouldn't believe — TCP over Satellite." Ví dụ thực tế về tuning TCP ở scale lớn.

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Bài này có giúp bạn hiểu bản chất không?

Hỏi đáp về bài này

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên

Bài tiếp theo

Module 2 — HTTP & Web: tổng quan