UDP报文长度是8字节
UDP为什么是不可靠的?
从UDP的设计层面来说,如果一个应用能够容忍少量的分组丢失,并且它们更加关注于实时通信,那么它们就没必要在每次通信时都引入建立连接的时延,所以我们设计了无连接的UDP来达到这一目的。
UDP是无连接的,所以在发送报文段前后运输层实体间并没有握手,发送方在发送出报文段之后就无法感知这个报文段了。而且UDP只是做了复用分解和少量的差错检测,此外它没有对IP增加其他的东西,也就是说应用程序几乎是直接跟IP打交道。而IP协议也被称作“尽力而为的服务”嘛,它为了保证网络间数据包的快速传输,就抛弃了一系列的可靠性校验,继而UDP就不是可靠传输了。
那我们如何实现UDP的可靠传输呢?
首先,何为可靠传输?我认为“可靠”是指如果某些数据在传输过程中由于拥塞超时等因素丢失,那接收端要有能力检测到数据包丢失,然后要求发送端重新发送丢失的数据,“有序”是指数据要按照当时发送时的顺序来接收。既然UDP是不可靠的,我们可以在应用层维护它的可靠性。
①UDP自身的检验和提供了差错检测。检验和就是发送方把报文段中所有16比特字的和进行反码运算并保存到反码段中,接收方把16比特和与反码段相加,若传输正确则应该全是1。UDP就是通过这样的机制来检测或丢弃受损的报文段,但检验和只是检测,它并没有差错恢复能力。
②TCP连接通过源IP、源端口、目标IP、目标端口来标识通信双方,所以我们可以自定义一个随机数标识来维护一个连接机制,我们通过session来传输、维护这一标识!当IP或端口发生变化时,只要ID不变,那他就是在复用这个连接,这样使得UDP也是面向连接的,也就可以把发送方和接收方的套接字相关联,从而关联操作系统内核信息,那么我们就可以基于操作系统内核与应用层实现UDP的可靠传输了。
③TCP使用序号和ACK机制来解决顺序问题和丢包问题,每个数据包在采用RTT时间内没有应答,就需要超时重发。那我们也可以自定义一个计时器与ACK报文,采样判断发送数据包后收到的ACK是否超时。
④TCP具有滑动窗口、拥塞避免等流量控制机制,那我们可以在UDP报文上自定义一个WINDOW字段,来告诉对端它可以接收的字节数,就相当于滑动窗口了。
UDP协议为什么能实现广播?
因为UDP是没有建立连接的。它的传输原理是把目的地址附在分组上,然后通过目的地址中的IP发送找到对应主机,通过端口号找到对应套接字,根据ip+端口号发送到对应的接收端进程。换而言之,发送端把打包好的报文段通过套接字广播出去就不管了。网络通过报文段上附带的ip与端口号找到接收端套接字,完成端到端的通信。
UDP应用场景
①网络情况比较好的内网、或对于丢包不敏感的应用。比如DHCP
②不需要点对点建立连接,可以广播的应用。比如IGMP、路由器组播
③需要处理速度快、延时低,可以容忍少数丢包的应用。
Linux开启udp端口段
iptables -I INPUT -p UDP --dport 11111 -j ACCEPT
service iptables save