源本科技 | 码上会

TCP 与 UDP 协议

2026/01/31
45
0

学习目标

  • 理解 TCP 与 UDP 协议的基本概念、特点及适用场景

  • 掌握 Java 中基于 TCP 和 UDP 的网络编程模型

  • 能够根据应用需求选择合适的传输层协议

  • 通过图示理解数据在网络中的传输流程


什么是传输层协议

在计算机网络的 OSI 模型中,传输层(第四层)负责端到端的数据通信。TCP 和 UDP 是两种最常用的传输层协议,它们都运行在 IP 协议之上,为应用程序提供网络通信能力。


TCP 协议

特点

  • 面向连接:通信前需建立连接(三次握手),通信结束后释放连接(四次挥手)

  • 可靠传输:通过确认、重传、校验和等机制确保数据完整、有序到达

  • 流量控制与拥塞控制:防止发送方过快导致接收方或网络崩溃

  • 字节流服务:数据以连续字节流形式传输,无消息边界

适用场景

  • 文件传输(如 FTP)

  • 网页浏览(HTTP/HTTPS)

  • 邮件收发(SMTP、IMAP)

  • 数据库连接

三次握手与四次挥手


UDP 协议

特点

  • 无连接:无需建立连接,直接发送数据报

  • 不可靠传输:不保证数据到达、不重传、不排序

  • 开销小、延迟低:头部仅 8 字节,无连接管理开销

  • 保留消息边界:每个 send 对应一个独立的数据报

适用场景

  • 实时音视频通话(如 VoIP、直播)

  • 在线游戏(对延迟敏感)

  • DNS 查询

  • IoT 设备上报(小数据、高频)

UDP 通信流程


Java 中的 TCP 编程

Java 通过 java.net 包提供网络编程支持。TCP 编程使用 Socket(客户端)和 ServerSocket(服务端)。

服务端代码

import java.io.*;
import java.net.*;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        System.out.println("TCP 服务端启动,监听 8080 端口...");

        while (true) {
            Socket clientSocket = serverSocket.accept(); // 阻塞等待连接
            new Thread(() -> {
                try (BufferedReader in = new BufferedReader(
                        new InputStreamReader(clientSocket.getInputStream()));
                     PrintWriter out = new PrintWriter(
                        clientSocket.getOutputStream(), true)) {

                    String request = in.readLine();
                    System.out.println("收到请求: " + request);
                    out.println("Echo: " + request); // 回显

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

客户端代码

import java.io.*;
import java.net.*;

public class TCPClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8080);
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
            new InputStreamReader(socket.getInputStream()));

        out.println("Hello from Java TCP Client");
        System.out.println("服务端响应: " + in.readLine());

        socket.close();
    }
}

Java 中的 UDP 编程

UDP 编程使用 DatagramSocketDatagramPacket

服务端代码

import java.net.*;

public class UDPServer {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(9000);
        byte[] buffer = new byte[1024];
        System.out.println("UDP 服务端启动,监听 9000 端口...");

        while (true) {
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            socket.receive(packet); // 阻塞接收数据报

            String request = new String(packet.getData(), 0, packet.getLength());
            System.out.println("收到请求: " + request);

            // 构造响应
            String response = "Echo: " + request;
            DatagramPacket reply = new DatagramPacket(
                response.getBytes(),
                response.length(),
                packet.getAddress(),
                packet.getPort()
            );
            socket.send(reply);
        }
    }
}

客户端代码

import java.net.*;

public class UDPClient {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName("localhost");

        // 发送请求
        String msg = "Hello from Java UDP Client";
        byte[] buf = msg.getBytes();
        DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 9000);
        socket.send(packet);

        // 接收响应
        byte[] recvBuf = new byte[1024];
        DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length);
        socket.receive(recvPacket);
        String response = new String(recvPacket.getData(), 0, recvPacket.getLength());
        System.out.println("服务端响应: " + response);

        socket.close();
    }
}

TCP vs UDP

特性

TCP

UDP

连接方式

面向连接

无连接

可靠性

可靠(确认 + 重传)

不可靠

传输顺序

保证顺序

不保证

头部开销

20 字节(最小)

8 字节

速度

较慢(因可靠性机制)

流量控制

支持

不支持

拥塞控制

支持

不支持

消息边界

无(字节流)

有(数据报)

典型应用

HTTP、FTP、SMTP

DNS、VoIP、游戏


重点总结

  • TCP 提供可靠、有序的字节流服务,适合对数据完整性要求高的场景

  • UDP 提供轻量、低延迟的数据报服务,适合实时性要求高、可容忍少量丢包的场景

  • Java 中:

    • TCP 使用 Socket / ServerSocket

    • UDP 使用 DatagramSocket / DatagramPacket

  • 选择协议时,应权衡 可靠性性能 / 延迟 的需求


思考题

  1. 为什么 HTTP 协议通常基于 TCP 而不是 UDP?如果改用 UDP 会带来哪些问题?

  2. 在一个多人在线射击游戏中,玩家位置更新应使用 TCP 还是 UDP?请说明理由。

  3. 假设你正在开发一个物联网温度传感器上报系统,每秒上报一次数据,且允许偶尔丢失一两次数据,你会选择哪种协议?为什么?