1.首先还是需要说一下UDP协议。先看一下UDP在五层网络协议中的地位吧:
UDP/TCP是传输层协议,为应用层提供了接口。但是二者有着很大的区别。UDP全称是用户数据报协议。这玩意怎么传输数据呢?其实很简单,他把数据打包,然后封装成一个数据包,封装完成之后,丢给网络层,网络层加一层IP丢给链路层,链路再加一层自己的东西丢给物理层,物理层直接开始传输。这其实就体现了分层的好处,每一层只需要做好自己的事,并且给上一层提供接口。然后就井然有序的工作了。
2.UDP协议格式:
看上去十分的简洁,首先是源端口和目的端口(这个时候你就不用管IP了,因为这个工作会在网络层做)然后数数据长度,最大64k,然后是checksum。防止数据传输过程中出错,这起事件就是一个数据包的Hash值,检错的。
3.UDP的优缺点。首先一个很重要的缺点:容易丢失。UDP的主旨是我努力帮你传输,但是结果我不管。就像那个checksum,如果发现组后数据错了,checksum不对,那也没办法。丢失了就丢失了,错了就错了。其次,没法控制拥塞:啥叫拥塞?堵车知道吧,UDP传输的时候不管你链路上有多少数据在哪堵着,他只管传自己的,所以很可能造成越来越堵。还有一个很多的缺点,包的顺序无法保证,包长有限制....但是,存在即合理,他还是有很多优点的。虽然说他可能丢丢包,但是对于一下对于数据要求不严格的文件,比如音频,视频,少个一两帧你还是可以看懂,而且他的效率高(可能是因为比较莽,传就完事了)。所以还是由很多的应用。但是这其中存在的问题,是必须解决的,因为还是有很多文件对数据有着严格的要求的。所以提出了可靠传输的概念以及可靠传输的典型实现:TCP协议,但是TCP不仅仅是可靠传输,他还做了更多的事情,这个我们后边再说。
4.算了,既然说到了UDP,光说不练假把式,就简单的写一个基于UDP通信的程序。分为客户端和服务端。程序如下(Python实现):
客户端:
from socket import *
HOST = '127.0.0.1'#主机地址,这里就采用本机地址
PORT = 21567#端口号
BUFSIZ = 1024#数据长度
ADDR = (HOST,PORT)#地址元组
udpCliSock = socket(AF_INET,SOCK_DGRAM)#SOCK_DGRAM:采用UDP
while True:
data = input('> ')
if not data:
break
udpCliSock.sendto(data.encode(),ADDR)#发送
data,addr=udpCliSock.recvfrom(1024)#接受
print(data.decode())
udpCliSock.close()
服务端:
from socket import *
HOST = '127.0.0.1'#localhost
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST,PORT)
udpSerSock = socket(AF_INET,SOCK_DGRAM)
udpSerSock.bind(ADDR)
while True:
print("waiting for message...")
data,addr = udpSerSock.recvfrom(BUFSIZ)
print("...receive from and return to:" , data)
udpSerSock.close()