Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题( 三 )


  • TCP 是面向连接的传输层协议 , 传输数据前先要建立连接 。
  • UDP 是不需要连接 , 即刻传输数据 。
2. 服务对象
  • TCP 是一对一的两点服务 , 即一条连接只有两个端点 。
  • UDP 支持一对一、一对多、多对多的交互通信
3. 可靠性
  • TCP 是可靠交付数据的 , 数据可以无差错、不丢失、不重复、按需到达 。
  • UDP 是尽最大努力交付 , 不保证可靠交付数据 。
4. 拥塞控制、流量控制
  • TCP 有拥塞控制和流量控制机制 , 保证数据传输的安全性 。
  • UDP 则没有 , 即使网络非常拥堵了 , 也不会影响 UDP 的发送速率 。
5. 首部开销
  • TCP 首部长度较长 , 会有一定的开销 , 首部在没有使用「选项」字段时是 20 个字节 , 如果使用了「选项」字段则会变长的 。
  • UDP 首部只有 8 个字节 , 并且是固定不变的 , 开销较小 。
TCP 和 UDP 应用场景:
由于 TCP 是面向连接 , 能保证数据的可靠性交付 , 因此经常用于:
  • FTP 文件传输
  • HTTP / HTTPS
由于 UDP 面向无连接 , 它可以随时发送数据 , 再加上UDP本身的处理既简单又高效 , 因此经常用于:
  • 包总量较少的通信 , 如 DNS 、SNMP 等
  • 视频、音频等多媒体通信
  • 广播通信
为什么 UDP 头部没有「首部长度」字段 , 而 TCP 头部有「首部长度」字段呢?
原因是 TCP 有可变长的「选项」字段 , 而 UDP 头部长度则是不会变化的 , 无需多一个字段去记录 UDP 的首部长度 。
为什么 UDP 头部有「包长度」字段 , 而 TCP 头部则没有「包长度」字段呢?
先说说 TCP 是如何计算负载数据长度:
Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
其中 IP 总长度 和 IP 首部长度 , 在 IP 首部格式是已知的 。 TCP 首部长度 , 则是在 TCP 首部格式已知的 , 所以就可以求得 TCP 数据的长度 。
大家这时就奇怪了问:“ UDP 也是基于 IP 层的呀 , 那 UDP 的数据长度也可以通过这个公式计算呀?为何还要有「包长度」呢?”
这么一问 , 确实感觉 UDP 「包长度」是冗余的 。
因为为了网络设备硬件设计和处理方便 , 首部长度需要是 4字节的整数倍 。
如果去掉 UDP 「包长度」字段 , 那 UDP 首部长度就不是 4 字节的整数倍了 , 所以小林觉得这可能是为了补全 UDP 首部长度是 4 字节的整数倍 , 才补充了「包长度」字段 。
Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
TCP 连接建立TCP 三次握手过程和状态变迁
TCP 是面向连接的协议 , 所以使用 TCP 前必须先建立连接 , 而建立连接是通过三次握手而进行的 。
Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
TCP 三次握手
  • 一开始 , 客户端和服务端都处于 CLOSED 状态 。 先是服务端主动监听某个端口 , 处于 LISTEN 状态

Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
第一个报文—— SYN 报文