(参考文献)TCP/IP详解,卷1:协议
UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。UDp数据报封装成IP数据报格式如下图:
UDP首部
UDP首部的各个字段如下图:
端口号表示发送进程和接收进程。由于IP层已经把数据报分配给TCP或者UDP(根据IP首部中协议字段值),因此TCP端口号有TCP查看,UDP端口号由UDP查看。TCP端口号与UDP端口号时是相对独立的。
UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节(即没有数据时的情况)。
UDP和TCP在首部中都有覆盖他们首部和数据的校验和。UDP校验和是可选的,而TCP校验和是必须的。
IP分片
物理网络层一般要限制每次发送数据帧的最大长度。任何时候IP层收到一份要发送的IP数据报时,他要判断向本地哪个接口发送数据(选路),并查询该接口获取MTU。IP把MPU和数据报进行比较较,如果需要。则进行分片。分片可以发生在原始发送端上,也可以发送在中间路由器上。
把一数据报进行分片后,只有到达目的地才进行重新组装(这里的重新组装与其他网络协议不同,他们要求下一站就进行重新组装,而不是在最终目的地)。重新组装由目的地的IP层来完成。已经分过片的数据报有可能再次进行分片。IP首部中包含的数据位分片和重组提供了足够的信息。
如上图,对于发送端发送的每份IP数据报来说,其标识字段都包含一个唯一值。该值在数据报分片时被复制到每个片中。标志字段用一个比特位来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置一。片偏移字段指的是该片偏移原始数据报开始处的位置。另外,该数据报被分片后,每个片的总长度值要为该片的长度值。
最后,标志字段中有一个比特称作“不分片”位。如果将这一比特置1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文(需要进行分片但设置了不分片比特)给起始端。
当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时和其他分组独立。这样,当数据报到达目的端时有可能失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据片。
IP数据报与分组
IP数据报是指IP层端到端的传输单元(在分组之前和重新组装之后)。分组是指在IP层和链路层之间传送的数据单元,一个分组可以是一个IP数据报,也可以是IP数据报的一个分片。
广播和多播
IP 地址分三种:单播地址、广播地址和多播地址。
广播和多播仅应用于UDP,它们对需将报文同时传往多个接收者的应用来说十分重要。TCP是一个面向连接的协议,它意味着分别运行于两主机内的两进程间存在一连接。
考虑包含多个主机的共享信道网络,如以太网。每个以太网帧包含源主机和目的主机的以太网地址(48bit)。通常每个以太网帧仅发往单个目的主机,目的地址指往单个接收接口,因而称为单播。
然而,有时候一个主机要向网络上的所有主机发送帧,这就是广播。通过ARP和RARP可以看到这一过程。多播处于单播和广播之间,帧只发送属于多播组的多个主机。
要了解广播和多播,需要了解主机对由信道传送过来帧的过滤过程。
首先,网卡查看由信道传送过来的帧,确定是否接受该帧,若接收后就把他传往设备驱动程序。通常网卡仅接收那些目的地址为网卡物理地址或广播地址的帧。另外,多数接口被设置为混杂模式,这种模式能够接收每个帧的一个复制。
目前,大多数的网卡经过配置都能接收目的地址为多播地址或某些子网多播地址的帧。对于以太网,当地址中最高啊字节的最低位设置为1时表示改地址是一个多播地址,用十六进制可表示为01:00:00:00:00:00(以太网广播地址ff:ff:ff:ff:ff:ff可以看做是以太网多播地址的特例)。
如果网卡收到一个帧,这个帧将被传送给设备驱动程序(如果帧检验和错,网卡就会丢弃该帧)。设备驱动程序将进行另外的帧过滤。首先,帧类型中必须指定要使用的协议(IP、ARP等等),其次,进行多播过滤来检查该主机是否属于多播地址说明的多播组。
设备驱动程序随后将数据帧传送给上一层,比如,当帧类型指定为IP数据报时,就传往IP层。IP根据IP地址中的源地址和目的地址进行更多的过滤监测。如果正常,就把数据报再传送给上一层(TCP或UDP层)。
每次UDP收到有IP传送过来的数据报,就根据目的端口号,有时还根据源端口号进行数据报过滤。如果当前没有进程使用目的端口号,就丢弃该数据报,并产生一个ICMP不可到达 报文(TCP根据端口号做相似的处理)。如果UDP数据报出现检验和错,数据报将被丢弃。
多播之于广播出现的原因
使用广播的问题在于,它增加了对广播数据不感兴趣主机的处理负荷。拿一个使用UDP广播应用作为例子。如果网络内有50个主机,但仅有20个参与该应用,每次这20个主机中的一个发送UDP广播数据时,其余30个主机不得不处理这些广播数据报。一直到UDP层收到的广播数据报才会被丢弃。这30个主机丢弃该数据报的原因是因为这些主机没有使用该目的端口。
多播的出现减少了对应用不感兴趣主机的处理负荷。使用多播,主机可以加入一个或者多个多播组,这样网卡就仅接收主机所在多播组的那些数据帧。
广播
广播地址主要有4种:受限的广播、指向网络的广播、指向子网的广播、指向所有子网的广播。
受限的广播
受限的广播地址是255.255.255.255。该地址用于主机配置过程中IP数据报的目的地址,此时,主机可能还不知道它所在网络的网络掩码甚至连他的IP地址也不知道。
在任何情况下,路由器都不转发目的地址为受限的广播地址的数据报,这样的数据报仅出现在本地网络中。
指向网络的广播
指向网络的广播地址是主机号全为1的地址。A类网络广播地址为netid.255.255.255,其中netid为A类网络的网络号。
一个路由器必须转发指向网络的广播,但它也必须有一个不进行转发的选择。
指向子网的广播
指向子网的广播地址为主机号全为1且有特定子网号的地址。作为子网直接广播地址的IP地址需要了解子网的掩码。例如,如果路由器收到发往128.1.2.255的数据报,当B类网络128.1的子网掩码为255.255.255.0时,该地址就是指向子网的广播地址;但如果该子网的掩码为255.255.254时,该地址就不是指向子网的广播地址。
指向所有子网的广播
指向所有子网的广播也需要了解目的网络的子网掩码,以便于指向网络的广播地址区分开。指向所有子网的广播地址的子网号及主机号全为1例如如果目的地址子网掩码为255.255.255.0,那么IP地址128.1.255.255是一个指向所有子网的广播地址。然而,如果网络没有划分子网,这就是一个指向网络的广播。
多播
IP多播提供两类服务:
1. 向多个目的地址传送数据。有许多向多个接收者传递信息的应用:例如交互式会议系统或向多个接收者分发邮件或新闻。如果不采用多播,目前这些应用都采用TCP来完成(向每个目的地址传送一个单独的数据复制)。然而,即使使用多播,某些应用任然采用TCP来保证他的可靠性。
2. 客户对服务器的请求。例如,无盘工作站需要确定启动引导服务器,目前这项服务是通过广播来提供的,但是如果采用多播,则可以降低不提供这项服务主机的负担。
多播组地址
不像其他IP地址(A、B、C类地址),分配的28bit均用作多播组号,而不再表示其他。
多播组地址包括为1110的最高4bit和多播组号。它表示的地址范围从224.0.0.0到239.255.255.255 。这个地址段是保留个本地网络分段网络协议的,类似广播报文,路由器是不会转发多播报文的。
能够接收发往一个特定多播组地址数据的主机集合称为主机组。一个主机组可跨越多个网络。主机组中成员可随时加入或离开主机组。主机组中对主机的数量没有限制,同时不属于某一主机组的主机可以向该组发送信息。
一些多播组地址被IANA确定为知名地址。他们也被当做永久主机组,这和TCP和UDP中的熟知端口相似。例如:224.0.0.1代表“该子网内的所有系统组”,224.0.0.2代表“该子网内的所有路由器组”。多播组地址224.0.1.1用作网络时间协议NTP。
多播组地址到以太网地址的转换
同单播地址和广播地址一样,多播IP地址也需要相应的多播MAC地址在本地网络中实际传输帧。根据IANA规定,多播MAC地址以十六进制值01-00-5E打头,余下的6个十六进制是根据IP多播组地址的最后23位转换得到的。
由于多播组号中的最高5bit在映射过程中被忽略,因此每个以太网多播地址对于的多播组是不唯一的。32个不同的多播组号被映射为一个以太网地址。例如,多播地址224.128.64.32(十六进制e0.80.40.20)和224.0.64.32(十六进制e0.00.40.20)都映射为同一个以太网地址01:00:5e:00:40:20 。
既然地址映射不是唯一的,那么设备驱动程序或者IP层就必须对数据报进行过滤。因为网卡可能接收到主机不想接收的多播数据帧。另外,如果网卡不提供足够的多播数据过滤功能,设备驱动程序就必须接收所有多播数据帧,然后对他们进行过滤。
D类IP地址到以太网多播地址的映射:
单个物理网络的多播是简单的。多播进程将目的ip地址指明为多播地址,设备驱动程序将它转换为相应的以太网地址,然后把数据发出去。当一个主机接收到多播数据报时,他必须向属于那个多播组的每个进程均传送一个复制。这个单个进程收到单播UDP数据报的UDP不同。使用多播,一个主机上可能存在多个属于同一多播组的进程。
当把多播扩展到单个物理网络以外需要通过路由器转发多播数据时,需要有一个协议让多播路由器了解确定网络中属于确定多播组的任何一个主机。这个协议就是Internet组管理协议(IGMP)。
IGMP:Internet组管理协议
一般情况下,多播数据只在局域网内传播,当需要将多播数据通过路由器转发时,就需要用到IGMP协议。
IGMP协议(加入一个多播组)
多播的基础就是一个进程的概念,该进程在一个主机给定的接口上加入了一个多播组。在一个给定接口上的多播组中的成员是动态的——他随时因进程加入和离开多播组而变化。
这里暗示一个主机通过组地址和接口来识别一个多播组。主机必须保留一个表,表中包含所有至少含有一个进程的多播组以及多播组中的进程数量。
IGMP报告和查询
多播路由器使用IGMP报文来记录与该路由器相连网络中组成员的变化情况,IGMP报文通过IP数据报来进行传输,如:
1) 当第一个进程加入一个多播组时,主机就发送一个IGMP报告。如果一个主机的多个进程加入同一组,只发送一个IGMP报告。
2) 进程离开一个组时,主机不发送IGMP报告,即使是组中的最后一个进程离开。主机知道在确定的组中不再有组成员后在随后收到多播路由器的IGMP查询中就不再发送报告报文。
3) 多播路由器定时发送IGMP查询来了解是否还有任何主机包含有属于多播组的进程。多播路由器必须向每个接口发送一个IGMP查询。因为路由器希望主机对他加入的每个多播组均发回一个报告。
4) 主机通过IGMP报告来响应一个IGMP查询,对每个至少包含一个进程的组都要发回一个IGMP报告。
使用这些查询和报告报文,多播路由器对每个接口保持一个表,表中记录接口(这里的接口是的是一个socket套接字)上至少还包含一个主机的多播组。当路由器收到要转发的多播组数据报时,他只将数据报转发到还拥有属于那个组主机的接口上。
IGMP实现细节
为了改进IGMP协议的效率,有许多实现的细节需要考虑。首先,当一个主机首次发送IGMP报告(当第一个进程加入一个多播组)时,并不保证该报告被可靠接收(因为ip协议的不可靠性)。所以下一个报告将在间隔一段时间后发送。这个时间间隔由主机在0到10秒的范围内随机选择。
其次,当一个主机收到一个从路由器发出的查询后,并不立即响应,而是进过一定的时间间隔才发出一些响应。既然参加同一个多播组的多个主机均能发送一个报告,可将他们的发送时间间隔设为随机延时。在一个物理网络中的所有主机将收到同组其他主机发送的所有报告(因为IGMP的目的地址是所有主机组地址:224.0.0.1)。这意味着,如果一个主机在等待发送的过程中,却收到了来自其他主机的相同报告,则该主机的相应就可以不必发送了。因为多播路由器并不关心有多少主机属于该组,而只关心该组是否还至少拥有一个主机。也就是说,一个多播路由器甚至不关心哪个主机属于一个多播组。它仅仅想知道在给定的接口上的多播组中是否还至少有一个主机。
IGMP生存时间字段
一般情况下IGMP报告和查询的生存时间(TTL)均设置为1 。在默认情况下,待传多播数据报的TTL被设置为1,这将使多播数据报仅局限在同一子网内传输。更大的TTL值将被多播路由器转发。
对发往一个多播地址的数据报从不会产生ICMP差错。当TTL值为0时,。多播路由器也不会产生ICMP“超时”差错。
所有主机组
多播路由器的IGMP报文会被送到目的IP地址224.0.0.1。该地址被称为所有主机地址。