TCP和UDP的区别

好久没回顾这个知识点了,我现在只记得 TCP 是有链接的,UDP 是无连接的;TCP 是可靠的,UDP 是不可靠的。技术细节已经全然忘光了,今天就来回顾一下。

先说几个几点结论,然后再说说细节:

  • TCP 是有链接的,UDP 是无连接的
  • TCP 可靠(无差错,不丢失不重复,按序到达),UDP 不可靠
  • TCP 面向字节流,UDP 面向报文
  • TCP 是一对一全双工,UDP 是 n 对 n
  • TCP 的首部较大为 20 字节,UDP 首部只有 8 字节

TCP 为什么要三次握手四次挥手

三次握手是因为双方都要确认对方的发送和接收两种能力

  1. 第一次客户端发送 SYN 报文段,服务器接收到了,从服务器的视角看,客户端具备了发送能力。
  2. 第二次服务器端发送 ACK+SYN 报文段,客户端接收到了,从客户端的角度看,服务器具备了接收和发送两种能力。
  3. 第三次客户端接收到了服务器的报文,再发一个 ACK 报文给服务器,服务器接收到这个 ACK 报文就能确认客户端的接受能力正常。

所以最少需要三次,才能确认双方的收发能力都是正常的。

四次挥手是因为 TCP 是双工信道,关闭了 A 到 B 的发送渠道,B 到 A 的还没关闭,所以需要四次:

  1. 客户端发送 FIN 报文段给服务器端,服务器收到后发送 ACK 给客户端,客户端收到 ACK 后就会不再发消息。也就是说客户端到服务器端这条信道关闭了。
  2. 服务器发送 FIN 报文段给客户端,客户端收到后发送 ACK 给服务器,服务器收到 ACK 后就不再发消息给客户端了。服务器发送给客户端这条信道就关闭了。

这里的问题就是为什么服务器不把 ACK 和 FIN 合在一起发,就像三次握手时候那样 ACK+SYN 一起发。因为服务器 → 客户端,客户端 → 服务器这两条信道是互相独立的,在关闭其中一条的时候,另一条可能还在工作,不应该一起关闭,需要设计成独立关闭

面向报文和面向字节流的区别

面向报文的传输方式是应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则 IP 层需要分片,降低效率。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。

面向字节流的话,虽然应用程序和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把应用程序看成是一连串的无结构的字节流。TCP 有一个缓冲,当应用程序传送的数据块太长,TCP 就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP 也可以等待积累有足够多的字节后再构成报文段发送出去。