用户数据报协议,是一个无链接的面向数据报的运输层协议。python
UDP不提供可靠性,它只是把应用程序传给IP层的数据报发出去,可是并不能保证他们能到达目的地。服务器
因为UDP在传输数据报前不用在客户和服务器之间创建一个链接,且没有超时重发等机制,故而传输速度很快。网络
UDP是一种面向无链接的协议,每一个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,所以可否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。socket
UDP能够理解为写信,TCP能够理解为打电话。tcp
UDP在互联网中的丢包率几乎为0,在互联网中(美国到中国),丢包率也很低,可是始终仍是存在丢包的可能spa
UDP是面向无链接的通信协议code
UDP数据包括目的端口号和源端口号信息视频
通信不须要创建链接,因此能够实现广播发送server
UDP传输数据有大小限制,每一个被传输的数据报必须限定在64KB以内blog
UDP是一个不可靠的协议,发送方发送的数据报并不必定以相同的次序到达接收方
多点通讯和实时性要求高的场景
UDP是面向消息的协议,通讯时不须要创建链接,数据的传输天然是不可靠的,UDP通常用于多点通讯和实时的数据业务员,如:
语音广播、视频、QQ、TFTP(简单文件传送)、SNMP(简单网络管理协议)、RIP(路由信息协议,如报告股票市场,航空信息)、DNS(域名解释)
注重速度流畅的场景
UDP操做简单,并且仅须要较少的监护,所以一般用于局域网高可靠性的分散系统中的client/server应用程序。如:视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就能够了,这种状况下显然使用UDP会更合理。
流程
建立一个UDP的程序的流程很简单,以下:
一、建立客户端套接字
二、发送/接收数据
三、关闭套接字
原理
通常状况下,在一台电脑上运行的网络程序不少,而各自用的端口号不少状况下是不知道的,为了不与其余的网络程序占用同一个端口号,每每在代码中,udp的端口号是不绑定的。
对于发送方(客户端程序),端口号随机分配问题不大,可是对于接收方(服务器)来讲,最好绑定一个固定的端口,那么别人往服务器发送数据的时候,只须要往约定好的端口发送数据便可。想一想若是服务器的端口号是任意的,那么每次往服务器发送数据的时候还须要肯定端口号,可是服务器的端口号是随机的,如何肯定?!
若是是一个服务器端的程序的话,就须要绑定端口号了。想一想若是报警电话天天都在变,想必世界就会乱了,因此通常服务性的程序,每每须要一个固定的端口号,这就是所谓的端口绑定。
报警电话为110,只能定死,而拨打110的号码,能够是手机,能够是别人的手机,能够是座机,能够是公用电话等等。可见绑定端口,通常是接收方(服务器)才须要绑定端口,而发送方是不须要绑定端口。
听:接收
说:发送
单工:如收音机,只能听,不能说话
半双工:如对讲机,当某我的在说话时,你不能说话,当没人说话时,你可说话
全双工:如电话,能够同时说话。socket就是全双工的,在接收数据的同时也能够发送数据
# coding:utf-8 import socket import config def main(): # 建立udp的套接字 sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 重用ip和port,防止报错 sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定ip和port sk.bind((config.host, config.port)) if config.connected: # 要创建链接 nsk, addr = sk.accept() # 经过新的socket去接收数据 data = nsk.recv(1024) else: # 不用创建链接,只有udp才能这么写,tcp是必须先创建链接的 data, addr = sk.recvfrom(1024) print(data) if __name__ == '__main__': main()
# coding:utf-8 import socket import config def main(): # 建立udp的套接字 sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 地址 addr = (config.host, config.port) # 要发送的内容 send_data = b"hello" if config.connected: # 要创建链接 sk.connect(addr) sk.send(send_data) else: # 不用创建链接 sk.sendto(send_data, addr) if __name__ == '__main__': main()