Multicast

In simple terms, I can do a broadcast on a network. This results in every client on the network receiving and processing the packet. That's a great way to cause congestion on a network! There are cases where the output of process needs to be seen by many other processes on many other nodes.

Imagine I have power monitoring equipment in my data centre, and I have distributed control to take action based on the power state. For example, if the power is out, and the temperature is OK, I might shut down ventilation fans to reduce the load on the Uninterruptible Power Supply (UPS). One way to do this is to use multicast.

First, I create Exercises_11\settings\mc.py

MCSERVER = {
    "MCAST_GROUP": '239.1.1.1',
    "IP_ADDRESS": '127.0.0.1',
    "PORT": 5001
}

MCCLIENT = {
    "MCAST_GROUP": '239.1.1.1',
    "IP_ADDRESS": '127.0.0.1',
    "PORT": 5001
}

Then I create Exercises_11\mc_client.py

'''
Multicast client by: JOR
Sends multicast packets to a particular address and port.
Alpha: 13FEB22
'''
import socket
import time
from datetime import datetime
import settings.mc as settings

# Set multicast information
MCAST_GRP = settings.MCCLIENT["MCAST_GROUP"]
MCAST_PORT = settings.MCCLIENT["PORT"]
MCAST_IF_IP = settings.MCCLIENT["IP_ADDRESS"]

print(f'This is the client, make sure its IP address matches {MCAST_IF_IP} in settings.')
print(f'This selects which interface is used for multicast to {MCAST_GRP}.')
print('This script has no error handling, by design')

while True:
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as s:
        # inet_aton converts IPv4 from the a dotted decimal string to 32 bit packed binary format
        s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MCAST_GRP) + socket.inet_aton(MCAST_IF_IP))
        message_text = f"ATU {datetime.now()}"
        message = message_text.encode('utf-8')
        s.sendto(message, (MCAST_GRP, MCAST_PORT))
        print(f'Sent {message_text} to {MCAST_GRP}:{MCAST_PORT}')
        time.sleep(1)

Then I create Exercises_11\mc_server.py

'''
Multicast Server by: JOR
Reads multicast packets from a particular address and port.
Alpha: 13FEB22
'''
import socket
import struct
import settings.mc as settings

# Set multicast information
MCAST_GRP = settings.MCSERVER["MCAST_GROUP"]
SERVER_ADDRESS = ('', settings.MCSERVER["PORT"])
MCAST_IF_IP = settings.MCSERVER["IP_ADDRESS"]

print('This is the server.')
print(f'Make sure its IP address matches {MCAST_IF_IP} in settings.')
print(f'This selects which interface is used to listen for multicast as {MCAST_GRP}.')
print('This script has no error handling, by design.')

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
    s.bind(SERVER_ADDRESS)
    # inet_aton converts IPv4 from the a dotted decimal string to 32 bit packed binary format
    s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MCAST_GRP) + socket.inet_aton(MCAST_IF_IP))

    while True:
        print('Waiting to receive message')
        data, address = s.recvfrom(1024)
        print(f'received {len(data)} bytes from {address}')
        print(data)

Last updated