如果此时机器A马上关闭连接,会导致数据不完整、机器B无法释放连接等问题。所以此时机器A需要等待2个报文生存最大时长,确保网络中没有任何遗留报文了,再关闭连接
最后,机器A等待两个报文存活最大时长之后,机器B 接收到ACK报文之后,均关闭连接,进入CLASED状态
双方之间4次互相发送报文来断开连接的过程,就是四次挥手。
现在,对于为什么握手是三次挥手是四次、一定要三次/四次吗、为什么要停留2msl再关闭连接等等这些问题,就都解决了。
UDP协议运输层协议除了TCP,还有大名鼎鼎的UDP。如果说TCP凭借他完善稳定的功能独树一帜,那UDP就是精简主义乱拳打死老师傅。
UDP只实现了运输层最少的功能:进程间通信。对于应用层传下来的数据,UDP只是附加一个首部就直接交给网络层了。UDP的头部非常简单,只有三部分:
源端口、目标端口:端口号用来区分主机的不同进程
校验码:用于校验数据包在传输的过程中没有出现错误,例如某个1变成了0
长度:报文的长度
所以UDP的功能也只有两个:校验数据报是否发生错误、区分不同的进程通信。
但,TCP的功能虽然多,但同时也是要付出相对应的代价。例如面向连接的特性,在建立和断开连接的时候会有开销;拥塞控制的特性,会限制传输的上限等等。下面来罗列一下UDP的优缺点:
UDP的缺点无法保证消息完整、正确到达,UDP是一个不可靠的传输协议;
缺少拥塞控制容易互相竞争资源导致网络系统瘫痪
UDP的优点效率更快;不需要建立连接以及拥塞控制
连接更多的客户;没有连接状态,不需要为每个客户创建缓存等
分组首部字节少,开销小;TCP首部固定首部是20字节,而UDP只有8字节;更小的首部意味着更大比例的数据部分
在一些需要高效率允许可限度误差的场景下可以使用。如直播场景,并不需要保证每个数据包都完整到达,允许一定的丢包率,这个时候TCP的可靠特性反而成为了累赘;精简的UDP更高的效率是更加适合的选择
可以进行广播;UDP并不是面向连接的,所以可以同时对多个进程进行发送报文
UDP适用场景UDP适用于对传输模型需要应用层高度自定义、允许出现丢包、需要高效率的场景、需要广播;例如
视屏直播
DNS
RIP路由选择协议
其他补充 分块传输我们可以发现,运输层在传输数据的时候,并不是把整个数据包加个首部直接发送过去,而是会拆分成多个报文分开发送;那他这样做原因是什么?
有读者可能会想到:数据链路层限制了数据长度只能有1460。那数据链路层为什么要这么限制?他的本质原因就是:网络是不稳定的。如果报文太长,那么极有可能在传输一般的时候突然中断了,这个时候就要整个数据重传,效率就降低了。把数据拆分成多个数据报,那么当某个数据报丢失,只需要重传该数据报即可。
那是不是拆分得越细越好?报文中数据字段长度太低,会使得首部的占比太大,这样首部就会成为网络传输最大的负担了。例如1000字节,每个报文首部是40字节,如果拆分成10个报文,那么只需要传输400字节的首部;而如果拆分成1000个,那么需要传输40000字节的首部,效率就极大地降低了。
路由转换先看下图:
正常情况下,主机A的数据包可以又 1-3-6-7路径进行传送
如果路由3坏掉了,那么可以从 1-4-6-7进行传送
如果4也坏掉了,那么只能从2-5-6-7传送
如果5坏掉了,那么就中断线路了
可以看出来,使用路由转发的好处是:提高网络的容错率,本质原因依旧是网络是不稳定的 。即使坏掉几个路由器,网络依旧畅通。但是如果坏掉路由器6那就直接导致主机A和主机B无法通信,所以要避免这种核心路由器的存在。
使用路由的好处还有:分流。如果一条线路太拥堵,可以从别的路线进行传输,提高效率。
粘包与拆包在面向字节流那一小节讲过,TCP不懂这些数据流的意义,他只知道从应用层拿到数据流,切割成一份份报文,然后发送给目标对象。而如果应用层传输下来的是两个数据包,那么极有可能出现这种情况:
应用层需要向目标进程发送两份数据,一份音频,一份文本
TCP只知道接收到一个流,并把流拆分成4段进行发送
中间第二个报文的数据就出现两个文件的数据混在一起,这就是粘包
目标进程应用层在接收到数据之后,需要把这些数据拆分成正确的两个文件,就是拆包