4. UDP广播与接收
任务目标
实现一个UDP广播发送端和一个接收端:发送端向子网广播地址发送消息,同一网络中的多个接收端进程都能收到该消息。通过本案例掌握UDP广播的地址设置、套接字选项配置及多客户端接收验证方法。
实现原理与关键点
UDP广播使用受限广播地址 255.255.255.255 或子网定向广播地址(如 192.168.1.255)。发送端无需特殊配置,接收端必须设置 SO_REUSEADDR 套接字选项,否则多个接收端绑定同一端口会冲突。广播消息默认被路由器隔离,仅在当前局域网内传播。
完整代码
# udp_broadcast.py
import socket
import sys
def broadcast_sender(message="Hello Broadcast", port=8888):
"""发送UDP广播消息"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 允许广播
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# 使用受限广播地址,发送到所有子网
sock.sendto(message.encode(), ('255.255.255.255', port))
sock.close()
print(f"[发送端] 已广播: {message}")
def broadcast_receiver(port=8888):
"""接收UDP广播消息(可多实例同时运行)"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 关键:允许多个接收端绑定同一端口
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', port))
print(f"[接收端] 监听端口 {port},等待广播...")
while True:
data, addr = sock.recvfrom(1024)
print(f"[接收端] 收到来自 {addr} 的消息: {data.decode()}")
if __name__ == '__main__':
if len(sys.argv) < 2:
print("用法:")
print(" 发送: python udp_broadcast.py send [消息内容]")
print(" 接收: python udp_broadcast.py receive")
sys.exit(1)
mode = sys.argv[1].lower()
if mode == 'send':
msg = sys.argv[2] if len(sys.argv) > 2 else "Hello Broadcast"
broadcast_sender(msg)
elif mode == 'receive':
broadcast_receiver()
else:
print("未知模式,使用 send 或 receive")
运行与验证
环境要求:Python 3.6+,无需第三方库。所有测试设备需连接同一局域网(同一Wi-Fi或交换机)。
验证步骤:
- 打开两个或多个终端,均进入代码所在目录,分别执行接收命令:
python udp_broadcast.py receive
每个终端都会显示“监听端口 8888,等待广播...”。
- 另开一个终端,执行发送命令:
python udp_broadcast.py send "测试广播消息"
通过条件:所有正在运行的接收端终端都同时打印出 [接收端] 收到来自 ('发送端IP', 临时端口) 的消息: 测试广播消息,且发送端显示发送成功。若多个接收端均收到同一条消息,则验证通过。
常见问题
- 接收端收不到消息:检查防火墙是否拦截UDP端口8888;确认发送端与接收端在同一网段(可用
ipconfig/ifconfig查看IP);部分云服务器或虚拟网络环境不支持广播,需改用真实局域网测试。 - 第二个接收端启动报错“Address already in use”:确认代码中已设置
SO_REUSEADDR;Windows系统下该选项对UDP多绑定生效,Linux/macOS同样支持。 - 发送端报错“Permission denied”:某些系统禁止向
255.255.255.255发送,可改用子网定向广播地址(如192.168.1.255,需根据实际子网修改)。