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. 启动接收端(终端1):python receiver.py 37020
  2. 启动发送端(终端2):python sender.py 37020 "广播测试消息" 3
  3. 判定通过条件:接收端终端依次打印3条来自发送端的消息,内容包含 广播测试消息 #1、#2、#3,且发送端显示3条发送成功日志。

关键说明

  • 广播地址:255.255.255.255 为受限广播地址,无需知道目标主机IP即可发送到本地子网所有主机。若需跨子网,应使用目标子网的定向广播地址(如 192.168.1.255)。
  • 端口设置:发送与接收必须使用相同端口号。接收端绑定 ''(所有接口)以接收来自任意网卡的广播。
  • SO_BROADCAST:发送端必须设置此套接字选项,否则发送广播会报 PermissionError。
  • SO_REUSEADDR:接收端设置此选项可避免端口被占用时重启失败,允许多个进程同时绑定同一端口(多播场景常用)。
发送端 sender.py SO_BROADCAST=1 接收端 receiver.py bind('', 37020) 本地子网广播域 255.255.255.255:37020 UDP数据报 其他主机 (不监听则丢弃) 目标端口: 37020 监听端口: 37020

常见问题

  • 发送时报错 [Errno 13] Permission denied:确认已设置 SO_BROADCAST 套接字选项。
  • 接收端收不到消息:检查两端端口是否一致;确认系统防火墙未阻止UDP通信;若在虚拟机或容器中,需确保网络模式支持广播。
  • 同一主机多网卡时收不到:接收端绑定 '' 已覆盖所有接口,若仍失败,可尝试绑定具体网卡IP(如 '192.168.1.10')。