UPD 广播与组播

广播

接收端
python3 复制代码
import socket

UDP_PORT = 9999
online_bmc = {}
HEARTBEAT_TIMEOUT = 15

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("0.0.0.0", UDP_PORT))
print("UDP server listening on port %d..." % UDP_PORT)

while True:
    data, (bmc_ip, _) = sock.recvfrom(1024)
    msg = data.decode().strip()
    print("receive msg: ", msg)
发送端
bash 复制代码
# 发送广播
python3 -c "import socket; s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1); s.sendto(b'Broadcast message', ('255.255.255.255', 9999))"

# 发送单播
echo "sing test" > /dev/udp/10.101.197.214/9999

组播(多播)

接收端
python3 复制代码
import socket
import struct
import sys

MULTICAST_GROUP = "239.1.2.3"
PORT = 8888
# LOCAL_IP = "0.0.0.0"
LOCAL_IP = "10.101.197.214"

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# bind physical network interface IP (Not '' or '0.0.0.0')
sock.bind((LOCAL_IP, PORT))

# mreq = struct.pack("4sl", socket.inet_aton(MULTICAST_GROUP), socket.INADDR_ANY)
mreq = struct.pack("4sI",
                   socket.inet_aton(MULTICAST_GROUP),
                   struct.unpack("I", socket.inet_aton(LOCAL_IP))[0])
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

print(f"Listening on {LOCAL_IP}:{PORT} for group {MULTICAST_GROUP}")

while True:
    data, addr = sock.recvfrom(1024)
    print(f"Received from {addr[0]}: {data.decode()}")
发送端

bash

bash 复制代码
# 使用 socat
echo "Test" | socat - UDP4-DATAGRAM:239.1.2.3:8888,ttl=2

# 使用 python3
python3 -c "import socket;s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM);s.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,2);s.sendto(b'Test',('239.1.2.3',8888))"

# 循环发送系统信息
while true; do echo "$(hostname): $(uptime)" | socat - UDP4-DATAGRAM:239.1.2.3:8888,ttl=2; sleep 5; done
检查电脑是否加入了组播

powershell

bash 复制代码
netsh int ip show joins

如果在输出的ip列表里有你定义的组播地址,说明加入成功了。

tcpdump 抓包

格式:sudo tcpdump -i <网卡名称> -nn 'udp port <端口号>'

在发送端新开一个窗口,执行

bash 复制代码
sudo tcpdump -i enp3s0 -nn 'udp port 8888'

网卡名称执行ifconfig查看。下面的 enp3s0 即使网卡名(当前机器的ip是inet 10.101.197.112 )

bash 复制代码
ifconfig
enp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.101.197.112  netmask 255.255.255.0  broadcast 10.101.197.255
        inet6 fe80::d41c:486b:b424:4955  prefixlen 64  scopeid 0x20<link>
        ether 00:23:81:63:e8:a6  txqueuelen 1000  (以太网)
        RX packets 2934  bytes 1285704 (1.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 779  bytes 137898 (137.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 46  base 0x8000

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (本地环回)
        RX packets 81  bytes 38976 (38.9 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 81  bytes 38976 (38.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0