4. UDP广播
任务目标
实现一个UDP广播通信的最小可运行示例:发送端向广播地址 255.255.255.255 的指定端口周期发送消息,接收端绑定该端口并监听,打印收到的广播内容。通过本案例理解UDP广播的地址选择、端口绑定及收发流程。
环境与依赖
- Python 3.6+(标准库
socket,无需第三方依赖) - 发送端与接收端可在同一台机器上运行验证(本机回环广播)
核心实现
以下代码包含两个独立脚本:receiver.py 负责绑定端口并持续接收广播;sender.py 负责向广播地址发送消息。两个脚本通过命令行参数控制端口与消息内容。
# receiver.py - UDP广播接收端
import socket
import sys
def main():
port = int(sys.argv[1]) if len(sys.argv) > 1 else 37020
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[0]}:{addr[1]} - {data.decode()}')
if __name__ == '__main__':
main()
# sender.py - UDP广播发送端
import socket
import sys
import time
def main():
port = int(sys.argv[1]) if len(sys.argv) > 1 else 37020
message = sys.argv[2] if len(sys.argv) > 2 else 'Hello UDP Broadcast'
count = int(sys.argv[3]) if len(sys.argv) > 3 else 3
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # 启用广播权限
for i in range(count):
sock.sendto(f'{message} #{i+1}'.encode(), ('255.255.255.255', port))
print(f'[发送] 第 {i+1} 条 -> 255.255.255.255:{port}')
time.sleep(1)
sock.close()
if __name__ == '__main__':
main()
运行与验证
- 启动接收端(终端1):
python receiver.py 37020 - 启动发送端(终端2):
python sender.py 37020 "广播测试消息" 3 - 判定通过条件:接收端终端依次打印3条来自发送端的消息,内容包含
广播测试消息 #1、#2、#3,且发送端显示3条发送成功日志。
关键说明
- 广播地址:
255.255.255.255为受限广播地址,无需知道目标主机IP即可发送到本地子网所有主机。若需跨子网,应使用目标子网的定向广播地址(如192.168.1.255)。 - 端口设置:发送与接收必须使用相同端口号。接收端绑定
''(所有接口)以接收来自任意网卡的广播。 - SO_BROADCAST:发送端必须设置此套接字选项,否则发送广播会报
PermissionError。 - SO_REUSEADDR:接收端设置此选项可避免端口被占用时重启失败,允许多个进程同时绑定同一端口(多播场景常用)。
常见问题
- 发送时报错
[Errno 13] Permission denied:确认已设置SO_BROADCAST套接字选项。 - 接收端收不到消息:检查两端端口是否一致;确认系统防火墙未阻止UDP通信;若在虚拟机或容器中,需确保网络模式支持广播。
- 同一主机多网卡时收不到:接收端绑定
''已覆盖所有接口,若仍失败,可尝试绑定具体网卡IP(如'192.168.1.10')。