为什么我们使用 UDP 发送会有最大的限制,为什么在 RTP 发送视频码流时会分包为小于 MTU 的包去发送?这一切都要从 IP 层的协议说起。
OSI 七层协议大家都已经非常清楚,其中比较典型的 TCP/IP 协议栈就实现了其中的传输层和网络层,IP (Internet Protocol)协议就是一个网络层的协议,它主要实现了对传输层 (TCP, UDP, RawIp)发送的数据进行分片发送,并决定路由,对收到的 IP 分片进行组帧。然后到下面的链路层。但问题来了,一般链路层都会有自己能承受的最大发送单元(MTU)这个限制,如果是以太网组成的链路,那么 MTU 一般为 1500,也就是说,链路层所承受的载荷最大不能超过 1500,否则发送将失败,也就是整个数据包在链路层,它会认为是由链路层的头部,以太网的为 14(6+6+2)字节的头,加上载荷,而这个载荷不能超过 1500,也就成为网络层,这里我们叫它 IP 层,它的头部加上自己的载荷不能超过 1500,这个 MTU 的限制,所以在 IP 层向链表层封包时,要确保自己的整个数据包不大于 MTU,那么不大于 MTU 的数据到了 IP 层也不用分片,在某种程序上就会使效率提交。
OSI 七层协议大家都已经非常清楚,其中比较典型的 TCP/IP 协议栈就实现了其中的传输层和网络层,IP (Internet Protocol)协议就是一个网络层的协议,它主要实现了对传输层 (TCP, UDP, RawIp)发送的数据进行分片发送,并决定路由,对收到的 IP 分片进行组帧。然后到下面的链路层。但问题来了,一般链路层都会有自己能承受的最大发送单元(MTU)这个限制,如果是以太网组成的链路,那么 MTU 一般为 1500,也就是说,链路层所承受的载荷最大不能超过 1500,否则发送将失败,也就是整个数据包在链路层,它会认为是由链路层的头部,以太网的为 14(6+6+2)字节的头,加上载荷,而这个载荷不能超过 1500,也就成为网络层,这里我们叫它 IP 层,它的头部加上自己的载荷不能超过 1500,这个 MTU 的限制,所以在 IP 层向链表层封包时,要确保自己的整个数据包不大于 MTU,那么不大于 MTU 的数据到了 IP 层也不用分片,在某种程序上就会使效率提交。
那么这个 MTU 是不是我们使用 UDP 发送时的最大单次发送限制呢?不是,为了让传输层能够使用方便,即使传输层发送的数据大于 MTU 也没有关系,因为 IP 层会对大于 MTU 的数据进行分片,我们来看看 IP 层协议的头信息就知道了。
struct iphdr {
__u8 version:4,
ihl:4;
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
</