RSS
热门关键字:
当前位置 : 主页>网络方案>入门资料>列表

UDP服务器的设计

来源:我要研发网 作者:我要开发网.搜集 时间:2008-06-01 点击:




使用UDP的一些蕴含对于设计和实现服务器会产生影响。通常,客户端的设计和实现比服务器端的要容易一些,这就是我们为什么要讨论服务器的设计,而不是讨论客户端的设计的原因。典型的服务器与操作系统进行交互作用,而且大多数需要同时处理多个客户。
通常一个客户启动后直接与单个服务器通信,然后就结束了。而对于服务器来说,它启动后处于休眠状态,等待客户请求的到来。对于UDP来说,当客户数据报到达时,服务器苏醒过来,数据报中可能包含来自客户的某种形式的请求消息。
在这里我们所感兴趣的并不是客户和服务器的编程方面([Stevens 1990]对这些方面的细节进行了讨论),而是UDP那些影响使用该协议的服务器的设计和实现方面的协议特性(我们在18.11节中对TCP服务器的设计进行了描述)。尽管我们所描述的一些特性取决于所使用UDP的实现,但对于大多数实现来说,这些特性是公共的。
11.12.1 客户IP地址及端口号
来自客户的是UDP数据报。IP首部包含源端和目的端IP地址, UDP首部包含了源端和目的端的UDP端口号。当一个应用程序接收到UDP数据报时,操作系统必须告诉它是谁发送了这份消息,即源IP地址和端口号。
这个特性允许一个交互UDP服务器对多个客户进行处理。给每个发送请求的客户发回应答。

字串5


11.12.2 目的IP地址
一些应用程序需要知道数据报是发送给谁的,即目的IP地址。例如, Host Requirements RFC规定,TFTP服务器必须忽略接收到的发往广播地址的数据报(我们分别在第12章和第15章对广播和TFTP进行描述)。
这要求操作系统从接收到的UDP数据报中将目的IP地址交给应用程序。不幸的是,并非所有的实现都提供这个功能。
socket API以IP_RECVDSTADDR socket选项提供了这个功能。对于本文中使用的系统,只有BSD/386、4.4BSD和AIX3.2.2支持该选项。SVR4、SunOS 4.x和Solaris 2.x 都不支持该选项。
11.12.3 UDP输入队列
我们在1.8节中说过,大多数UDP服务器是交互服务器。这意味着,单个服务器进程对单个UDP端口上(服务器上的名知端口)的所有客户请求进行处理。
通常程序所使用的每个UDP端口都与一个有限大小的输入队列相联系。这意味着,来自不同客户的差不多同时到达的请求将由UDP自动排队。接收到的UDP数据报以其接收顺序交给应用程序(在应用程序要求交送下一个数据报时)。
然而,排队溢出造成内核中的UDP模块丢弃数据报的可能性是存在的。可以进行以下试验。我们在作为UDP服务器的bsdi主机上运行sock程序:
bsdi % sock -s -u -v -E -R256 -P30 6666

字串2


from 140.252.13.33, to 140.252.13.63: 1111111111 从sun发送到广播地址
from 140.252.13.34, to 140.252.13.35: 4444444444444 从s v r 4发送到单播地址
我们指明以下标志: - s表示作为服务器运行, - u表示UDP,- v表示打印客户的IP地址,- E表示打印目的IP地址(该系统支持这个功能)。另外,我们将这个端口的UDP接收缓存设置为256字节(- R),其每次应用程序读取的大小也是这个数( - r)。标志- P30表示创建UDP端口后,先暂停30秒后再读取第一个数据报。这样,我们就有时间在另两台主机上启动客户程序,发送一些数据报,以查看接收队列是如何工作的。
服务器一开始工作,处于其3 0秒的暂停时间内,我们就在sun主机上启动一个客户,并发送三个数据报:
sun % sock -u -v 140.252.13.63 6666 到以太网广播地址
connected on 140.252.13.33.1252 to 140.252.13.63.6666
1 1 1 1 1 1 1 1 1 1 1 1字节的数据(新行)
2 2 2 2 2 2 2 2 2 1 0字节的数据(新行)
3 3 3 3 3 3 3 3 3 3 3 1 2字节的数据(新行)
目的地址是广播地址(140.252.13.63)。我们同时也在主机svr4上启动第2个客户,并发送另外三个数据报: 字串1
svr4 % sock -u -v bsdi 6666
connected on 0.0.0.0.1042 to 140.252.13.35.6666
444444444444414字节的数据(新行)
55555555555555516字节的数据(新行)
666666669字节的数据(新行)
首先,我们早些时候在bsdi上所看到的结果表明,应用程序只接收到2个数据报:来自sun的第一个全1报文,和来自svr4的第一个全4报文。其他4个数据报看来全被丢弃。
图11-20给出的tcpdump输出结果表明,所有6个数据报都发送给了目的主机。两个客户的数据报以交替顺序键入:第一个来自sun,然后是来自svr4的,以此类推。同时也可以看出,全部6个数据报大约在1 2秒内发送完毕,也就是在服务器休眠的30秒内完成的。
UDP服务器的设计(图一)
我们还可以看到,服务器的- E选项使其可以知道每个数据报的目的IP地址。如果需要,它可以选择如何处理其接收到的第一个数据报,这个数据报的地址是广播地址。
我们可以从本例中看到以下几个要点。首先,应用程序并不知道其输入队列何时溢出。只是由UDP对超出数据报进行丢弃处理。同时,从tcpdump输出结果,我们看到,没有发回任何信息告诉客户其数据报被丢弃。这里不存在像ICMP源站抑制这样发回发送端的消息。最后,看来UDP输出队列是FIFO(先进先出)的,而我们在11.9节中所看到的ARP输入却是LIFO(后进先出)的。
字串7

11.12.4 限制本地IP地址
大多数UDP服务器在创建UDP端点时都使其本地IP地址具有通配符( wildcard )的特点。这就表明进入的UDP数据报如果其目的地为服务器端口,那么在任何本地接口均可接收到它。例如,我们以端口号777启动一个UDP服务器:
sun % sock -u -s 7777
然后,用n e t s t a t命令观察端点的状态:
sun % netstat -a -n -f inet
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
udp 0 0 *.7777 *.*
这里,我们删除了许多行,只保留了其中感兴趣的东西。- a选项表示报告所有网络端点的状态。- n选项表示以点数格式打印IP地址而不用DNS把地址转换成名字,打印数字端口号而不是服务名称。-f inet选项表示只报告TCP和UDP端点。
最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册