IP层分包

来源:互联网 发布:sql 查询前10条 编辑:程序博客网 时间:2024/06/05 01:06
    1.在数据链路层有个MTU(Maximum Transmission Unit, 它由硬件规定,例如以太网是1500,大多数的链路的MTU都大等于1500),这个值限定了链路层一个帧的大小,使得一个IP数据报(包括包头)的大小不能超过MTU(IP数据报的大小除了受MTU限制外,也受到接收方的IP实现中的重组缓冲区大小的限制,这将在第2点中介绍,不过可能重组缓冲区的大小与本地MTU相同)。如果IP数据报的大小超过MTU就会在IP层执行IP分包操作,将一个IP划分成多个IP分片,每一个分片都是一个独立的IP数据报。在IP数据报的头部有数据报ID和分片标识符,用于将同一个IP数据报的不同分片重新组合。由于因特网上的各个网段的MTU不同,IP数据报可能会在路由过程中被路由器重新分片。在一条路由路径上最小的MTU叫做路径MTU。如果IP数据报在头部设置了不可分片标志,则路由器丢弃大于本段MTU的IP数据报,并向源主机发送ICMP出错报文(需要分片,但是设置了禁止分片的标志位)。

         2.协议栈中IP层的实现定义了一个最小重组缓冲区大小,它是IPv4的任何实现都必须支持的最小IP数据报,为576。我们不能判定某个给定的目的地能否接受577字节的IP数据报,因此许多使用UDP的IPv4网络应用(例如DNS,RIP等)避免产生大于这个大小的IP数据报(这个大小可能已经过时了,因为现在的操作系统内核一般都提供大于8192+8大小的缓冲区,8192这个数字在第5点中会提到)

        3.我们应该尽量避免IP分片,因为IP分片会带来效率的降低:即使只丢失一片IP分片也要重传整个IP数据报。因为在IP层没有超时重传机制,它必须交由上层的传输层甚至应用层来处理(这样重传的可能就不止是一个IP数据报)。

        4.TCP会尽量避免IP分片的发生,因为在三次握手的过程中双方会相互通知对方自己的MSS(Maximum Segment Size)。这个MSS值指的是每个TCP segment的数据段的最大长度,间接得告诉对方IP层实现的重组缓冲区大小。MSS通常设置成MTU减去IP和TCP头部的固定长度(这里的MTU可能指的是本地MTU,因为TCP协议没有发现路径MTU的机制。而且这个MSS是可以本地设置的)。注意,TCP两端以segment的形式交换数据,但TCP本质是没有分段的,它具有流的特点。TCP的实现从内核的套接口发送缓冲区中取出MSS大小的数据,安上TCP和IP头然后交由下层协议实现处理。

        5.UDP的套接口没有缓冲区。既然UDP是不可靠的,它不必保持应用进程的数据拷贝。应用进程的数据在沿协议栈向下传递时,以某种形式拷贝到内核的缓冲区,然而数据链路层在送出这些数据后将丢弃该拷贝。UDP套接口虽然没有缓冲区,但是它有发送缓冲区大小,不过它仅仅是写到套接口的UDP数据报大小的上限。如果应用进程写一个大于套接口发送缓冲区大小的数据,内核将返回一个EMSGSIZE的错误。现在大多数系统都默认提供大于可读写大于8192的UDP数据报。但是这并不意味着可以发送这么大的UDP包,因为大的UDP包会导致IP分片,降低效率。

0 0
原创粉丝点击