1. UDP协议的特点
相比与TCP协议来说,UDP协议就显得相对比较简单了。
(1)
UDP是无连接的
即发送数据之前不需要建立连接
(当然,发送数据结束时也没有连接可释放),因此减少了开销和发送数据之前的时延。
(2)
UDP使用尽最大努力交付
即不保证可靠交付(可能会丢包)
,因此主机不需要维持复杂的连接状态表(这里面有许多参数)。
(3)
UDP是面向报文的
发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。在接收方的UDP,对IP层交上来的UDP用户数据报,在去除首部后就原封不动地交付上层的应用进程。也就是说,UDP一次交付一个完整的报文。因此,应用程序必须选择合适大小的报文。若报文太长,UDP把它交给IP层后,IP层在传送时可能要进行分片,这会降低IP层的效率。反之,若报文太短,UDP把它交给IP层后,会使IP数据报的首部的相对长度太大,这也降低了IP层的效率。
(4)
UDP没有拥塞控制
因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的
。很多的实时应用(如IP电话、实时视频会议等)要求源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太大的时延
。UDP正好适合这种要求。
(5)
UDP支持一对一、一对多、多对一和多对多的交互通信
(6)
UDP的首部开销小
只有8个字节,比 TCP的20个字节的首部要短。虽然某些实时应用需要使用没有拥塞控制的UDP,但当很多的源主机同时都向网络发送高速率的实时视频流时,网络就有可能发生拥塞,结果大家都无法正常接收。因此,不使用拥塞控制功能的UDP有可能会引起网络产生严重的拥塞问题。
2. UDP程序的编写
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包
。但是,能不能到达就不知道了。虽然用UDP传输数据不可靠,和TCP相比,它速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
2.1
UDP程序
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # SOCK_DGRAM代指UDP协议
s.bind(('127.0.0.1', 9999)) # 绑定端口
while True:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
s.sendto(b'Hello, %s!' % data, addr)
2.2
验证
首先
开启一个NetAssist,然后绑定UDP的8888端口,并开启。如下图所示:
接着
我们运行程序,如下图所示:
再接着
我们在NetAssist的远程主机那里填入要发生通信的主机ip和端口,这里我们填写127.0.0.1:9999
,如下图所示:
最后
发送数据,进行观察,如下图所示:
我们向127.0.0.1:9999发送了数据,9999端口的UDP程序收到了数据,并向8888端口的UDP发送了数据。
3. 写在最后
此处仅仅是编写了一个简单的UDP的demo而已。实际项目中肯定是更为复杂的,此处不再赘述,以期抛砖引玉。