We read the world wrong but say that it deceives us.

  "我们看错了世界,却说世界欺骗了我们"

参考资料TCP/IP入门经典 (第五版)

     TCP/IP详解 卷一:协议

一、简介

  UDP(User Datagram Protocol,用户数据报协议),是一个简单的面向数据报的传输层协议,进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。它在协议栈中的位置如下

  特点:UDP是一个面向数据报的协议,所以它不提供可靠性:它把应用程序传给IP层的数据发送出去,但并不保证它们能到达目的地

二、UDP首部

  由于不提供可靠性,所以UDP的首部比较简单

  各字段含义如下:

  ● 端口号:就是传输层识别应用程序的一个正整数

  ● 16位UDP长度:UDP长度指的是UDP首部和UDP数据的总长度。注意,UDP长度的最小值为8字节,也就是说可以发送一个没有数据的UDP数据报。记得在 TCP/IP协议-IP协议 中说到IP首部中有一个首部长度,那么用IP数据报的总长减去IP首部的长度就可以得到UDP数据报的长度了

  ● 16位UDP检验和:关于检验和,要特别留意几点。

  首先,UDP的检验和覆盖了UDP首部和UDP数据,而IP首部的检验和只覆盖了IP首部;其次,UDP的检验和是可选的,而TCP的检验和是必须的;UDP数据报的长度可以是奇数字节,所以在计算时要在末尾填充0,但是这些0可能不被传送;UDP检验和的计算方法与IP首部的检验和一样(16个bit的二进制反码求和)

  最后,UDP在计算检验和的时候包含了一个12字节长的伪首部,它仅仅是为了计算检验和而设置。UDP检验和计算过程中使用的各个字段如下

  如果检验和的计算结果为0,则存入的值全为1。如果传送的检验和为0,说明发送端没有计算检验和。这样,如果接收端计算的检验和不为全0,但是检验和字段为全0的话,说明传送过程中出错了,UDP数据报将会被丢弃,并且不产生任何差错报文

  虽然UDP检验和是可选的,但是它们应该总是在用,毕竟还是要确报数据传输的正确性

三、IP分片和重组

  为什么要在这里讨论IP分片呢?前面讲到UDP是不提供传输的可靠性的,但是至少要保证数据能完整的传输,所以只能把这个责任留给IP。下面先来了解几个概念

最大UDP数据报长度

  IP数据报的最大长度为65535个字节,去掉IP首部的20个字节和UDP首部的8个字节,UDP数据报的最大长度理论上应该为65507字节。但事实上,大多数实现都达不到这个长度,原因有下:

   ● 应用程序接口限制:socket API提供了一个可供应用程序调用的函数,用来设置接收和发送缓存的长度,大部分系统都默认提供了可读写大于8192字节的UDP数据报。

   ● 内核实现:可能存在一些实现特性(或差错),使IP数据报长度小于65535

  虽然IP可以发送那么长的数据报,但应用程序并不保证能够读取该长度的数据。因此,UDP编程接口允许应用程序设置能处理的最大长度。当数据报长度超出应用程序能处理的最大长度时,不同的API有着不同的处理策略,这就要求发送端控制数据报的大小

路径MTU

  MTU(最大传输单元),指的是数据链路层对传输的数据帧长度的一个上限值,不同的网络类型有着不同的值。而路径MTU指的是两台通信主机路径中最小的MTU。两台主机之间的路径MTU不一定是一个常数,因为路由选择并不一定是对称的,而且网络随时都在发生变化

  ICMP

  ICMP(Internet控制报文协议),是一个位于网络层的协议。它经常被认为是IP层的一个组成部分,因为ICMP的主要功能是传递差错报文及其他需要注意的信息,并且ICMP报文是封装在IP数据报内部的

  常见的几种差错报文:

  ● 端口不可达:如果接收端收到一份UDP数据报而目的端口与某个正在使用的进程不相符,那么UDP返回一个ICMP不可达报文

  ● 分片冲突不可达:当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片的标志位,那么路由器返回一个ICMP不可达报文。并且,此时可以把这条路径的路径MTU返回给源主机或路由器,这样就可以帮助这条路径上的其他路由器确定每个子路径上的MTU,这被称作路径MTU发现机制

  ● 源站抑制:当一个系统(路由器或主机)接收数据报的速度比其处理速度快时,它有可能会返回一个源站抑制差错报文。由于源站抑制需要消耗带宽,并且实际上没有什么作用,所以人们并不支持产生源站抑制报文

  IP分片

  前面已经讲过,数据链路层一般要限制每次发送数据帧的最大长度(MTU)。任何时候IP层接收到一份要发送的IP数据报时,它要判断向本地哪个接口发送数据(选路),并查询接口获得MTU,如果数据报长度大于MTU,那就需要进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

  在介绍IP首部字段的时候,谈到IP首部的“第二行”有三个字段:16位标识3位标志13位片偏移,它们就是被用在IP分片过程中。对于发送端发送的每份IP数据报来说,其标识字段都包含一个唯一值,在数据报分片时被复制到每个片中,表明它们是来自同一个数据报。标志字段用其中一个bit来表示“更多的片”,把该位置1表示这个还有其他分片,所以最后一片要把该位置0。片偏移字段指的是该片偏移原始数据报开始处的位置。另外,分片以后,每个片的总长度值要改为该片的长度值。标志字段中有一个bit称作“不分片”位,如果将这个置1,IP将不对数据报进行分片。如果此时导致数据报不能发送,那么将会返回一个ICMP不可达差错报文(分片冲突)

  分片之后,每一片都成为一个分组,这里的分组指的是网络层到数据链路层之间的传输单元,而IP数据报是指IP层端到端的传输单元。每个分组都有自己的IP首部

  需要注意是:

  ● 在分片时,除最后一个片外,其他每一个片中的数据部分(除IP首部外的其余部分)必须是8字节的整数倍(暂时没搞清楚为什么,个人猜测是为了方便计算片偏移,还有接收端的重组)

  ● 任何传输层首部只出现在第一片数据中

  ● 分片可能发生在源主机或者路径上的路由器,但重组只可能发生在目的主机上。因为路径上的路由器只负责转发,并不关心IP数据报的数据内容

  ● 即使只丢失了一片数据也需要重新传整个数据报,因为上一点,中间路由器可能再次分片,而目的端并不知道丢失的片是被如何分片的

    ● 各个片到达目的端时可能是乱序的,但是IP首部利用前面讲的三个字段,可以将分片正确地拼接起来

  下面来完整描述一个IP数据报的传输过程作为总结,假设待发送的传输层数据报需要进行分片,并且发送端和接收端不是直接相连:

   ①源主机的传输层将数据报发送到网络层;

  分片:

   ②IP发现数据报太大,需要分片,就将数据报分片:第一片包含了数据报的开头部分数据,数据大小为8字节的整数倍,包含了传输层首部,并将标志字段中表示“更多的片”字段置1,片偏移字段置0,然后把总长度值改为分片以后的片长度值;第二片到倒数第二片包含了某个长度的数据,并且数据大小为8字节的整数倍,但是它们都没有包含传输层首部,它们的“更多的片”字段置为1,片偏移字段根据片序号和前一片的数据长度设置,总长度设置同第一片;最后一片包含了剩余的数据部分,数据长度不一定是8字节的整数倍,没有包含传输层首部,“更多的片”字段被置0,片偏移字段根据前面的数据长度设置,总长度值也根据前面的片进行设置;所有片的标识字段都相同

   ③网络层把每一个片作为一个分组传送给数据链路层;

  传输:④~⑥

   ④数据链路层将分组转化为数据帧发送给下一个系统(路由器或者主机);

   ⑤接收到数据帧的路由器向上传送至网络层;

   ⑥IP检查数据报长度和MTU,如果需要分片,就跳到第②步;如果不需要分片,就跳到第④步,直到发送到目的主机;

  重组:

   ⑦目的主机陆续收到各个片,如果目的主机发现缺失了某个片,那么将会返回一个ICMP错误报文,源主机将会重新发送数据报,回到第①步;如果没有片缺失,目的主机将会根据标识字段、标志字段和片偏移将所有片重组为传输层数据报,传输层发送给应用程序,数据传输完成

  关于IP分片重组的实现,可以参考 Linux TCP/IP协议栈关于IP分片重组的实现

四、UDP服务器设计

  最后来讨论一下UDP那些影响使用该协议的服务器的设计和实现方面的协议特性

  客户IP地址及端口号

  UDP服务器必须保存来自客户数据报的源IP地址和源端口号,这个特性允许一个交互UDP服务器对多个客户进行处理

  目的IP地址

  某些应用程序需要知道数据报是发送给谁的,即目的IP地址

  UDP输入队列

  大多数UDP服务器是重复型服务器,单个服务器进程对单个UDP端口上的所有客户请求进行处理。所以必须维护一个输入队列来对差不多同时到达的请求进行处理

  限制本地IP地址

  大多数UDP服务器在创建UDP端点是都使其IP地址具有通配符的特点,这样可以从任何的本地接口来接收用户请求

  限制远端IP地址

  限制远端IP地址和端口号可以只接收特定地址的UDP数据报

  每个端口有多个接收者

  当UDP数据报到达目的IP地址为广播或多播地址,而且在目的IP地址和端口号处有多个端点时,就向每个端点传送一份数据报的复制。如果UDP数据报到达的是一个单播地址,那么只向其中一个端点传送一份数据报的复制

总结:UDP是一个简单的协议,本文大部分篇幅都在介绍IP分片的内容,等到介绍TCP的时候,就能了解UDP与TCP之间的区别和联系

TCP/IP-UDP的更多相关文章

  1. Socket,TCP/IP,UDP,HTTP,FTP

    1.Socket:套接字,是传输层协议的一种编程API 作用:用于描述IP地址和端口,区分来自不同应用程序的通信,实现数据传输的并发服务 JDK  Socket:在java.net包下有两个类Sock ...

  2. TCP/IP, UDP, ICMP, ARP协议族简介--纯图慎点

    ISO/OSI的网络模型架构 TCP/IP参考模型的层次结果 以太网头部结构 以太网属于数据链路层, 属于最基本的协议结构 IP协议 IP协议为TCP, UDP, ICMP提供最基本的数据传输通路 I ...

  3. SOCKET,TCP/IP,UDP,HTTP,FTP总结

    一.TCP/UDP,SOCKET,HTTP,FTP简析   TCP/IP是个协议组(主要解决数据如何在网络中传输),可分为三个层次:网络层.传输层和应用层: 网络层:IP协议.ICMP协议.ARP协议 ...

  4. TCP/IP/UDP 协议

    互连网早期的时候,主机间的互连使用的是NCP协议.这种协议本身有很多缺陷,如:不能互连不同的主机,不能互连不同的操作系统,没有纠错功能.为了改善这种缺点,大牛弄出了TCP/IP协议.现在几乎所有的操作 ...

  5. android 网络编程--socket tcp/ip udp http之间的关系

    网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层,一般编程人员接触最多的就是应用层和运输层,再往下的就是所谓的媒体层了,不是我们研究的对象. 下面是应用层.运输层,网络 ...

  6. HTTP/TCP/IP UDP Socket等区别联系

    1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...

  7. 常用传输层协议(tcp/ip+udp)与常用应用层协议简述(http)

    一.计算机网络体系结构 二.TCP与UDP差异 1.TCP是面向连接的可靠传输,UDP是面向无连接的不可靠传输 面向连接表现在3次握手,4次挥手:可靠传输表现在未进行4次挥手时的差错重传,超时重传: ...

  8. TCP/IP UDP 协议首部及数据进入协议栈封装的过程

    数据的封装 UDP 封装 TCP 封装 IP 封装 检验和算法 当应用程序用TCP传送数据时,数据被传送入协议栈中,然后逐一通过每一层直到被当作一串比特流送入网络 注: UDP数据TCP数据基本一致. ...

  9. TCP/IP||UDP广播和多播

    1.概述 广播和多播应用于UDP,TCP是一个面向连接协议,意味着分别运行与两个主机内的两进程间存在一个连接,在考虑多个主机内的共享通信网络,每个以太网帧包含源主机和目的主机以太网地址(48bit), ...

  10. TCP/IP --- UDP Broadcast Address

    Related information link : 百度百科---->广播地址 Use restrictions: 1. You can only broadcast on the same ...

随机推荐

  1. 阿里云ECS试用

    公司在推一个大项目,感觉阿里云挺好用的,自己搞了台小机器平时可以跑着玩,而且可以做个跳板机,平时学校里的收费网直接用跳板机就可以访问了,直接写个脚本在自己机器上跑一下: #!/usr/bin/expe ...

  2. Redis源码阅读笔记(1)——简单动态字符串sds实现原理

    首先,sds即simple dynamic string,redis实现这个的时候使用了一个技巧,并且C99将其收录为标准,即柔性数组成员(flexible array member),参考资料见这里 ...

  3. Java IO流以及装饰器模式在其上的运用

    流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输 ...

  4. poj1222

    貌似又是一个矩阵图形的问题,看起来应该是不太容易,不管了先做做吧! 题目大意: 题目:灯光延伸出去(延长熄灯)?? 在一个扩展的游戏版本 熄灯,它是一个难题(或者谜)在一个5行每一行有6个按钮(实际是 ...

  5. HashMap,TreeMap,LinkedHashMap学习

    Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复.Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快 ...

  6. Unity3D NGUI制作进度条

    利用GUI可以制作进度条,但是NGUI更加方便 我是用的NGUI3.5.3, 先找到NGUI  Slider的预制体,利用自带的UISlider来制作. 主要是利用UISlider的Value来控制进 ...

  7. quartz 定时任务的实现

    需求:项目中有一个任务,当时间到了会向移动端通过百度云推送推送信息,之前很傻叉的是写一个多线程一直扫描,每分钟扫描一次,比对当前时间和任务时间是否一样,结果把 项目跑死了,项目中用了一个简单的quar ...

  8. makeKeyAndVisible的作用

    [self.window makeKeyAndVisible]; 这个是便捷方法,去使被使用对象的主窗口显示到屏幕的最前端.你也可以使用hiddenUIView方法隐藏这个窗口

  9. DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  10. Android URI简单介绍

    就Android平台而言,URI主要分三个部分:scheme, authority and path.当中authority又分为host和port.格式例如以下: scheme://host:por ...