为什么说TCP是面向流的协议?而UDP是面向数据报的协议?
问题
经常能听人说:TCP是面向流的协议,而UDP是面向数据报的协议。从字面理解上来说,似懂非懂。每次都不是能彻底明白什么是流,什么是数据报?
在大家眼里,网络报文都是IP包,而IP包肯定是分片的,有最大Payload限制,那什么是流?什么是数据报呢?
我们先重温一下这些协议头。
IP、TCP、UDP协议头
IPv4协议头
IP 是 TCP/IP 协议中的核心协议,为 TCP、UDP 等协议提供了一种尽力而为、无连接的数据报传输服务,也就意味着 IP 协议不保证成功传输,也不维护数据报相关的链接状态信息。
IPv4 数据报头部至少为 20 字节,结构如下:
- 版本:确定 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传输数据时,才有粘包或者拆包现象发生的可能。