Skip to content

网络编程


UDP 和 TCP 的区别

TCP 重可靠,UDP 图快。两者都在传输层,但设计哲学完全不一样。

TCP(Transmission Control Protocol)

  • 面向连接:三次握手先把关系确认好,再开始传数据。
  • 可靠传输:有序、无丢包、无重复,靠重传和序号保证。
  • 有流量控制和拥塞控制:防止把对方冲爆。
  • 应用场景:文件传输(FTP)、网页(HTTP/HTTPS)、邮件(SMTP、IMAP)。

TCP 像寄快递,先打电话确认地址 → 发件 → 对方签收 → 丢件还能重发。

UDP(User Datagram Protocol)

  • 无连接:直接丢包出去,不管对方有没有准备好。
  • 不保证可靠:可能丢包、乱序、重复,需要应用层自己处理。
  • 轻量、开销小:没有握手、没有确认,速度快。
  • 应用场景:实时性要求高的场景,视频会议、语音通话、在线游戏、广播。

UDP 像往人群里扔纸飞机——发得快,丢不丢接不接全看运气。

TCP 三次握手机制及报文

为了保证客户端和服务端双方都清楚:我能发、你能收、你也能发、我也能收。
三次握手就是一个互相确认通信能力的过程。

三次握手过程

  1. 第一次握手:客户端 → 服务端
    发送 SYN 报文,表示“我要连你,序号是 seq=x”

    客户端告诉服务端:我能发数据。

  2. 第二次握手:服务端 → 客户端
    回复 SYN + ACK,表示“收到啦,确认号 ack=x+1,序号 seq=y”

    服务端告诉客户端:我能收数据,而且我也要连你。

  3. 第三次握手:客户端 → 服务端
    发送 ACK,确认号 ack=y+1

    客户端告诉服务端:我能收你的数据,连接建立完毕。

此时,双方都准备好,TCP 进入 ESTABLISHED 状态,可以开始愉快收发数据。

报文里的关键字段

  • SYN:同步序列号,用来建立连接。
  • ACK:确认应答,告诉对方我收到了。
  • seq:序列号,标记当前发送的数据包。
  • ack:确认号,告诉对方我期望接收的下一个数据包序号。

如果只有两次,可能会出现历史连接的报文被服务器当成新连接响应,造成资源浪费(典型 SYN Flood 攻击场景)。
第三次握手是为了让客户端确认:服务端的应答是给我的,而且是最新的。

TCP 四次挥手机制(断开连接)

三次握手建立连接后,断开连接要四次挥手,因为 TCP 是全双工的,双方都要单独关闭自己的发送通道。
服务端可能还有没发完的数据,所以客户端发 FIN 后不能直接关闭,必须等服务端自己也发 FIN 表示“我也发完了”,再做最后的确认。

四次挥手过程

  1. 第一次挥手:客户端 → 服务端
    发送 FIN 报文,seq=u

    客户端说:我已经没有数据要发了,但我还能接收你的数据。

  2. 第二次挥手:服务端 → 客户端
    回复 ACK 报文,ack=u+1

    服务端说:收到,你先等一下,我可能还有数据要发。

(此时客户端进入 FIN_WAIT_2 状态,等待服务端的数据发完)

  1. 第三次挥手:服务端 → 客户端
    发送 FIN 报文,seq=v

    服务端说:我也发完了,可以断了。

  2. 第四次挥手:客户端 → 服务端
    回复 ACK 报文,ack=v+1

    客户端说:收到确认,我也断开了。

客户端此时进入 TIME_WAIT 状态,等待 2MSL 确保服务端收到了最后的 ACK,然后彻底关闭。

TIME_WAIT:四次挥手最后,客户端并不是立刻就释放连接,而是进入一个“等待状态”,等一小段时间才真正关闭。

MSL(Maximum Segment Lifetime):报文最大生存时间,也就是一个 TCP 报文在网络中能存在的最长时间。超过这个时间报文就会被丢弃。

2MSL:就是 MSL 的两倍。TCP 规定要等两倍的时间,原因有两点:

  1. 保证最后那个 ACK 能到达服务端
    如果服务端没收到 ACK,会重发 FIN。客户端留在 TIME_WAIT 状态,可以重新发 ACK,避免服务端一直重发。

  2. 避免旧连接的数据干扰新连接
    等两倍时间,能确保网络中旧连接的报文都自然消亡,再用同样的四元组(源 IP、源端口、目标 IP、目标端口)建新连接就不会混淆。

为什么是客户端进入 TIME_WAIT

一般来说,主动关闭连接的一方进入 TIME_WAIT。因为它发出了最后一个 ACK,必须保证对方收到了,不然对方会重发 FIN。

TCP/IP 模型

协议是规则,分层是分工。
TCP/IP 模型就是把“从你写出一条消息到对方能正确看到它”这条链拆成几层,每层负责不同的事,减少混乱。

如果没有统一规则,对方可能不知道从哪里开始读、读多少、什么时候结束。中间丢一块就收不全,甚至一直等待。即便收到了,也不知道数据是文字、图片还是语音。

分层能让复杂问题拆开,每层专心做好一件事:

  • 上层只管我要说什么,不管怎么送。
  • 下层只管怎么送到,不管内容是什么。

这样每层都能独立演化,互相不影响。

比起教科书的 OSI 七层,TCP/IP 模型更贴近实际网络实现,常见划分是四层:

  1. 网络接口层
    负责直接和物理网络打交道,把比特流丢到网卡、WiFi、以太网上。
    协议:以太网、PPP、ARP。
  2. 网络层
    负责寻址和路由,把数据送到对的机器。
    核心协议:IP,还有 ICMP(Ping 就用它)。
  3. 传输层
    负责端到端通信,保证数据按顺序、完整到达,或者只管快速送达。
    核心协议:TCP(可靠)、UDP(不可靠)。
  4. 应用层
    直接面向用户,定义数据内容和语义。
    协议:HTTP、FTP、SMTP、DNS。

可以把 TCP/IP 模型看成 OSI 七层模型的简化版:

  • 上三层(应用/表示/会话)合并成应用层
  • 下两层(数据链路/物理)合并成网络接口层

每层解决的问题

层级负责的事
网络接口层把 0/1 比特正确放上网线/空中并接收回来
网络层找到目标机器,决定走哪条路
传输层保证数据顺序、重发丢包,或者快速发完不管
应用层定义数据长什么样,怎么解释

对比 OSI 七层模型

OSI 七层TCP/IP 四层
应用层、表示层、会话层应用层
传输层传输层
网络层网络层
数据链路层、物理层网络接口层

TCP/IP 把上三层合并成“应用层”,把下两层合并成“网络接口层”。

评论