最近为了维护一个抓包程序,搜索了好几篇文章,发现以下这一篇有点收藏价值,复制过来收藏吧,方便以后自己阅读。
1.IP+ICMP+DATA = 1500字节
2.ping size指定的是data的大小.
3,可以ping大包+不分片检测mtu(分片发生在出口,如果包尺寸大于接口ip mtu,则干脆不往出发包)
我们都知道,在以太网中,如果源主机向目标主机发送的数据包大于网关MTU
,则该数据包在传输过程中会被IP协议分片
传输,具体的分片过程是怎样的呢?我们通过协议分析软件抓包来进行详细的查看(抓包软件使用科来网络分析系统)。
因为以太网默认的MTU
值为1500
Byte,所以,为了达到分片的效果,我们应该传输大于1500
Byte字节的数据包,才能使该数据包分段传输。
我们从本机(192.168.6.11)发送一个2000字节的数据包到局域网的另一台主机(192.168.0.208)为例,在传输的过程中,开启软件抓包,就能够查看到详细的分片结果。
我们以ping为例,在Windows命令提示符下输入:ping 192.168.0.208 -l 2000
通过科来网络分析系统抓包,我们看到,该数据包被分片了,由于我们重复Ping了4次,所以,抓到了4次同样的请求与回显的数据包。如下图:
查看详细的数据包解码(见下图):
分析:因为ping的长度是2000字节,大于了MTU
的值,所以会分片发送,如上图。捕获的这个数据包总长度为1500
字节,更多分段位置1,表示还有数据分段。s,偏移量为0,需要注意的是IP头部的总长度字段值(这里是1500
字节)并不全是数据的净载荷长度,这里还包括了IP
以及ICMP
的头部长度,分别是20字节和8字节。
另外,IP协议
的头部总长度并不一定就是MTU
值1500
字节,这个值与网络环境、操作系统等因素有关。
下图是第一个分片包:
分析:IP字段的标识0x787F
,与第一个包相同,说明这是同一个数据包,只是被分片了。
偏移量为185
,表示相对第一个包的位置,以便接收主机根据偏移量进行数据重组。
需要注意的是此处分片包并没有ICMP
字段,接收主机会可以根据偏移重组成完整的ICMP
数据包。
最后,我们来计算一下该数据包的长度:
默认的MTU
1.IP+ICMP+DATA = 1500字节
2.ping size指定的是data的大小.
第一个数据包
的总长度为1500
字节,减去IP头部长度20
字节,减去ICMP
头部长度8字节,即1500-20-8=1472
字节;
第二个数据包
的总长度为548
字节,减去IP
头部长度20
字节,即548-20=528
字节,两个数据包的净载荷1472+528=2000
,正好是我们发送的数据长度。
MTU
和MSS
首先说明:数据报的分段和分片确实发生,分段发生在传输层,分片发生在网络层。但是对于分段来说,这是经常发生在UDP传输层
协议上的情况,对于传输层使用TCP协议
的通道来说,这种事情很少发生。
TCP层
的分段和IP层
的分片之间的关系 & MTU和MSS
之间的关系
首先说明:数据报的分段和分片确实发生,分段发生在传输层,分片发生在网络层。但是对于分段来说,这是经常发生在UDP传输层协议上的情况,对于传输层使用TCP协议的通道来说,这种事情很少发生。
(1)以太网和802.3对数据帧的长度都有一个限制,其最大 值分别是1500和1492
个字节。链路层的这个特性称作MTU。不同类型的网络大多数都有一个上限。如果IP层有一个数据要传,且数据的长度比链路层的 MTU
还大,那么IP层就要进行分片(fragmentation),把数据报分成若干片,这样每一个分片都小于MTU。
(2)把一份IP数据报进行分片以后,由到达目的端的IP层来进行重新组装,其目的是使分片和重新组装过程对运输层(TCP/UDP
)是透明的。由于每一分片都是一个独立的包,当这些数据报的片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。
(3)尽管IP分片过程看起来透明的,但有一点让人不想使用它:即使只丢失一片数据也要重新传整个数据报。why?因为IP层本身没有超时重传机制------由更高层(比如TCP)来负责超时和重传。当来自TCP报文段的某一片丢失后,TCP在超时后会重发整个TCP报文段,该报文段对应于一份IP数据报(而不是一个分片),没有办法只重传数据报中的一个数据分片。
(4)使用UDP
很容易导致IP分片,TCP试图避免IP分片。 那么TCP是如何试图避免IP分片的呢?其实说白了,采用TCP协议进行数据传输是不会造成IP分片的,因为一旦TCP数据过大,超过了MSS
,则在传输 层会对TCP包进行分段(如何分,见下文!),自然到了IP层的数据报肯定不会超过MTU
,当然也就不用分片了。而对于UDP数据报,如果UDP组成的 IP数据报长度超过了1500,那么IP数据报显然就要进行分片,因为UDP不能像TCP一样自己进行分段。总结:UDP不会分段,就由我IP来分。TCP会分段,当然也就不用我IP来分了!
(1)MSS
就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes
)所以往往MSS为1460
。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。
(2)相信看到这里,还有最后一个问题:TCP是如何实现分段的呢?其实TCP无所谓分段,因为每个TCP数据报在组成前其大小就已经被MSS限制了,所以TCP数据报的长度是不可能大于MSS的,当然由它形成的IP包的长度也就不会大于MTU,自然也就不用IP分片了。
1.IP分片产生的原因是网络层的MTU
;TCP
分段产生原因是MSS
.
2.IP分片由网络层完成,也在网络层进行重组;TCP
分段是在传输层完成,并在传输层进行重组. //透明性
3.对于以太网,MSS
为1460
字节,而MUT往往会大于MSS
.
故采用TCP协议进行数据传输,是不会造成IP分片的。若数据过大,只会在传输层进行数据分段,到了IP层就不用分片。
所以可以看成是这种情况:传输层协议想发送一个超过了MTI的数据报,这个时候网络层就需要对其进行分片,一般UDP
和ICMP
会出现分片情况,但是TCP不会出现这种情况!因为TCP使用了MSS来避免分片!
IP分片只有第一个带有传输层或ICMP首部,其余的分片只有IP头。至于怎么重组就是到对端以后IP层的事情了。
若TCP报文非常长那么在IP层传输时就有可能要分解成多个短数据报片。(计算机网络谢希仁)
TCP分段
每个都有完整首部。
PS:所以我觉得是这样的,TCP的分段是针对应用层的数据来说的,比如使用TCP发送70KB的数据,这个时候就需要将70KB分成若干个MSS,到了网络层就不需要分片了。MSS的存在就避免了网络层分片的发生,
IP层
的分片是针对传输层中使用UDP协议来说的,如果使用UDP发送数据,UDP
并不知道如何分段,那么到了IP层就需要进行分片,分片的原则根据MTU
,那么分UDP
最大的数据负载就是1500-8=1492
看完了理论,让我们实践一把,看是否与以上的理论相符。
对于TCP
来说,它是尽量避免分片的。假设我们这里要发送给TCP层的数据大小为2748个字节,这个大小是明显大于链路层的发送数据的大小的,在这个情况
下我们来看,对于来自TCP层
的数据,IP会不会进行分片。
从第一张图看来,应用层的2748个字节在TCP层就进行了分段,分层了两个TCP段,一个1460字节,一个1288字节。那么到IP层的时候,自然就不会在进行分片了。
从第二张图片看出,在这两个TCP
分段中,在序号3处,IP的头部字段(Don ’ t Fragment) 被设置了,用于告诉IP层不要对该数据进行分片。
而对于MSS大小的协商,我们可以从下面这张图片看到,下面的图片是TCP CLIENT发出的第一个SYN TCP分段:
对于UDP
来说,假设我们要发送的一个UDP
数据包大小为1600
个字节,那么在实际上通过UDP/IP
分发出去的时候,会不会进行分片呢? 看如下的图片:
从上面的图片可以看出,我们发送的数据包的大小为1600
字节(序号1
处),在UDP
层,长度为1608
字节(序号2
处),这里的8个字节是UDP
的头部字段的长度, 到了IP层(序号3
处),我们可以清楚的看到IP对UDP
数据包进行了分片,一个大小为1480
字节,一个为128
字节。
一个以太帧最大为1518
字节 (14字节以太首部,20字节IP首部,UDP8/TCP20
,因此IP包每次最大为1500==MTU
。去掉协议头UDP有效数据1472
字节,TCP为1460
字节。还有最后的4字节CRC),但是一个IP数据报则可能会有8192
字节,超过以太帧的最大限制,那么这时就需要IP分片,分批进行传输。
发送方会在IP层将要发送的数据分成多个数据包分批发送,而接收方则将数据按照顺序再从新组织起来,等接收到一个完整的数据报之后,然后再提交给上一层传输层。