TCP/IP协议---UDP协议

时间:2023-12-12 20:48:50

    UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都产生一个UDP数据报,并组装成一份待发送的IP数据报。UDP数据报是要依赖IP数据报传送的。UDP协议并不可靠,它不能保证发出去的包会被目的端接收。

TCP/IP协议---UDP协议

TCP/IP协议---UDP协议

UDP首部的前8个字节:
16bit的源端口号、16bit的目的端口号、16bit的UDP长度、16bit的UDP检验和
1. 端口号可以代表用户的程序,分别表示发送进程和接收进程。
2. UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节(发送一份0字节的UDP数据报是OK)。这个UDP长度是有冗余的。IP数据报长度指的是数据报全长(包括IP首部和数据部分,这个数据部分可能就是UDP的),因此UDP数据报长度是全长减去IP首部的长度。
3. UDP的检验和:UDP和TCP的检验和是包括首部和数据部分的。此前的IP检验和只是计算IP首部的,而不包括数据部分。
求检验和的算法和IP检验和类似,但也有不同。UDP的长度可以是奇数字节,就是说可能不够16bit的倍数,算法要求是每16bit进行求和,这样就需要填充一些字节0,满足达到16位的倍数,当然这只是为了计算检验和的动作,而真正的UDP传输是不会有这些填充0的。
再一个不同于IP求检验和的是,为了计算UDP或者TCP的校验和,需要有个伪首部,伪首部要参与计算检验和。

伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地(ps这块理解的不太好..例如,IP没有接受地址不是本主机的数据报,以及IP没有把应传给另一高层的数据报传给UDP)。格式如图:

TCP/IP协议---UDP协议

可以发现,UDP数据报的长度在检验和计算过程中出现两次,首部和伪首部中都有。
如果检验和的计算结果为 0,则存入的值为全1,这在二进制反码计算中是等效的。如果传送的检验和为0,说明发送端没有计算检验和。
UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为发现UDP首部和数据在发送端到接收端之间发生的任何改动。
从计算检验和的算法中可以发现,既然是每个16bit的和,那么即便是交换两个端口号,交换伪首部的两个ip,也不影响检验和。表明UDP检验和(事实上,TCP/IP协议簇中所有的检验和)是简单的16bit和。它们检测不出交换两个16bit的差错。

- IP分片:

IP层到链路层发送帧的时候,又或者IP层收到一份IP数据报的时候,要查询往哪个接口转发(路由选路),当发现这个数据报的长度超过了这个链路或者说接口的MTU(路由每个接口都可能有各自的MTU),就会发生分片。也就表示分片可以发生在原始发送端主机上,也可以发生在中间路由器上。
IP分片后,只有到达了目的端才进行重组。已经分片过的数据报有可能会再次进行分片(可能不止一次)。IP首部中包含的数据为分片和重新组装提供了足够的信息。
在IP首部中,讲到过16bit标识,3bit标志和13bit片偏移。标识唯一标识了一个数据报。被分片以后,每个片(分组)都拷贝下这个标识。标志有个保留位,有个不分片位(1为不分片,0为可以分片),有个更多片位(分片后,除了最后一个分片为0,其它片都是1,为了告诉接收端啥时候组装完这个数据报)。
几个术语: IP数据报是指IP层端到端的传输单元(在分片之前和重新组装之后),分组是指在IP层和链路层之间传送的数据单元。显然一个分组可以是一个完整的 IP数据报,也可以是IP数据报的一个分片。
如图:   值得注意的是,任何传输层首部只出现在第1片数据中。

TCP/IP协议---UDP协议

看一下分片时,tcpdump出来的内容。如图:

TCP/IP协议---UDP协议

前两行可以看出来没有经过ip分片。第三行开始分片。第三行说明一下:

upd 1473 (frag 26304:1480@0+)

1473表示UDP数据的长度(除掉了UDP头部的长)

26304表示是IP首部中的标识。

1480表示UDP的长度(包括了UDP首部的8个字节长,表示数据长是1472,注意只有这个第一片有UDP首部,同一个标识里其它分片没有...)

@后边这个0表示偏移量。+号表示更多片位,出了最后一个分片分组没有,其它分片都要有。

第四行同理。

- ICMP不可达差错(需要分片)
发生ICMP不可达差错的另一种情况是,当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片(DF)的标志比特。
这个ICMP报文的类型是3,代码是4。
从这个特性中看出来,可以做一个程序,用来判断到达目的端的路途中最小MTU是多少--这称作路径MTU发现机制。
利用traceroute程序可以确定路径的MTU。路由器可以设置是否在ICMP不分片差错中返回下一跳的MTU值,不返回的话MTU就置为0。

-UDP和ARP之间的交互:

发送一个超过MTU大小的UDP包,因此是要分片的。当没有目的主机ARP缓存的时候,发送帧的时候要获取硬件地址。
比较意想不到的是,每一个分片都发送了一个ARP请求。。在大多数的协议实现中,在等待一个ARP应答时,只将最后一个报文(从tcpdump输出结果可以发现这个报文在更多片位中是没有+号的)发送给特定目的主机,其它的就被丢弃了。
在目的端收到第一个分片的时候,就开始生成一个计时器,大约在30或者60s的时候,如果这个数据报的所有分片没全部集齐,就舍弃掉这些分片(如果不舍弃,那接收端缓存早晚挤爆了哈哈)。
这里接收端只收到了一个最后的分片,为什么在发送端没接收到ICMP组装超时类型的报文呢?原因可能有两个:1. 计时器超时了就舍弃,压根就产生这个ICMP报文。2. 如果接收端接收的不是第一个分片,那么就不会产生ICMP报文(因为第一个分片才有传输层首部,才知道端口号,对应哪个用户进程。ICMP报文当然是需要这个首部了~)。

- ICMP源站抑制差错

当接收端的处理速度小于接收速度了,接收端就可能(不一定)返回一个ICMP源站抑制差错报文。

新的协议规定,不太建议有这个ICMP报文发送。UDP协议接到这个抑制差错报文时,一般会忽略掉。。部分原因是,导致这个抑制差错报文产生的进程可能已经完事了,意思就是我这个源端产生的UDP数据报都已经发完了,你再给我这个差错报文提醒也没啥用了哈哈。

-