为什么说TCP是面向流的协议?而UDP是面向数据报的协议?

问题

经常能听人说:TCP是面向流的协议,而UDP是面向数据报的协议。从字面理解上来说,似懂非懂。每次都不是能彻底明白什么是流,什么是数据报?

在大家眼里,网络报文都是IP包,而IP包肯定是分片的,有最大Payload限制,那什么是流?什么是数据报呢?

我们先重温一下这些协议头。

IP、TCP、UDP协议头

IPv4协议头

IP 是 TCP/IP 协议中的核心协议,为 TCP、UDP 等协议提供了一种尽力而为、无连接的数据报传输服务,也就意味着 IP 协议不保证成功传输,也不维护数据报相关的链接状态信息。

IPv4 数据报头部至少为 20 字节,结构如下:为什么说TCP是面向流的协议?而UDP是面向数据报的协议?

  • 版本:确定 IP 协议的版本(IPv4 或 IPv6),从而能正确解释后面的内容。
  • IHL(头部长度):由于选项的存在,由此字段确定数据从何处开始。
    DS(区分服务,DiffServ):用于支持其他不同类型的服务(非尽力而为的)。可以区分一些可能要求低时延或者其他要求的服务。
  • ECN:拥塞标识符。当路由器感知到拥塞时会设置这两位以降低发送速度。
  • 总长度:IP 数据报的总长度,包括首部和头部,字节为单位。由于位数限制最多 65535 字节,所以数据大小最多为 65515 字节,但是链路层一般不能携带这么大的数据,很少超过 1500 字节。
  • 标识、标志、分片偏移:用于 IP 分片。传输过程有些协议并不能携带过大的数据,所以只能分为多个部分发送。标识避免与其他数据报分片混淆。最后一片标志设为 0,其他的设为 1。偏移指明是第几个分片,用于正确组装。
  • 生存期(Time-To-Live,TTL):标识可通过的路由器数量上限。每经过一个路由器将该值减一,为 0 时丢弃,避免在一个网络环路中无限传输。
  • 协议:指示了上层是什么协议,6 为 TCP,17 为 UDP。
  • 头部校验和:用 16 位反码和(Internet 校验和)计算头部,对于数据部分校验由上层协议实现。由于 TTL 每经过一次路由器都会改变,校验和也要因此重新计算。

TCP协议头

UPD协议头

总结

TCP报文粘包、拆包 :面试官问:你来讲下Netty通信中的粘包、拆包?
那么UDP是否会发生粘包或拆包的现象呢?

答案是不会。UDP是基于报文发送的,从UDP的帧结构可以看出,在UDP首部采用了16bit来指示UDP数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。

而TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界;另外从TCP的帧结构也可以看出,在TCP的首部没有表示数据长度的字段,基于上面两点,在使用TCP传输数据时,才有粘包或者拆包现象发生的可能。

参考