一、进程到进程的通信 在学习UDP协议之前,首先应该了解主机到主机的通信和进程到进程的通信,以及这两种通信之间的区别。

IP协议负责主机到主机的通信。作为一个网络层协议,IP协议只能把报文交付给目的主机。这是一种不完整的交付,因为这个报文还没有送交到正确的进程。像UDP这样的传输层协议负责进程到进程的通信。UDP协议负责把报文交付到正确的进程。下图描绘了IP协议和UDP协议的作用范围。

使用udp协议传输数据的有哪些(电脑网络基础知识)(1)

图6-1 UDP与IP的区别

1.端口号

在网络中,主机是用IP地址来标识的。而要标识主机中的进程,就需要第二个标识符,这就是端口号。在TCP/IP协议族中,端口号是在0~65535之间的整数。

在客户/服务器模型中,客户程序使用端口号标识自己,这种端口号叫做短暂端口号,短暂的意思是生存时间比较短。一般把短暂端口取为大于1023的数,这样可以保证客户程序工作得比较正常。 服务器进程也必须用一个端口号标识自己。但是这个端口号不能随机选取。如果服务器随机选取端口号,那么客户端在想连接到这个服务器并使用其服务的时候就会因为不知道这个端口号而无法连接。TCP/IP协议族采用熟知端口号的办法解决这个问题。每一个客户进程都必须知道相应的服务器进程熟知端口号。 UDP的熟知端口号如下表所示:

表6-1 UDP的熟知端口号

使用udp协议传输数据的有哪些(电脑网络基础知识)(2)

在一个IP数据包中,目的IP地址和端口号起着不同的寻址作用。目的IP地址定义了在世界范围内惟一的一台主机。当主机被选定后,端口号定义了在这台主机上运行的多个进程中的一个。

2.套接字地址

一个IP地址与一个端口号结合起来就叫做一个套接字地址。客户套接字地址惟一地定义了客户进程,而服务器套接字地址惟一地定义了服务器进程。 要使用UDP的服务,就需要一对套接字地址:客户套接字地址和服务器套接字地址。客户套接字地址指定了客户端的IP地址和客户进程,服务器套接字地址指定了服务器的IP地址和服务器进程。二、面向连接的服务与面向无连接的服务

从通信的角度来看,在OSI参考模型中,下层能向上层提供两种不同形式的服务:面向连接的服务和面向无连接的服务。1.面向连接的服务

所谓连接,就是两个对等实体为进行数据通信而进行的一种结合。面向连接服务在进行数据交换前,先建立连接。当数据传输结束后,应释放这个连接。因此,采用面向连接的服务进行数据传送要经历三个阶段: (1)建立连接阶段:在有关的服务原语以及协议数据单元中,必须给出源用户和目的用户的完整地址。同时可以协商服务质量和其它一些选项。 (2)数据交换阶段:在这个阶段,每个报文中不必包含完整的源用户和目的用户的完整地址,而是使用一个连接标识符来代替。由于连接标识符相对于地址信息要短得多,因此使控制信息在报文中所占的比重相对减小,从而可减小系统的额外开销,提高信道的有效利用率。另外,报文的发送和接收都是按固定顺序的,即发送方先发送的报文,在接受方先收到。 (3)释放连接阶段:通过相应的服务原语完成释放操作。 从面向连接服务的三个阶段来看,连接就像一个管道,发送端在其一端依次发送报文,接收者依次在其另一端按同样的顺序接收报文。这种连接又称虚拟电路。它可以避免报文的丢失、重复和乱序。 若两个用户经常需要通信,则可以建立永久虚电路。这样可以免除每次通信时建立连接和释放连接这两个阶段。这点与电话网中的专线很相似。2.面向无连接的服务

在面向无连接服务的情况下,两个实体之间的通信不必事先建立一个连接。相对于面向连接的服务,面向无连接服务灵活方便且快速。但它不能防止报文的丢失、重复和乱序。由于它的每个报文必须包括完整的源地址的目的地址,因此开销较大。 面向无连接服务主要有三种类型: (1)数据报:它的特点是发完报文就结束,而对方不做任何响应。数据报的服务简单,额外开销少,但可靠性差,它比较适合于数据具有很大的冗余度以及要求有较高的实时性的通信场合。 (2)证实交付:又称可靠的数据报。这种服务对每一个报文产生一个证实给发送方,不过这种证实不是来自对应方用户,而是来自提供服务的层。这种证实只能保证报文已经发给目的站了,而不能保证对应方用户正确地接收到报文。 (3)请求回答:这种类型服务是接收端用户每收到一个报文,即向发送端用户发送一个应答报文。但是双方发送的报文都有可能丢失。如果接收端发现报文有错误,则回送一个表示有错误的报文。

三、DP协议简介

UDP(用户数据报协议),主要用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似的协议所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和可行的网络传输层协议。 UDP协议直接位于IP协议的上层。根据OSI参考模型,UDP和TCP都属于传输层协议。UDP协议不提供端到端的确认和重传功能,它不保证数据包一定能到达目的地,因此是不可靠协议。 UDP协议有以下特点:

● UDP是面向事务的协议,它用最少的传输量为应用程序向其它程序发送报文提供了一个途径。

● UDP是无连接的、不可靠的传输机制。在发送数据报前,UDP在发送和接收两者之间不建立连接。

● UDP让应用程序能直接访问网络层的数据报服务,例如分段和重组等网络层所提供的数据报服务。

● UDP使用IP协议作为数据传输机制的底层协议。

● UDP报头和数据都以与最初传输时相同的形式被传送到最终目的地。

● UDP不提供确认,也不对数据的到达顺序加以控制。因此UDP报文可能会丢失。

● 不实现数据包的传送和重复检测。 ● 当数据包在传送过程中发生错误时,UDP不能报告错误。

● 吞吐量不受拥塞控制算法的调节,只受应用程序生成数据的速率、传输带宽、发送端和接收端主机性能的限制。

四、UDP报文格式 下图显示了UDP报文格式。每个UDP报文称为一个用户数据报(User Datagram),用户数据报分为两个部分:UDP首部和UDP数据。首部被分为四个16位的字段,分别代表源端口号﹑目的端口号﹑报文的长度以及UDP校验和。

使用udp协议传输数据的有哪些(电脑网络基础知识)(3)

图6-2 UDP报文格式

● 源端口:该字段表示发送端的端口号。如果源端口没有使用,那么此字段的值就被指定为0。这是一个可选的字段。不同的应用程序使用不同的端口号,UDP协议使用端口号为不同的应用程序保留其各自的数据传输通道,从而实现了同一时间段内多个应用程序可以一起使用网络进行数据的发送和接收。 ● 目的端口:该字段表示数据包被发往的目的端的端口号。 ● 有效负载长度:该字段表示包括UDP首部和UDP数据在内的整个用户数据报的长度。该字段的最小值是8。数据报的最大尺寸随操作系统的不同而不同。在两字节字段中,理论上数据报最多可达65535字节。然而,一些UDP实现将数据报的大小限制到了8192字节。 ● 校验和:UDP的校验的校验范围包括伪首部(IP首部一部分字段)、UDP首部和UDP数据,该字段是可选的。如果该字段值为零就说明不进行校验。五、UDP封装 当进程有报文要通过UDP发送时,它就把这个报文连同一对套接字地址以及数据的长度传递给UDP。UDP收到数据后就加上UDP首部。然后UDP就把这用户数据报连同套接字地址一起传递给IP。IP加上自己的首部,在高层协议类型字段使用值17,指出该数据是从UDP协议来的。这个IP数据报再传递给数据链路层。数据链路层接收到IP数据报后,加上自己的首部(可能还有尾部),再传给物理层。物理层把这些位编码为电信号或光信号,把它发送到远程的主机。如下图所示:

使用udp协议传输数据的有哪些(电脑网络基础知识)(4)

图6-3 UDP封装

六、UDP校验和

UDP校验和的计算与IP和ICMP校验和的计算不同。UDP校验和校验的范围包括三部分:伪首部、UDP首部以及从应用层来的数据。 伪首部是IP首部的一部分,其中有些字段要填入0。用户数据报封装在IP数据包中。如下图所示:

使用udp协议传输数据的有哪些(电脑网络基础知识)(5)

图6-4 伪首部添加在UDP数据报上

若校验和不包括伪首部,用户数据报也可能是安全的和正确的。但是,若IP首部受到损伤,则它可能被交付到错误的主机。 伪首部中包含高层协议类型字段是为了确保这个数据包是属于UDP而不是属于TCP(参见实验七)的。使用UDP的进程和使用TCP的进程可以使用同一个端口号。UDP的高层协议类型字段是17。若在传输过程中这个值改变了,在接收端计算校验和时就可检测出来,UDP就可丢弃这个数据包。这样就不会交付给错误的协议。1.在发送端的校验和计算 在发送端按以下步骤计算校验和: (1)把伪首部填加到UDP用户数据报上。 (2)把校验和字段填入零。 (3)按16位长度将数据报分段。

(4)若分段总数不是偶数,则增加一个分段的填充(全0)。填充只是为了计算校验和,计算完毕后就把它丢弃。

(5)把所有16位的分段使用反码算术运算相加。

(6)把得到的结果取反码,它是一个16位的数,把这个数插入到校验和字段。 (7)把伪首部和填充丢掉。 (8)把UDP用户数据报交付给IP进行封装。 在伪首部中的各行的顺序对校验和的计算没有任何影响。此外,增加0也不影响计算的结果。 下图给出了一个计算UDP校验和的例子。这里假定用户数据报的长度是15字节,因此要添加一个全0的字节。

使用udp协议传输数据的有哪些(电脑网络基础知识)(6)

图6-5 UDP校验和的计算过程

2、在接收端的校验和计算 接收端按以下6个步骤计算校验和是否正确: (1)把伪首部加到UDP用户数据报上。 (2)若需要,就增加填充。 (3)把数据报按16位长度分段。 (4)把所有16位的分段使用反码算术运算相加。 (5)把得到的结果取反码。

(6)若得到的结果是全零,则丢弃首部和填充,并接受这个用户数据报。若结果是非零,就丢弃这个用户数据报。

校验和是可选使用的,若不计算校验和,则校验和字段就填入0。七、UDP应用 下面列出了UDP协议的一些用途:

● UDP适用于这样的进程,它需要简单的请求——响应通信,而较少考虑流量控制和差错控制。对于需要传送成块数据的进程,如FTP,则通常不使用UDP;

● UDP适用于具有内部流量控制和差错控制机制的进程; ● 对多播和广播来说,UDP是个比较合适的传输层协议; ● UDP可用于管理进程,如SNMP协议; ● UDP可用于某些路由选择更新协议,如路由信息协议(RIP协议,参考实验17)。

八、协议栈实现代码解析 本实验将通过对安装目录ExpCNS\work\EXPcns_studentnet\netproto_udp_student\netproto_udp_student下的proto_udp_student.h、netproto_udp_shudent.c和安装目录ExpCNS\work\EXPcns_studentnet\netproto_udp_student\netproto_udpif_student下的netproto_udpif_student.h、netproto_udpif_student.c四个文件进行编码,完成协议栈中UDP协议的实现。 netproto_udp_student.h和netproto_udp_shudent.c文件用于实现UDP数据包发送和接收。其中,netproto_udp_student.h文件中定义了UDP协议实现相关数值以及UDP的负载内容、负载长度,关键代码如下所示:

使用udp协议传输数据的有哪些(电脑网络基础知识)(7)

这段代码定义了5个宏,他们代表的含义如下表所示:

表6-2 netproto_udp_student.h中定义的宏

使用udp协议传输数据的有哪些(电脑网络基础知识)(8)

在实验的编码过程中,应该使用这些宏对相应的变量进行赋值。 netproto_udp_shudent.c文件是协议栈中UDP数据包发送和接收的实现部分,其中定义了2个函数。下面介绍这些协议栈的实现部分。 函数netp_udp_output_student的功能是构造并发送一个UDP数据包,其高层协议为自定义协议类型,负载内容为自定义负载。这个函数的编码工作需要由学生完成。 当有数据到达本机网络接口时,函数netp_udp_input_student将被调用,并传递给这个函数原始数据。在该函数中,需要判断一些条件值来确定接收到的数据包为自定义UDP数据,如果是自定义UDP数据包,则输出负载内容,如果不是,则返回NETP_PUSH_TO_LWIP交给协议栈继续处理。 netproto_udpif_student.h和netproto_udpif_shudent.c文件用于实现UDP上层投递的功能,即为高层使用UDP协议提供了接口。其中,netproto_udpif_student.h文件中并没有定义太多内容。netproto_udpif_shudent.c文件是协议栈中UDP上层投递的功能的实现部分,其中定义了一个全局变量recv_port和2个函数。 全局变量recv_port的作用很简单,它记录了发送UDP数据报时的源端口号作为接收UDP数据报的过滤条件。 函数netp_send_udp通过IP层接口发送UDP数据报,该函数功能需要学生完成。 函数netp_udp_input_student处理输入数据包,如果输入的数据报满足过滤条件,则投递给上层协议使用。该函数功能需要学生完成。 在编码过程中可能会设计到一些结构体、宏和函数,下表是对他们进行和介绍:

表6-3 实验涉及的结构体、宏和函数

使用udp协议传输数据的有哪些(电脑网络基础知识)(9)

九、各模块推荐流程1.UDP数据包发送流程 编码实现UDP数据包发送推荐使用如下流程:

使用udp协议传输数据的有哪些(电脑网络基础知识)(10)

图6-6 UDP数据包发送推荐流程

2.输入UDP数据包处理流程 编码实现处理UDP输入数据包推荐使用如下流程:

使用udp协议传输数据的有哪些(电脑网络基础知识)(11)

图6-7 处理UDP输入数据包推荐流程

3.UDP发送接口实现流程 编码实现UDP发送接口推荐使用如下流程:

使用udp协议传输数据的有哪些(电脑网络基础知识)(12)

图6-8 UDP发送接口实现推荐流程

4.UDP接收接口实现流程 编码实现UDP接收接口推荐使用如下流程:

使用udp协议传输数据的有哪些(电脑网络基础知识)(13)

图6-9 UDP接收接口实现推荐流程

【实验步骤】

练习1 编辑并发送UDP数据报

各主机打开工具区的"拓扑验证工具",选择相应的网络结构,配置网卡后,进行拓扑验证,如果通过拓扑验证,关闭工具继续进行实验,如果没有通过,请检查网络连接。 本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。现仅以主机A、B所在组为例,其它组的操作参考主机A、B所在组的操作。1.主机A打开协议编辑器,编辑发送给主机B的UDP数据报。 MAC层: 目的MAC地址:接收方MAC地址 源MAC地址:发送方MAC地址 协议类型或数据长度:0800,即IP协议 IP层: 总长度:包括IP层、UDP层和数据长度 高层协议类型:17,即UDP协议 首部校验和:其它所有字段填充完毕后填充此字段 源IP地址:发送方IP地址

【思考问题】

1.为什么UDP协议的"校验和"要包含伪首部?2.比较UDP和IP的不可靠程度?

练习2 UDP单播通信

本练习将主机A、B、C、D、E、F作为一组进行实验。1.主机B、C、D、E、F上启动实验平台工具栏中的"UDP工具",作为服务器端,监听端口设置为2483,"创建"成功。2.主机C、E上启动协议分析器开始捕获数据,并设置过滤条件(提取UDP协议)。3.主机A上启动实验平台工具栏中的"UDP工具",作为客户端,以主机C的IP为目的IP地址,以2483为端口,填写数据并发送。4.察看主机B、C、D、E、F上的"UDP工具"接收的信息。 ● 哪台主机上的"UDP工具"能够接收到主机A发送的UDP报文?5.察看主机C协议分析器上的UDP报文,并回答以下问题: ● UDP是基于连接的协议吗?阐述此特性的优缺点。 ● UDP报文交互中含有确认报文吗?阐述此特性的优缺点。6.主机A上使用协议编辑器向主机E发送UDP报文,其中: 目的MAC地址:E的MAC地址 目的IP地址:主机E的IP地址 目的端口:2483

【思考问题】

1. 思考UDP的差错处理能力。

练习3 UDP广播通信

本练习将主机A、B、C、D、E、F作为一组进行实验。1.主机B、C、D、E、F上启动UDP工具,作为服务器端,监听端口设为2483。2.主机B、C、D、E、F启动协议分析器捕获数据,并设置过滤条件(提取UDP协议)。3.主机A上启动UDP工具,作为客户端,以255.255.255.255为目的地址,以2483为端口,填写数据并发送。4.察看主机B、C、D、E、F上的"UDP工具"接收的信息。 ● 哪台主机能够接收到主机A发送的UDP报文?5.察看协议分析器上捕获的UDP报文,并回答以下问题: ●主机A发送的报文的目的MAC地址和目的IP地址的含义是什么?

【思考问题】

1.如果将目的MAC地址换成某一个主机的MAC地址,是否所有主机还会收到这种报文?

2.如果将目的MAC地址设成广播地址,目的IP设成某一主机的IP地址,结果怎样?

3.在可靠性不是最重要的情况下,UDP可能是一个好的传输协议。试给出这种特定情况的一些示例。

4.UDP协议本身是否能确保数据报的发送和接收顺序?

练习4 UDP数据报发送与接收

本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。现仅以主机A、B所在组为例,其它组的操作参考主机A、B所在组的操作。实验开始前,先单击"初始环境"。 在实验中,主机A将新接口的IP地址设置为172.16.1.11、主机B使用处于连接状态的物理接口,将新接口的IP设置为172.16.1.12、主机C将新接口的IP地址设置为172.16.1.13、主机D使用处于连接状态的物理接口,将新接口的IP地址设置为172.16.1.14、主机E使用处于连接状态的物理接口,将新接口的IP地址设置为172.16.1.15、主机F将新接口的IP地址设置为172.16.1.16。所有主机使用子网掩码255.255.255.0,默认网关设置为0.0.0.0。1.设置目的IP地址 各主机打开安装目录ExpCNS\work\EXPcns_student\netproto_udp_student\netproto_udp_student下的netproto_udp_student.h文件,将IP_DEST_ADDR宏所定义的IP地址修改为同组同学的新接口IP地址。2.编码实现发送UDP数据包 (1)各主机打开安装目录ExpCNS\work\EXPcns_student\netproto_udp_student\netproto_udp_student下的netproto_udp_student.c文件,在函数netp_udp_output_student内编写实现代码。 (2)参考实验原理UDP数据包发送推荐流程图给出的流程,分析已经存在的代码。 已经存在的代码创建了UDP头结构、UDP伪首部结构、源IP地址、目的IP地址、发送缓冲区和校验和缓冲区等变量,UDP校验和的计算过程,将UDP头和负载拷贝到发送缓冲区中以及将缓冲区数据发送到网络中的实现。 (3)构造UDP头,校验和字段为0 构造并填充一个UDP数据包头。可以使用netproto_udp_student.h文件中所定义的端口值。总长度为UDP_HEADER_LEN PAYLOAD_LEN。 (4)构造UDP伪首部 各主机构造并填充UDP伪首部。其中,源IP地址为本接口IP地址,目的IP地址为IP_DEST_ADDR所指定的IP地址,长度与UDP头中的总长度数值相同。3.所有主机编码实现UDP数据包输入处理功能 (1)各主机打开安装目录ExpCNS\work\EXPcns_student\netproto_udp_student\netproto_udp_student下的netproto_udp_student.c文件,在函数netp_udp_input_student内编写实现代码。 (2)参考实验原理处理UDP输入数据包推荐流程图给出的流程,分析已经存在的代码。 已经存在的代码定义了以太网帧头、IP包头、UDP报头、UDP伪报头、校验和、负载缓冲区指针和校验和缓冲区指针,以太网高层协议的校验,目的IP地址的校验,申请负载缓冲区,打印负载内容等实现。 (3)提取UDP数据包 各主机通过以IP头结构ip_header中的protocol即"高层协议类型"字段值判断该数据帧的高层协议是否为UDP协议,可以使用宏IP_PROTO_UDP。如果不是UDP数据包则返回NETP_PUSH_TO_LWIP交给协议栈继续执行。 (4)提取UDP目的端口号为UDP_SOUR_PORT的数据报 各主机通过UDP头结构udp_header中的dest_port即"目的端口号"字段值判断该UDP数据报是否是我们感兴趣的UDP数据报。如果不是则返回NETP_PUSH_TO_LWIP交给协议栈继续执行。 (5)判断UDP校验和是否正确 如果UDP头的校验和字段值不为0,则需要验证校验和是否正确。各主机通过IP包头和UDP报头中的数值验证UDP校验和是否正确,如果不正确则丢弃该数据报。4.所有主机打开协议分析器,开始捕获数据5.所有主机调试并运行程序6.各主机停止数据捕获,观察实验现象 ● 你收到的负载内容是什么?7.参考代码如下:

使用udp协议传输数据的有哪些(电脑网络基础知识)(14)

练习5 UDP报文的上层投递的设计与实现

本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。现仅以主机A、B所在组为例,其它组的操作参考主机A、B所在组的操作。实验开始前,先单击"初始环境"。 在实验中,主机A将新接口的IP地址设置为172.16.1.11、主机B使用处于连接状态的物理接口,将新接口的IP设置为172.16.1.12、主机C将新接口的IP地址设置为172.16.1.13、主机D使用处于连接状态的物理接口,将新接口的IP地址设置为172.16.1.14、主机E使用处于连接状态的物理接口,将新接口的IP地址设置为172.16.1.15、主机F将新接口的IP地址设置为172.16.1.16。所有主机使用子网掩码255.255.255.0,默认网关设置为0.0.0.0。1.编码实现发送UDP数据报接口 (1)各主机打开安装目录ExpCNS\work\EXPcns_student\netproto_udp_student\netproto_udpif_student下的netproto_udpif_student.c文件,在函数netp_send_udp内编写实现代码。 (2)参考实验原理UDP发送接口实现推荐流程图给出的流程,分析已经存在的代码。 已经存在的代码创建了UDP头结构、UDP伪首部结构、源IP地址、负载缓冲区指针和校验和缓冲区指针等变量,申请负载缓冲区、校验和缓冲区,UDP校验和的计算过程,将UDP头和负载拷贝到发送缓冲区中以及利用IP接口将缓冲区数据发送到网络中的实现。 (3)构造UDP头,校验和字段为0 构造并填充一个UDP数据包头。可以使用安装目录ExpCNS\work\EXPcns_student\netproto_udp_student\netproto_udp_student下的netproto_udp_student.h文件中所定义的端口值。总长度为UDP_HEADER_LEN buff_len。 (4)构造UDP伪首部 各主机构造并填充UDP伪首部。其中,源IP地址为本接口IP地址,目的IP地址为用户所指定的目的IP地址,长度与UDP头中的总长度数值相同。2.编码实现接收UDP数据报接口 (1)各主机打开netproto_ udpif _student.c文件,在函数netp_udp_input_student内编写实现代码。 (2)参考实验原理UDP接收接口实现推荐流程图给出的流程,分析已经存在的代码。 已经存在的代码定义了以太网帧头、IP包头、UDP报头、UDP伪报头、校验和、负载缓冲区指针和校验和缓冲区指针,以太网高层协议的校验,目的IP地址的校验,申请负载缓冲区,将负载内容投递到上层协议、释放负载缓冲区等实现。 (3)提取UDP数据包 各主机通过以IP头结构ip_header中的protocol即"高层协议类型"字段值判断该数据帧的高层协议是否为UDP协议,可以使用宏IP_PROTO_UDP。如果不是UDP数据包则返回NETP_PUSH_TO_LWIP交给协议栈继续执行。 (4)提取UDP目的端口号为recv_port的数据报 各主机通过UDP头结构udp_header中的dest_port即"目的端口号"字段值判断该UDP数据报是否是我们感兴趣的UDP数据报。如果不是则返回NETP_PUSH_TO_LWIP交给协议栈继续执行。 (5)判断UDP校验和是否正确 如果UDP头的校验和字段值不为0,则需要验证校验和是否正确。各主机通过IP包头和UDP报头中的数值验证UDP校验和是否正确,如果不正确则丢弃该数据报。3.所有主机打开协议分析器,开始捕获数据4.所有主机调试并运行程序5.各主机停止数据捕获,观察实验现象 ● 你收到的负载内容是什么?6.参考代码如下:

使用udp协议传输数据的有哪些(电脑网络基础知识)(15)

,