1

I'm wondering if it's possible to bind more than one multicast address without using multithreading(creating few sockets), just by creating one socket that can obtain data from two addresses (which is my current way of doing this).

My code looks like:

import socket
import struct
import time


MCAST_GRP2 = '239.0.1.105'
MCAST_GRP = '239.0.1.104'

MCAST_PORT = 12345


IS_ALL_GROUPS = True
#scan time in seconds
SCAN_TIME = 10
#sampling time in seconds
SAMPLING_TIME = 1
bufferUDP = 2048
totalSize = 0
bitrateList = []


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

if IS_ALL_GROUPS:
    # on this port, receives ALL multicast groups
    sock.bind(("", MCAST_PORT))
    sock2.bind(("", MCAST_PORT))
else:
    # on this port, listen ONLY to MCAST_GRP
    sock.bind((MCAST_GRP, MCAST_PORT))
    sock2.bind((MCAST_GRP2, MCAST_PORT))

mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
mreq2 = struct.pack("4sl", socket.inet_aton(MCAST_GRP2), socket.INADDR_ANY)

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
sock2.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq2)

print("_____.:|   Starting analysis of multicasts!   |:._____\n")


for x in range(SCAN_TIME):
    stop = time.time() + SAMPLING_TIME
    while (time.time()<stop):
        totalSize += len(sock.recv(bufferUDP)) + len(sock2.recv(bufferUDP))

    bitrateList.append(totalSize)
    print(bitrateList[x]*8/(1000000))
    totalSize = 0



bitrateList.pop(0)
txtfile = open("Bitrate_history_ip_{}.txt".format("TESTTT"),"w+")
for x in range(SCAN_TIME-1):
    bitrateList[x] = bitrateList[x]*8/(1000000)
    txtfile.write("{}.Bitrate was equal to: {} Mbps\n".format(x+1,bitrateList[x]))

txtfile.write("Maximum bitrate value was: {} Mbps\n".format(max(bitrateList)))
txtfile.write("Minimum bitrate value was: {} Mbps\n".format(min(bitrateList)))


print('End of test')
time.sleep(5)

And is based on:

How do you UDP multicast in Python?

1 Answers1

2

.. just by creating one socket that can obtain data from two addresses

One cannot bind a socket to multiple IP addresses.

One can still handle multiple sockets in parallel without needing multiple threads or multiple processes. This is done with an event-based architecture and non-blocking sockets, see Non-blocking Sockets in the Python documentation for more details.

Steffen Ullrich
  • 90,680
  • 7
  • 99
  • 140
  • `One (socket) cannot bind a socket to multiple IP addresses.` `One can still handle multiple sockets in parallel`? One socket can handle multiple sockets? How can I do that in case of my code? Right now my code (local code with multithreading) creates 2 sockets, on each socket bitrate is calculated. Currently `IS_ALL_GROUPS` is set to false - the results is that each thread gives unique bitrate for address. If parameter is set to true, it prints out twice the same, summed result of two addresses. I would like to get this but without using multiple threads. – kaszankabanka Dec 16 '19 at 09:55
  • 1
    @kaszankabanka: Please follow the documentation I've explicitly linked to. Other examples see [here](https://pymotw.com/2/select/) or [here](https://stackoverflow.com/questions/15101333/is-there-a-way-to-listen-to-multiple-python-sockets-at-once). – Steffen Ullrich Dec 16 '19 at 11:26