一、什么是UDP协议
相对于 TCP 协议,UDP 协议则是面向无连接的协议。使用 UDP 协议时,不需要建立连接,只需要知道对象的 IP 地址和端口号,就可以直接发数据包。但是,数据无法保证一定到达。虽然用 UDP 传输数据不可靠,但它的优点是比 TCP 协议的速度快。对于不要求可靠到达的数据而言,就可以使用 UDP 协议。
UDP 每次发送数据的时候,都需要写上接收方的 IP 和 PORT;
二、创建UDP服务器
创建 UDP 服务器的伪代码如下:
import socket # 导入socket模块
ss = socket.socket() # 创建服务器套接字
ss.bind() # 套接字与地址绑定
while True: # 监听连接
cs = ss.recvfrom()/ss.sendto() # 对话(接收/发送)
ss.close() # 关闭服务器套接字
UDP 和 TCP 服务器之间的一个显著差异是,因为数据报套接字是无连接的,所以就没有为了通信成功而使一个客户端连接到一个独立的套接字 “转换” 的操作。这些服务器仅仅接收消息,并有可能回复数据。
from socket import socket
from socket import AF_INET, SOCK_DGRAM, SOL_SOCKET, SO_REUSEADDR
from time import ctime
HOST = "127.0.0.1"
PORT = 8080
ADDRESS = (HOST, PORT)
udp_server = socket(AF_INET, SOCK_DGRAM) # 创建服务器套接字
udp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # 解决端口占用问题
udp_server.bind(ADDRESS) # 套接字与地址绑定
while True: # 通信循环
recv_data, client_addr = udp_server.recvfrom(1024) # 服务端接收消息,单次最大接收为1024个字节
print(f"收到客户端【{client_addr}】数据:{recv_data.decode('utf-8')}")
udp_server.sendto(f"【{ctime()}】 {recv_data.decode('utf-8')}".encode("utf-8"), client_addr) # 服务端发送消息
udp_server.close() # 关闭服务器套接字
对 socket() 的调用的不同之处仅仅在于,我们现在需要一个 数据报/UDP 套接字类型,但是 bind() 的调用方式与 TCP 服务器版本的相同。因为 UDP 是无连接的,所以这里没有调用 “监听传入的连接”。
三、创建UDP客户端
创建 UDP 服务器的伪代码如下:
import socket # 导入socket模块
cs = socket.socket() # 创建客户端套接字
while True: # 通信循环
cs.sendto()/cs.recvfrom() # 对话(发送/接收)
cs.close() # 关闭客户端套接字
UDP 客户端循环工作方式几乎和 TCP 客户端一样。唯一的区别是,事先不需要建立与 UDP 服务器的连接,只是简单的发送一条消息并等待服务器的回复。
from socket import socket
from socket import AF_INET, SOCK_DGRAM
HOST = "127.0.0.1"
PORT = 8080
ADDRESS = (HOST, PORT)
udp_client = socket(AF_INET, SOCK_DGRAM) # 创建客户器套接字
while True: # 通信循环
send_data = input("请输入要发送的数据: ").strip()
udp_client.sendto(send_data.encode("utf-8"), ADDRESS) # 客户端发送数据
recv_data, server_addr = udp_client.recvfrom(1024) # 客户端接收数据,单次最大接收为1024个字节
print(f"收到服务端【{server_addr}】返回的数据:{recv_data.decode('utf-8')}")
udp_client.close() # 关闭客户端套接字
四、执行UDP服务器和客户端
如果先运行客户端,那么将无法进行任何连接,因为没有服务器等待接受请求。服务器可以视为一个被动伙伴,因为必须首先建立自己,然后被动的等待连接。另一方面,客户端是一个主动的合作伙伴,因为它主动发起一个连接。换句话说,首先启动服务器(在任何客户端试图连接之前)。
在开发中,创建这种 “友好的” 退出方式的一种方法就是,将服务器的 while 循环放在一个 try-except 语句中的 except 子句中,并监控 EOFError 或 KeyboardInterrupt 异常,这样你就可以在 except 或 finally 子句中关闭服务器的套接字。
标签:UDP,socket,05,编程,udp,服务器,接字,客户端 From: https://www.cnblogs.com/kurome/p/17800970.html