summaryrefslogtreecommitdiffstats
path: root/Demo/sockets/mcast.py
blob: c1902d602bccd07f9803d9b47f3c8ec4b719beff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# Send/receive UDP multicast packets.
# Requires that your OS kernel supports IP multicast.
# This is built-in on SGI, still optional for most other vendors.
#
# Usage:
#   mcast -s (sender)
#   mcast -b (sender, using broadcast instead multicast)
#   mcast    (receivers)

MYPORT = 8123
MYGROUP = '225.0.0.250'

import sys
import time
import struct
from socket import *


# Main program
def main():
    flags = sys.argv[1:]
    #
    if flags:
        sender(flags[0])
    else:
        receiver()


# Sender subroutine (only one per local area network)
def sender(flag):
    s = socket(AF_INET, SOCK_DGRAM)
    if flag == '-b':
        s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        mygroup = '<broadcast>'
    else:
        mygroup = MYGROUP
        ttl = struct.pack('b', 1)               # Time-to-live
        s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, ttl)
    while 1:
        data = repr(time.time())
##              data = data + (1400 - len(data)) * '\0'
        s.sendto(data, (mygroup, MYPORT))
        time.sleep(1)


# Receiver subroutine (as many as you like)
def receiver():
    # Open and initialize the socket
    s = openmcastsock(MYGROUP, MYPORT)
    #
    # Loop, printing any data we receive
    while 1:
        data, sender = s.recvfrom(1500)
        while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's
        print(sender, ':', repr(data))


# Open a UDP socket, bind it to a port and select a multicast group
def openmcastsock(group, port):
    # Import modules used only here
    import string
    import struct
    #
    # Create a socket
    s = socket(AF_INET, SOCK_DGRAM)
    #
    # Allow multiple copies of this program on one machine
    # (not strictly needed)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    #
    # Bind it to the port
    s.bind(('', port))
    #
    # Look up multicast group address in name server
    # (doesn't hurt if it is already in ddd.ddd.ddd.ddd format)
    group = gethostbyname(group)
    #
    # Construct binary group address
    bytes = list(map(int, string.split(group, ".")))
    grpaddr = 0
    for byte in bytes: grpaddr = (grpaddr << 8) | byte
    #
    # Construct struct mreq from grpaddr and ifaddr
    ifaddr = INADDR_ANY
    mreq = struct.pack('ll', htonl(grpaddr), htonl(ifaddr))
    #
    # Add group membership
    s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
    #
    return s


main()