,我们知道 TCP 可以建⽴可靠连接,并且通信双⽅都可以以流的形式发送数据。本⽂我们再来介绍另⼀个常⽤的协议–UDP。相对TCP,UDP则是⾯向⽆连接的协议。UDP 协议
我们来看 UDP 的定义:
UDP 协议(User Datagram Protocol),中⽂名是⽤户数据报协议,是 OSI(Open System Interconnection,开放式系统互联) 参考模型中⼀种⽆连接的传输层协议,提供⾯向事务的简单不可靠信息传送服务。从这个定义中,我们可以总结出 UDP 的⼏个特点以及其与 TCP 的区别:
UDP 是⽤户数据报协议,传输模式是数据报,⽽ TCP 是基于字节流的传输协议。
UDP 是⽆连接的协议,每个数据报都是⼀个独⽴的信息,包括完整的源地址或⽬的地址,它在⽹络上以任何可能的路径传往⽬的地,因此能否到达⽬的地,到达⽬的地的时间以及内容的正确性都是不能被保证的。
UDP 是简单不可靠的协议,它不提供可靠性,只是把数据包发送出去,并不保证能够到达⽬的地。由于它不需要在客户端和服务端之间建⽴连接,也没有超时重发机制,所以传输速度很快。
从以上特点,我们可以看到 UDP 适合应⽤在每次传输数据量⼩、对数据完整性要求不⾼、对传输速度要求⾼的领域。这⾥⾯最典型的就是即时通信的场景,微信是⼀个很常见的例⼦。相信⼤家在使⽤微信的时候都遇到过先发的消息后收到,或者有些发送的消息对⽅没有收到的情况吧,这就是 UDP 协议典型的特点,不保证传输数据的完整性和顺序性。除此之外, UDP 还应⽤在在线视频、⽹络电话等场景。UDP 传输过程
我们在讲 TCP 的时候,我们说 TCP 客户端和服务端必须先连接才可以传输数据:客户端先请求连接服务器,服务器接受连接请求,然后双⽅才可以通信。在 UDP 协议⾥,客户端只需要知道服务器的地址和端⼝号,就可以直接发送数据了。我们来看下 UDP 传输的流程图:UDP服务器的建⽴可以归纳这⼏步:
创建 socket(套接字)
绑定 socket 的 IP 地址和端⼝号接收客户端数据关闭连接
udp客户端的创建可总结为这⼏步:
创建 socket(套接字)向服务器发送数据关闭连接
这⾥需要注意的是 UDP 客户端连接到服务器的 IP 和端⼝号必须是 UDP 服务器的 IP 和监听的端⼝号,服务器服务器只需要绑定 IP 和端⼝号,就可以时刻准备接收客户端发送的数据,此时服务器处于阻塞状态,直到接收到数据为⽌。UDP 客户端
创建 socket,可以这样做:
# 导⼊socket库import socket
# 创建⼀个socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
创建 socket 时,第⼀个参数 socket.AF_INET 表⽰指定使⽤ IPv4 协议,如果要使⽤ IPv6 协议,就指定为socket.AF_INET6。SOCK_DGRAM 指定基于 UDP 的数据报式 Socket 通信。创建了 socket 之后,我们就可以向⽬标地址发送数据报了:
# 发送数据
s.sendto(b'Hello Server', ('127.0.0.1', 6000))
第⼀个参数是需要发送的数据报内容,第⼆个参数是 IP 地址和端⼝号的⼆元组。如果是接收数据的话,我们可以这样写:
# 接收数据
data, addr = s.recv(1024)# 解码接收到的数据
data = data.decode('utf-8')
接收信息的时候,第⼀个 data 表⽰接收到的数据, addr 是对⽅的 IP 地址和端⼝号的⼆元组。想要关闭 socket,直接调⽤ close() ⽅法即可:
# 关闭 socketsocket.close()
UDP 服务器
相⽐于客户端,服务器端只是多了⼀个步骤,在创建 socket 之后,需要绑定⼀个 IP 地址和端⼝号,以便接收客户端随时可能发送过来的数据。绑定的⽅法为:
# 绑定 IP 和端⼝
s.bind(('127.0.0.1', 6000))
UDP 简单实例
我们通过⼀个简单的实例来体会下 UDP 的客户端和服务器的通信流程。服务器代码为:
import socket
# 创建 socket
sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 绑定 IP 和端⼝号
sk.bind(('127.0.0.1', 6000))while True: # 接收数据报
msg, addr = sk.recvfrom(1024) # 打印
print('来⾃[%s:%s]的消息: %s' % (addr[0], addr[1], msg.decode('utf-8'))) # 等待输⼊
inp = input('>>>') # 发送数据报
sk.sendto(inp.encode('utf-8'), addr)# 关闭 socketsk.close()
这⾥,我们先创建 socket,然后绑定本机的6000端⼝,然后等待接收客户端发送的数据报,接收到数据后将数据内容打印在控制台。然后可以在控制台输⼊回复内容,发送给客户端。客户端代码:
import socket
# 创建 socket
sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)addr = ('127.0.0.1', 6000)while True: # 等待输⼊
msg = input('>>>') # 发送数据报
sk.sendto(msg.encode('utf-8'), addr) # 接收数据报
msg_recv, addr = sk.recvfrom(1024) # 打印
print(msg_recv.decode('utf-8'))# 关闭 socketsk.close()
在客户端代码中,我们就只是创建 socket,然后在控制台输⼊需要向服务器发送的内容,通过 sentto() ⽅法发送给服务器,然
后接收服务器返回的内容,将接收的内容打印到控制台。
分别运⾏客户端和服务器代码,然后我们在客户端的控制台输⼊ “hello server”,我们可以看到服务器的控制台打印了客户端发送的内容,然后我们在服务器控制台输⼊ “hello client”,同样在客户端控制台可以看你到内容。下⾯是客户端的控制台内容:
>>>hello serverhello client>>>
下⾯是服务器的控制台内容:
来⾃[127.0.0.1:61207]的消息: hello server>>>hello client
这个实例其实就是⼀个简单的聊天模型,客户端和服务器就像两个⼈⼀样可以发送和接收对⽅的信息。
那么多⼈群聊怎么实现呢?简单来说,我们需要设置⼀台中⼼服务器,我们每个⼈发送的内容都先发送到中⼼服务器,然后中⼼服务器再转发到每个群聊的⼈。总结
本⽂为⼤家介绍了 UDP 编程的基本原理以及通过 Python 实现⼀个最简单的聊天程序来模拟 UDP 通信的过程。通过本⽂的学习,我们需要对 UDP 协议有基本的认识,以及对 UDP 的通信过程⽐较熟悉。
以上就是详解python UDP 编程的详细内容,更多关于python UDP 编程的资料请关注其它相关⽂章!
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- sceh.cn 版权所有 湘ICP备2023017654号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务