UDP 不保證順序、不重傳、不流控。應用層交給 UDP 的每一次 sendto/DatagramPacket.send 都對應一個獨立的 UDP 數據報。
| 場景 | 發送端動作 | 網絡層行為 | 接收端收到的數據報數量 |
|---|---|---|---|
| 應用層主動拆分為 2 個包發送 | 調用 2 次 send | 直接封裝為 2 個 IP 數據報 | 2 個(邊界保持) |
| 應用層一次發送 3000 字節 | 調用 1 次 send | IP 層按 MTU (1500) 分片為 3 個片段 | 1 個(IP 層重組後交付) |
public void sendLargeData(DatagramSocket socket, InetAddress ip, int port, byte[] data) throws IOException {
final int MAX_PAYLOAD = 1460;
int offset = 0;
while (offset < data.length) {
int len = Math.min(MAX_PAYLOAD, data.length - offset);
DatagramPacket packet = new DatagramPacket(data, offset, len, ip, port);
socket.send(packet);
offset += len;
}
}
誤區:「UDP 發送大數據會自動拆包,接收端收到多少包不確定。」
正確:只有 IP 層分片才會「自動拆包」,但對應用層透明,仍是一個完整數據報。應用層若想控制包數量,必須自己拆分發送。
理解 UDP「保邊界」特性是網絡編程關鍵。主動分包、控制包大小、自定義協議頭(序號、分片標識) 是構建可靠 UDP 應用的基礎。若業務強依賴順序與可靠性,請直接選用 TCP 或基於 UDP 實現類 TCP 協議(如 QUIC、KCP)。