2.2.1 UDP协议基础(2)
校验和的计算算法与IP相同,不过UDP在计算校验和时会增加一个伪首部,伪首部只在计算校验和时使用,不会封装到IP分组中。校验内容包括伪首部(Pseudo Header)+首部+数据部分。UDP伪首部报文格式的结构如图2-8所示。
|
| (点击查看大图)图2-8 UDP伪首部报文格式 |
注意:伪首部使得IP层和UDP层的界线变得模糊。
UDP报文结构如图2-9所示。
|
| 图2-9 UDP报文结构 |
当今有很多应用程序是基于UDP传输的,包括网络文件系统NFS、简单网络管理协议SNMP、域名系统DNS以及简单文件传输系统TFTP、动态主机配置协议DHCP和路由信息协议RIP等,另外用于在线欣赏视频或音频内容的流媒体软件往往也采用了UDP传输。因为UDP虽然不保证传输可靠性,但是网络传输代价小,实时性好。流媒体传输的完整性并不是最重要的,即使少量数据丢失,可能也仅仅影响欣赏视频和音乐的某个瞬间,因此适合采用UDP传输。
4. UDP数据传输
UDP协议不面向连接,也不保证传输的可靠性,传输过程的具体说明如下。
(1) 发送端的UDP协议层只管把应用层传来的数据封装成段,交给IP协议层就算完成任务了,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息。
(2) 接收端的UDP协议层只管把收到的数据根据端口号交给相应的应用程序就算完成任务了,如果发送端发来多个数据包并且在网络上经过不同的路由,到达接收端时顺序已经错乱了,UDP协议层也不保证按发送时的顺序交给应用层。
(3) 通常接收端的UDP协议层将收到的数据放在一个固定大小的缓冲区中等待应用程序来提取和处理,如果应用程序提取和处理的速度很慢,而发送端发送的速度很快,就会丢失数据包,UDP协议层并不报告这种错误。
由此可见,在使用UDP协议的应用程序时,必须考虑到这些可能的问题并实现适当的解决方案,例如等待应答、超时重发、为数据包编号、流量控制等。一般使用UDP协议的应用程序实现都比较简单,只是发送一些对可靠性要求不高的消息,而不发送大量的数据。例如,基于UDP的TFTP协议一般只用于传送小文件(所以才叫 trivial的ftp),而基于TCP的FTP协议适用于各种文件的传输。
5. UDP编程(www.cppentry.com)步骤
编写UDP Server程序的具体步骤如下。
(1) 使用socket()来建立一个UDP Socket,第二个参数为SOCK_DGRAM。
(2) 初始化sockaddr_in结构的变量,并赋值。sockaddr_in结构定义格式如下:
- struct sockaddr_in {
- uint8_t sin_len;
- sa_family_t sin_family;
- in_port_t sin_port;
- struct in_addr sin_addr;
- char sin_zero[8];
- };
(3) 使用bind()把上面的Socket和定义的IP地址和端口绑定。这里检查bind()是否执行成功,如果有错误就退出。这样可以防止服务程序重复运行的问题。
(4) 进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。这里是直接把收到的数据发回给客户程序。