我们还有很长的路要走。
但没关系,路就是生活。
--- 杰克·凯鲁亚克 《在路上》---
路由就是在复杂的网络结构中,找出一条通往终点的路线。 IP协议提供了保证主机A可以跨网络发送数据到主机B。跨网络过程中,需要经过不同的路由器的一次一次的转发才能到达主机B。IP协议解决的就是在这个传输过程中为什么要去这个路由器子网而不是另一个!
IP 数据包的传输过程也和问路一样:
我们可以查看自己主机的路由表:
Destination
表示这台主机可以找到的网络;Gateway
表示下一次路由一个将报文交给哪台主机;Genmask
表示对应的子网掩码;face
是发送接口;Flags
中的 U 标志表示此条目有效( 可以禁用某些条目 ),G标志表示此条目的下一跳地址是某个路由器的地址,没有G 标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。如果在路由器中没有查到对应的网络,就会执行default
的过程,找到缺省的路由器。举个例子:
假如有这样的一个报文: src:XXXX DST:172.27.2 通过对目的IP与子网掩码进行按位与,确定目标网络。在
Destination
找到对应的网络就通过对应接口进行发送;没有找到就按照default
进行发送。
对于IP协议的报头我们到目前为止讲解了大部分的字段:
15 * 4 = 60字节
。那么就只剩下16位标识,3位标志,13位片偏移没有涉及过。而IP分片与组装就会使用了!
在网络协议栈中,从上到下依次是应用层,传输层,网络层,数据链路层。现在我们正在学习的是网络层,当网络层将数据传给数据链路层时,数据链路层也会加上对应的报头结构。
MTU
(比如最大1500字节)那么网络层传下来的数据只能小于MTU - 数据链路层报头
。网络层的分片转发会对传输层的数据进行分割,传输层不在意是否分片,只要求报文可以成功发送并接收到应答。数据链路层也不在意是否分片,你给我数据链路层什么数据我就发送什么数据。 那么最终,传输层的一个报文就会分成多片进行发送,接收方如何知道每次的报文是一个整体,也就是网络层进行组装!
我们可以给出几个结论:
对于分片策略,只有网络层可以处理,而分片造成的丢包问题最终是要由传输层进行解决的! 所以传输层就意识到最好不要进行分片!那么传输层也做出相应改变,根据MTU,调整报文大小最大为MTU - 数据链路层报头 - 网络层报头
,也就是TCP传输层缓冲区每次刷新策略!
回看滑动窗口内部为什么还要划分成一个一个的空间?就是保证网络层收到数据后不会进行分片处理!!!尽可能保证不会发生丢包!
至此我们解决了:
上面谈及了网络协议栈中会避免进行分片,但如果出现分片是如何进行的呢?我们一起来看看:
对于服务端来讲,每时每刻都会有大量的报文传输过来,有些是进行分片了的,有些事没有进行分片。那么怎样辨别与组装呢?并保证收集全了?我们来看看组装的这个过程就理解了。
首先我们来看三个字段的含义:
假如现在MTU是1500字节,目前要发送的报文长度是3000字节(20字节数据链路层报头)。
1460字节数据 + 20字节网络层报头 + 20字节数据链路层报头
,第二片是1480字节数据 + 20字节数据链路层报头
,第三片是20字节数据 + 20字节数据链路层报头
0
, 1480
,2960
。根据片偏移规则<<3
对应片偏移字段为0
, 185
,370
。001
,001
,000
那么数据链路层是如何知道分片的呢?我们按照第一片 , 中间部分,最后一片来分析,如果今天分片了:
收到很多分片之后,如何保证收集齐了呢?
自身长度+片偏移量 == 下一篇偏移量
就可以判断出来是否收集全了!那么收集全了,如何进行组装呢?