-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcsdisc.py
More file actions
134 lines (120 loc) · 4.56 KB
/
mcsdisc.py
File metadata and controls
134 lines (120 loc) · 4.56 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
Multicast service discovery
"""
import threading, time, socket, struct, json
class MulticastServiceDiscovery(threading.Thread):
"""
Client and server
"""
def __init__(self, addr = "224.3.4.5", port=45566):
threading.Thread.__init__(self)
self.addr = addr
self.port = port
self.services = {}
self.serverip = ""
self.daemon = True
#client section
def discover(self, ttlval=10):
"""
Send discover message to all servers from
multicast group and return a list
of servers with services
"""
multicast_group = (self.addr, self.port)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
#People have the misconception that binding is only for listening on a socket,
#but this is also true for connecting, and its just that in normal usage the binding is chosen for you.
#select ethernet interface according to self.serverip
sock.bind((self.serverip, 0))
sock.settimeout(1.5)
ttl = struct.pack("b", ttlval)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
message = "discover"
L = []
sent = sock.sendto(message, multicast_group)
while True:
try:
data, server = sock.recvfrom(1024)
except socket.timeout:
break
else:
L.append((data, server))
return L
def registerService(self, key, value):
#Update service list
self.services[key] = value
def run(self):
#Thread function
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((self.serverip, self.port))
group = socket.inet_aton(self.addr)
mreq = struct.pack("4sL", group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
sock.settimeout(0.5)
while True:
try:
data, address = sock.recvfrom(1024)
#it doesn't matter the data received, send always the service list
servicelist = json.dumps(self.services)
sock.sendto(servicelist, address)
except socket.timeout:
#ignore
pass
except Exception as ex:
print ex
if __name__ == "__main__":
"""
Test module
"""
print "Test module host =",socket.gethostname()
hostname, aliaslist, ipaddrlist = socket.gethostbyname_ex(socket.gethostname())
print "ipaddrlist=",ipaddrlist
mcsd_list = []
for serverip in ipaddrlist:
#if we have multiple ethernet interfaces
#create an MulticastServiceDiscovery instance for each interface
print "Add server on",serverip
mcsd = MulticastServiceDiscovery()
#mcsd.serverip should keep selected interface
#IP address, but on Linux is not working. Default is "".
#mcsd.serverip = serverip #test this on windows
#register a service according the interface IP address
mcsd.registerService("DSN","mssql+pymssql://webuser:userweb@{}/WWWDB".format(serverip))
mcsd.registerService("RPC","http://{}:4001".format(serverip))
mcsd.registerService("WEB","http://{}:8080".format(serverip))
iplist=""
for i in ipaddrlist:
if iplist:
iplist += ", "
iplist += i
mcsd.registerService("ipaddrlist",iplist)
mcsd_list.append(mcsd)
mcsd.start()
del mcsd
time.sleep(1)
try:
while True:
#time.sleep(2)
print "=========================="
for ix,mcsd in enumerate(mcsd_list):
if mcsd.serverip:
print "\n\n\nClient{} on {} discover:".format(ix, mcsd.serverip)
else:
#On Linux?
print "\n\n\nClient{} discover:".format(ix)
L = mcsd.discover(20)
for i in L:
data, server = i
d = json.loads(data.replace("'", "\""))
print "Services from",server
for i in d.keys():
print i,"=",d[i]
print "---------------"
raw_input("Press ENTER to retry discovery.")
except KeyboardInterrupt:
#print "KeyboardInterrupt"
pass
except Exception as ex:
print ex
raw_input("\nProgram ends. Press ENTER")