UDP和TCP在代码实现的区别

步骤 TCP UDP
Socket 创建 socket(AF_INET, SOCK_STREAM, 0) socket(AF_INET, SOCK_DGRAM, 0)
绑定地址 需要 bind()(服务端) 需要 bind()(服务端)
连接管理 服务端:listen() + accept()客户端:connect() 无连接管理,直接收发数据包
数据收发 send()/recv()write()/read() sendto()/recvfrom()(需指定目标地址)
关闭连接 close()(需处理四次挥手) 直接 close()(无连接状态)

3. 核心差异详解

  1. 连接管理
    • TCP 是面向连接的协议,需通过 listen() + accept() 建立连接池,每个客户端连接会生成一个新的 socket。
    • UDP 无连接概念,所有客户端通过同一个 socket 通信,需用 recvfrom() 获取客户端地址。
  2. 数据收发函数
    • TCP 使用 send()/recv(),数据像水流一样连续,无明确边界(需应用层处理粘包问题)。
    • UDP 使用 sendto()/recvfrom(),每个数据包独立且完整,自带地址信息。
  3. 错误处理
    • TCP 自动处理丢包、乱序、重传(可靠性由协议保证)。
    • UDP 需应用层自行处理丢包、超时、重传(如实现类似 TCP 的可靠性)。
  4. 多客户端处理
    • TCP 通常用多线程/多进程处理并发连接(每个 accept() 返回一个独立 socket)。
    • UDP 单线程即可处理所有请求(通过 recvfrom() 获取不同客户端的地址)

4. 边界问题示例

TCP 粘包问题

1
2
3
4
5
6
// 客户端连续发送两次数据
send(client_fd, "Hello", 5, 0);
send(client_fd, "World", 5, 0);

// 服务端可能一次收到 "HelloWorld"
recv(client_fd, buffer, 10, 0); // 需应用层自行分割消息

UDP 数据报完整性

1
2
3
4
5
6
7
// 客户端发送两次数据
sendto(sock, "Hello", 5, 0, &server_addr, addr_len);
sendto(sock, "World", 5, 0, &server_addr, addr_len);

// 服务端会收到两个独立的数据包
recvfrom(sock, buffer1, 5, 0, &client_addr, &addr_len); // "Hello"
recvfrom(sock, buffer2, 5, 0, &client_addr, &addr_len); // "World"

5. 总结

  • TCP 代码更复杂(连接管理、粘包处理),但可靠性高。
  • UDP 代码更简单(无连接、数据报独立),但需自行实现可靠性。
Footer Example