一、UDP报文丢失数据
利用UDP协议进行数据收发的时候,在局域网内一般情况下数据的接收均能接收到发送方的数据,除非连接双方的主机发生故障,否则不会发生接收不到数据的情况。
1.UDP报文的正常发送过程
在Internet上,由于要经过多个路由器,正常情况下一个数据报文从主机C经过路由器A、路由器B、路由器C到达主机S。
2.UPD报文的丢失
路由器要对转发的数据进行存储、处理、合法性判定、转发等操作,容易出现错误,所以很可能在路由器转发的过程中出现数据丢失的现象。对于数据丢失的原因,并不能通过一种简单的方法获得,例如,不能区分服务器发给客户端的响应数据是在发送的路径中被路由器丢弃,还是服务器没有发送此响应数据。
3.UDP报文丢失的对策
UDP协议中的数据报文丢失是先天性的,因为UDP是无连接的、不能保证发送数据的正确到达。对策:主机C发送的数据经过路由器,到达主机S后,主机S要发送一个接收到此数据报文的响应,主机C要对主机S的响应进行记录,直到之前发送的数据报文1已经被主机S接收到。如果数据报文在经过路由的时候,被路由器丢弃,则主机C和主机S会对超时的数据进行重发。
二、UDP数据发送中的乱序
UDP协议数据收发过程中,会出现数据的乱序现象。所谓乱发送数据的顺序和接收数据的顺序不一致。
1、UDP数据顺序收发的过程
主机C向主机S发送数据包0、数据包1、数据包2、数据包3,各个数据包途中经过路由器A、路由器B、路由器C,先后到达主机S,在主机S端的循序仍然为数据包0、数据包1、数据包2、数据包3,即发送数据时的顺序和接收数据时的顺序是一致的。
2、UDP数据的乱序
UDP的数据包在网络上传输的时候,有可能造成数据的顺序更改,接收方的数据顺序和发送方的数据顺序发生了颠倒。这主要是由于路由的不同和路由的存储转发的顺序不同造成的。
(1)路由器的存储转发有可能造成数据顺序的更改。例如,主机C发送的数据在经过路由器A和路由器C的时候,顺序均没有发生顺序更改。而在经过主机B的时候,数据的顺序由数据0123变成0321,这样主机C的数据0123顺序经过路由器到达主机S的时候变为了数据0321。
(2)UDP协议的数据经过路由器时的路径造成了发送数据的混乱。从主机C发送的数据0123,其中数据0和3经过路由器B、路由器C到达S,数据1和数据2经过路由器A、路由器C到达主机S,所以数据由发送时的顺序0123变成顺序1032。
3、UDP乱序的对策
对于乱序的解决方法可以采用发送端在数据段中加入数据报序号的方法,这样接收端对接收到数据的头端进行简单地处理就可以重新获得原始顺序的数据。
4、UDP协议中的connect()函数
在UDP协议中使用connect()函数的作用仅仅表示确定了另一方的地址,并没有其他的含议。
connect()函数在UDP协议中使用后会产生如下的副作用:
l 使用connect()函数绑定套接字后,发送操作不能再使用sendto()函数,要使用write()函数直接操作套接字文件描述符,不再指定目地址和端口号。
l 使用connect()函数绑定套接字后,接收操作不能再使用recvfrom()函数函数,要使用read()类的函数,函数不会返回发送方的地址和端口号。
l 在使用多次connect()函数的时候,会改变原来套接字绑定的目的地址和端口号,用新绑定的地址和端口号代替,原有的绑定状态会失效。可以使用这种特定来断开原来的连接。
5、UDP缺乏流量控制
1. UDP缺乏流量控制的概念
UDP协议没有TCP协议所具有的滑动窗口概念,接收数据的时候直接将数据放到缓冲区中。如果用户不有及时地从缓冲区中将数据复制出来,后面到来的数据会接着向缓冲区中放入。当缓冲区满的时候,后面到来的数据会覆盖之前的数据造成数据的丢失。
2. 缓冲区溢出对策
解决UDP接收缓冲区溢出的现象需要根据实际情况确定,一般可以用增大接收数据缓冲区和接收方接收单独处理的方法来解决局部的UDP数据接收缓冲区溢出问题。
6、UDP协议中的数据报文截断
当使用UDP协议接收数据的时候,如果应用程序传入的接收缓冲区的大小小于到来的数据大小时,接收缓冲区会保存最大可能接收到的数据,其他的数据将会丢失,并且有MSG_TRUNC的标志。