TCP-IP详解卷1-11:UDP(User Datagram Protocol):用户数据报协议

TCP-IP详解卷1-11:UDP(User Datagram Protocol):用户数据报协议

一:介绍
    1: 数据报。在OSI模型中,在第四层——传输层,处于IP协议的上一层。
        UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
    2: MTU(Maximum Transmission Unit):应用程序必须关心IP数据报的长度。如果它超过网络的MTU,那么就要对IP数据报进行分片。
        如果需要,源端到目的端之间的每个网络都要进行分片,并不只是发送端主机连接第一个网络才这样做。

二:特征
    1: UDP是一个无连接协议,传输数据之前源端和终端不建立连接。
        当UDP它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。
        在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;
        在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
    2: 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
    3: UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
    4: 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
    5: UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。 
    6: UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。 

三:格式
    1: IP数据报:IP首部(20B)+UDP首部(8B)+UDP数据
    2: UDP首部:源端口号(2B)+目的端口号(2B)+UDP长度(2B)+UDP校验和
        端口号表示发送进程和接收进程。
        UDP长度:UDP首部(8B)+UDP数据(当长度为0时,值为OK)。即=IP数据报长度-IP首部长度
    3: 校验和:IP校验和只覆盖IP首部,而UDP校验和覆盖UDP首部和UDP数据。该项可选。TCP必须
        由于UDP数据长度可能为奇数,所以107的计算长度中,可以考虑单独加一个,或后面补0, 凑足偶数。
        如果发送端没有计算检验和而接收端检测到检验和有差错,那么UDP数据报就要被悄悄地丢弃。不产生任何差错报文(当IP层检测到IP首部检验和有差错时也这样做)。
        UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。
    4: 伪首部
        A: 要时刻谨记一个“伪”字,既然是“伪”首部,也就是假的,不仅是“假”首部,而且“假”到连地址空间都没有。
            也就是说伪首部是不占地址空间的,在实际传输中不存在这样的字段。
            只是在使用的时候把它拿出来一下。
        B: 既然设置了伪首部,那么肯定就是有用的——为了计算检验和!书中原话“其目的是让UDP两次检查数据是否已经正确到达目的地”,具体是那两次呢?
            我们注意伪首部字段:32位源IP地址、32位目的IP地址、8位协议、16位UDP长度。由此可知,
            第一次,通过伪首部的IP地址检验,UDP可以确认该数据报是不是发送给本机IP地址的;
            第二,通过伪首部的协议字段检验,UDP可以确认IP有没有把不应该传给UDP而应该传给别的高层的数据报传给了UDP。
            从这一点上,伪首部的作用其实很大。

四:IP分片
    1: 物理网络层一般要限制每次发送数据帧的最大长度。
        任何时候IP层接收到一份要发送的IP数据报时,它要判断向本地哪个接口发送数据(路由),并查询该接口获得其MTU。
        IP把MTU与数据报长度进行比较,如果需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。
    2: 把一份IP数据报分片以后,只有到达目的地才进行重新组装(这里的重新组装与其他网络协议不同,它们要求在下一站就进行进行重新组装,而不是在最终的目的地)。
        重新组装由目的端的IP层来完成,其目的是使分片和重新组装过程对运输层(TCP和UDP)是透明的
    3: IP首部这些字段用于分片过程。
        对于发送端发送的每份IP数据报来说,其标识字段都包含一个唯一值。该值在数据报分片时被复制到每个片中(我们现在已经看到这个字段的用途)。
        标志字段用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置1。
        片偏移字段指的是该片偏移原始数据报开始处的位置。
        另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。
        而且,标志字段中有一个比特称作“不分片”位。如果将这一比特置1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文给起始端。
    4: 当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。
        这样,当数据报的这些片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。
    5: 尽管IP分片过程看起来是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报。为什么会发生这种情况呢?
        因为IP层本身没有超时重传的机制——由更高层来负责超时和重传(TCP有超时和重传机制,但UDP没有。一些UDP应用程序本身也执行超时和重传)。
        当来自TCP报文段的某一片丢失后,TCP在超时后会重发整个TCP报文段,该报文段对应于一份IP数据报。没有办法只重传数据报中的一个数据报片。
        事实上,如果对数据报分片的是中间路由器,而不是起始端系统,那么起始端系统就无法知道数据报是如何被分片的。就这个原因,经常要避免分片。
    6: 使用UDP很容易导致I P分片(在后面我们将看到, TCP试图避免分片,但对于应用程序来说几乎不可能强迫TCP发送一个需要进行分片的长报文段)。
        在一个以太网上,数据帧的最大长度是1500字节,其中1472(1500-20-8)字节留给数据,假定IP首部为20字节, UDP首部为8字节。
    7: 发送的用户数据为1 4 7 3字节,分片情况如下所示。需要重申的是,任何运输层首部只出现在第1片数据中。
        IP首部(20B)+UDP首部(8)+数据(1472)+IP首部(20)+数据(1B)
    8: IP数据报是指IP层端到端的传输单元(在分片之前和重新组装之后);
        分组是指在IP层和链路层之间传送的数据单元。
        一个分组可以是一个完整的IP数据报,也可以是IP数据报的一个分片。

五:MTU
    1: RFC 1191描述了“路径最大传输单元发现方法”,这是一种确定两个IP主机之间路径最大传输单元的技术,其目的是为了避免IP分片。
        在这项技术中,源地址将数据报的DF(Do not Fragment,不要分片)位置位,再逐渐增大发送的数据报的大小——路径上任何需要将分组进行分片的设备都会将这种数据报丢弃并返回一个“数据报过大”的ICMP响应到源地址——这样,源主机就“学习”到了不用进行分片就能通过这条路径的最大的最大传输单元了。
    2: 不幸的是,越来越多的网络封杀了ICMP的传输(譬如说为了防范DDOS攻击)——这使得路径最大传输单元发现方法不能正常工作,其常见表现就是一个连接在低数据流量的情况下可以正常工作,但一旦有大量数据同时发送,就会立即挂起。

六:UDP的最大数据报长度
    1: IP数据报的最大长度是65535字节,这是由IP首部16比特总长度字段所限制的。
        去除20字节的IP首部和8个字节的UDP首部, UDP数据报中用户数据的最长长度为65507字节。但是,大多数实现所提供的长度比这个最大值小。
        A: 应用程序可能会受到其程序接口的限制。socket API提供了一个可供应用程序调用的函数,以设置接收和发送缓存的长度。
            对于UDP socket,这个长度与应用程序可以读写的最大UDP数据报的长度直接相关。
            现在的大部分系统都默认提供了可读写大于8192字节的UDP数据报(使用这个默认值是因为8192是NFS读写用户数据数的默认值)。
        B: 第二个限制来自于TCP/IP的内核实现。可能存在一些实现特性(或差错),使IP数据报长度小于65535字节。
    2: 由于IP能够发送或接收特定长度的数据报并不意味着接收应用程序可以读取该长度的数据。
        因此, UDP编程接口允许应用程序指定每次返回的最大字节数。
        如果接收到的数据报长度大于应用程序所能处理的长度,那么会发生什么情况呢?不幸的是,该问题的答案取决于编程接口和实现。
        A: 典型的Berkeley版socket API对数据报进行截断,并丢弃任何多余的数据。
        B: SVR4下的socket API(包括Solaris 2.x) 并不截断数据报。超出部分数据在后面的读取中返回。它也不通知应用程序从单个UDP数据报中多次进行读取操作。
        C: TLI API不丢弃数据。相反,它返回一个标志表明可以获得更多的数据,而应用程序后面的读操作将返回数据报的其余部分。

七:ICMP源站抑制差错
    1: 当一个系统(路由器或主机)接收数据报的速度比其处理速度快时,可能产生这个差错。
        注意限定词“可能”。即使一个系统已经没有缓存并丢弃数据报,也不要求它一定要发送源站抑制报文。

八: UDP服务器
    1: 用各个不同的知名端口号的UDP服务器虽然提供不同的服务,但是其实现原理相似的。以53号知名端口号为例进行说明。
    2: 当在DNS服务器上启动运行DNS服务后,便会在计算机系统上创建一个相应的DNS服务进程。
        DNS服务进程会在53号UDP端口上进行监听所有客户请求。DNS服务进程属于TCP/IP模型中的应用层。
        一端主机应用层需与另一个计算机系统的应用层进行通信,首先会经过TCP/IP模型中的传输层进行通信,这个在传输层与应用层的DNS服务进程进行通信的就是端点。
    3: UDP(TCP)服务器在创建服务进程时便会在传输层(UDP模块,TCP模块)中创建相对应的端点。UDP端点(TCP端点)可分为两类端点:
        A: 监听型端点:在相应的端口上监听各个客户请求及处理。
        B: 接收数据端点:接收该端点能接收的UDP数据报(TCP数据报),然后传给相应的进程或线程(根据不同的操作系统而定)。
    4: 一般启动运行一个UDP服务,只会创建一个与服务进程相对应的监听端点。
        但也可以创建多个服务进程和监听端点(使用Socket API时,需指定SO_REUSEADDR Socket选项)。
        应用程序创建监听端点时,可限制本地IP地址,远端IP地址,远端端口号。
    5: 由于操作系具有并发性不具有并行性,不可能同时的处理每个进程,每个端点又是由进程或线程进行处理。
        这样可导致监听端点上不同客户的差不多同时到达的请求将由UDP自动排队。
        是队列就有大小限制。这样会导致UDP接收队列溢出,对超出数据报进行丢弃处理。
        不会发送任何信息给客户端。在接收数据端点上也存在相同的问题。这一点可表现出UDP协议的不可靠性。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值