Có TCP rồi, sao không dùng nó cho mọi thứ?
Có TCP rồi, sao Internet còn cần UDP?
TCP cố đảm bảo ứng dụng nhận được dữ liệu đầy đủ và đúng thứ tự.
Để làm được vậy, nó phải đánh số dữ liệu, xác nhận những gì đã nhận, phát hiện phần bị mất và gửi lại.
Với tải file hay mở trang web, đó thường là điều ta muốn.
Nhưng thử dùng cách này cho một cuộc gọi.
Giọng nói được chia thành những mẩu nhỏ liên tiếp:
A B C D E F
Gói C mất giữa đường.
Nên chờ C được gửi lại, hay bỏ qua nó và tiếp tục nghe D, E, F?
Chờ C có khi còn tệ hơn mất C
Với TCP, dữ liệu được giao cho ứng dụng theo đúng thứ tự.
Nếu C chưa tới, phần phía sau có thể phải chờ:
A B
↓
chờ C được gửi lại…
↓
C D E F
Vấn đề là người đang nói ở đầu bên kia đâu có dừng lại.
Đến lúc C được gửi lại, khoảnh khắc đó có thể đã trôi qua.
Với một cuộc gọi, đôi khi hợp lý hơn nếu nhận:
A B _ D E F
Bạn mất một chút âm thanh, nhưng cuộc nói chuyện vẫn tiếp tục đúng nhịp.
Thậm chí ở tầng ứng dụng, cách xử lý có thể rất tự nhiên:
“Bạn vừa nói gì đấy? Nãy tôi mất tín hiệu.”
Người bên kia nói lại câu đó.
Không nhất thiết mạng phải giữ toàn bộ cuộc gọi đứng yên chỉ để cứu vài trăm mili-giây âm thanh đã cũ.
Kim phát dưới đây chạy đều như một cuộc gọi thật. Để ý chuyện gì xảy ra khi C đến muộn:
thời gian →
- A đã phát
- B đã phát
- _ lặng
- D đã phát
- E đã phát
- F đã phát
C đã tới, nhưng quá muộn để phát ở vị trí cũ.
Có những loại dữ liệu mà tới đúng lúc quan trọng hơn tới đầy đủ.
Internet từng gặp đúng vấn đề này
Cuối thập niên 1970, những người xây Internet thử truyền giọng nói qua TCP.
Khi một gói mất, TCP phải phát hiện ra, yêu cầu gửi lại rồi chờ gói đó quay về. Với đường truyền thời đó, quá trình này có thể gây ra khoảng ngắt rất dễ nhận thấy trong cuộc nói chuyện.
Đây cũng là một trong những nhu cầu khiến kiến trúc TCP/IP được tách rõ hơn.
IP lo đưa gói tin qua các mạng.
TCP nằm phía trên và cung cấp một kết nối đáng tin cậy cho ứng dụng nào cần.
Nhưng có những ứng dụng không muốn chờ TCP gửi lại dữ liệu cũ. Chúng cần một cách gửi đơn giản hơn trực tiếp trên IP.
Năm 1980, UDP được đặc tả cho mục đích đó.
UDP chỉ gửi từng gói
UDP gửi từng gói dữ liệu rời (datagram).
Mỗi gói độc lập với những gói khác.
Nếu ứng dụng gửi:
Gói A
Gói B
Gói C
UDP giữ nguyên ba ranh giới đó.
Nó không biến chúng thành một dòng byte liên tục như TCP.

Bản thân UDP cũng không làm những việc TCP làm:
- không bắt tay để mở kết nối;
- không xác nhận từng phần dữ liệu;
- không tự gửi lại gói bị mất;
- không giữ dữ liệu lại để giao đúng thứ tự.
UDP vẫn có port nguồn và port đích, nên hệ điều hành vẫn biết gói đó phải được đưa cho ứng dụng nào.
Mất gói thì ai xử lý?
Ứng dụng tự quyết.
Đó là điểm quan trọng nhất của UDP.
Nếu một gói mất, ứng dụng có thể chọn gửi lại.
Hoặc bỏ luôn.
Hoặc dùng dữ liệu mới hơn thay thế.
Ví dụ với DNS:
Máy bạn: IP của example.com là gì?
... không thấy trả lời ...
Máy bạn: hỏi lại.
Không cần duy trì một kết nối dài chỉ để hỏi một câu ngắn.
Với cuộc gọi thoại hoặc video, một đoạn âm thanh hay khung hình đã quá cũ có thể bị bỏ.
Với game, giả sử server gửi vị trí người chơi:
t = 10.0s → x = 100
t = 10.1s → x = 104
Nếu vị trí ở 10.0s tới sau vị trí 10.1s, nó không còn nhiều giá trị nữa.
Game có thể bỏ nó.
Nhưng không phải mọi dữ liệu trong game đều có thể mất.
Ví dụ:
Bạn nhặt được một vật phẩm hiếm.
Thông tin đó có thể phải được đảm bảo tới nơi.
Một ứng dụng dùng UDP hoàn toàn có thể tự thêm cơ chế xác nhận hoặc gửi lại cho những dữ liệu như vậy.
Vậy UDP có nhanh hơn TCP không?
Nói “UDP nhanh hơn TCP” dễ gây hiểu nhầm.
Bit không chạy nhanh hơn chỉ vì nó nằm trong UDP.
UDP đơn giản hơn vì bản thân nó không làm nhiều việc mà TCP làm: không giữ thứ tự, không tự gửi lại, không duy trì một dòng byte đáng tin cậy.
Vì vậy ứng dụng có thể tránh phải chờ những dữ liệu mà nó cho rằng đã quá cũ.
Nhưng nếu ứng dụng dùng UDP rồi tự xây lại toàn bộ cơ chế xác nhận, gửi lại và kiểm soát tốc độ truyền, thì phần phức tạp đó vẫn tồn tại. Nó chỉ được chuyển từ TCP lên ứng dụng.
UDP cũng không có nghĩa là được gửi dữ liệu vào mạng với tốc độ tùy ý. Ứng dụng vẫn phải kiểm soát lượng dữ liệu mình gửi để tránh làm nghẽn mạng.
| Loại dữ liệu | Nếu mất một phần | Thường muốn |
|---|---|---|
| File, email, dữ liệu trang web | dữ liệu có thể bị hỏng | gửi lại và chờ |
| Âm thanh cuộc gọi | mất một khoảnh khắc | tiếp tục |
| Video trực tiếp | một khung hình có thể đã quá cũ | dùng khung hình mới |
| Vị trí nhân vật trong game | vị trí cũ nhanh chóng mất giá trị | dùng vị trí mới |
TCP và UDP vì vậy không phải hai phiên bản “chậm” và “nhanh” của cùng một thứ.
Chúng đưa ra hai cách xử lý khác nhau khi mạng làm mất hoặc làm chậm dữ liệu:
TCP
mất dữ liệu → gửi lại → giữ đúng thứ tự
UDP
mất dữ liệu → ứng dụng tự quyết làm gì
Và với những thứ diễn ra theo thời gian thực, đôi khi câu trả lời tốt nhất cho một gói đã mất chỉ đơn giản là:
“Nãy bạn nói gì đấy?”
TCP hay UDP chỉ mới giúp dữ liệu tới đúng ứng dụng ở đầu bên kia.
Nhưng nếu ứng dụng đó là một web server, trình duyệt vẫn phải biết nói gì với nó.
Trình duyệt phải nói gì với máy chủ để nhận về một trang web?
Nguồn bài viết (5)
- IEN 2 — Comments on Internet Protocol and TCP (Jon Postel, 1977) · RFC Editor
- Oral History of Danny Cohen · Computer History Museum
- TCP Split into TCP/IP · IEEE Communications Society
- RFC 768 — User Datagram Protocol · IETF
- RFC 8085 — UDP Usage Guidelines · IETF