UDP不像TCP创建连接时有3次握手,而是直接发送数据,不管对方是否接收到。
UDP网络通信不区分客户端和服务端。
UDP收发数据的步骤
1.创建UDP套接字对象
2.直接发送数据
3.读取数据
4.关闭套接字
示例
服务端
1 ''' 2 UDP应该说没有服务端和客户端,只是习惯称发请求的为客户端端,对方为服务端 3 4 最佳实践: 5 1. 创建UDP套接字:使用socket.socket()函数创建一个UDP套接字对象。 6 import socket 7 # 创建UDP套接字 8 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 9 2. 绑定地址和端口:使用bind()方法将套接字绑定到指定的IP地址和端口。 10 # 绑定地址和端口 11 udp_socket.bind(('127.0.0.1', 8000)) 12 3. 发送数据:使用sendto()方法发送数据给指定的目标地址和端口。 13 # 发送数据 14 data = b"Hello, UDP server!" 15 udp_socket.sendto(data, ('127.0.0.1', 9000)) 16 4. 接收数据:使用recvfrom()方法接收来自其他主机的数据,并返回接收到的数据和发送方的地址信息。 17 # 接收数据 18 data, addr = udp_socket.recvfrom(1024) 19 print("Received data:", data.decode()) 20 print("From address:", addr) 21 5. 关闭套接字:使用close()方法关闭套接字。 22 # 关闭套接字 23 udp_socket.close() 24 ''' 25 import socket 26 27 # 创建UDP套接字 28 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 29 udp_socket.bind(('127.0.0.1', 8000)) 30 31 while True: 32 # 接收数据 33 data, addr = udp_socket.recvfrom(1024) 34 print("Received data:", data.decode()) 35 36 # 发送数据 37 message = input("Enter message to send: ") 38 udp_socket.sendto(message.encode(), addr)
客户端
import socket # 创建UDP套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: # 发送数据 message = input("Enter message to send: ") udp_socket.sendto(message.encode(), ('127.0.0.1', 8000)) # 接收数据 data, addr = udp_socket.recvfrom(1024) print("Received data:", data.decode())
这个案例展示了一个简单的UDP聊天应用程序,服务器和客户端可以互相发送消息。服务器接收到客户端发送的消息后,将其显示在控制台,并向客户端回复一个消息。
广播
1 import socket 2 3 # 创建UDP套接字 4 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 5 udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 6 7 # 广播地址和端口号 8 broadcast_address = '<broadcast>' 9 port = 8000 10 11 # 发送消息到广播地址 12 message = "Hello, broadcast!" 13 udp_socket.sendto(message.encode(), (broadcast_address, port)) # 14 15 # 接收来自服务器的响应 16 response, address = udp_socket.recvfrom(1024) 17 print("Received response from server:", response.decode()) 18 print("Server address:", address) 19 20 # 关闭套接字 21 udp_socket.close()
# 服务端代码,用于处理广播消息 import socket # 创建UDP套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定到特定的IP地址和端口号 server_address = ('', 8000) udp_socket.bind(server_address) while True: # 接收来自客户端的请求 data, address = udp_socket.recvfrom(1024) print("Received request from client:", data.decode()) print("Client address:", address) # 发送回复消息 response = "Hello, client!" udp_socket.sendto(response.encode(), address) # 客户端代码,用于发送广播消息 import socket # 创建UDP套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # 广播地址(是广播地址的,也可以这样写)和端口号(端口号是服务端的端口) broadcast_address = '<broadcast>' port = 8000 # 发送广播消息 message = "Service discovery request" udp_socket.sendto(message.encode(), (broadcast_address, port)) # 接收来自服务端的回复消息 response, address = udp_socket.recvfrom(1024) print("Received response from server:", response.decode()) print("Server address:", address) # 关闭套接字 udp_socket.close()
获取广播地址的代码:
import socket import struct def calculate_broadcast_address(ip_address, subnet_mask): ip_bytes = socket.inet_aton(ip_address) mask_bytes = socket.inet_aton(subnet_mask) # 将IP地址和子网掩码转换为32位整数 ip_int = struct.unpack('!I', ip_bytes)[0] mask_int = struct.unpack('!I', mask_bytes)[0] # 计算广播地址 broadcast_int = ip_int | (~mask_int & 0xFFFFFFFF) # 将广播地址转换为字符串形式 broadcast_address = socket.inet_ntoa(struct.pack('!I', broadcast_int)) return broadcast_address ip_address = '192.168.68.1' # 自己电脑的ip subnet_mask = '255.255.255.0' # ip对于的子网掩码 broadcast_address = calculate_broadcast_address(ip_address, subnet_mask) print("Broadcast Address:", broadcast_address)
客户端:
服务端:
参考:https://www.bilibili.com/video/BV1dZ4y1o7Az/?spm_id_from=333.337.search-card.all.click&vd_source=551c4b0e8145ff81bc32a29ff09a3238
标签:UDP,socket,udp,broadcast,address,接字 From: https://www.cnblogs.com/allenxx/p/17625686.html