Distributed Computing With XML-RPC Python - python

Alright, here is a project I am running into issues with. I have the code written up, but it's running into issues. Frankly, I'm not even sure I connected the two files I had to use correctly so if someone could take a gander and help me determine what's wrong, I'd be glad for the assistance. Here are the instructions/hints.
Common tasks in distributed computing applications often require the
ability of one computer to be able to remotely invoke a procedure on
another computer in the distributed system. This assignment introduces
this idea further using XML-RPC and Python.
XML-RPC is a protocol used to call procedures, (i.e. methods or
functions) by one computer (client) on another computer (server). Its
name results from fact that XML is used to encode the procedure calls.
The means used to transport the XML from the client to the server is
HTTP. While Python has built-in support for this functionality, it is
important to note that support is not limited to Python but extends to
most high level languagesadd. This is inherent in the design since the
encoding is generic XML and transport is HTTP.
Finally, there are many ways to implement such functionality. For
Python, while outside the scope of this course, the interested reader
should explore projects such as Pyro, RPyC, and Fabric.
XML-RPC’s implementation in Python is found in the xmlrpc package. In
this package, the required modules are xmlrpc.client and
xmlrpc.server.
Assignment
This assignment requires you to develop two Python programs. One is a
client, the other is the server.
Server
The server should “register” x procedures that the client will
be able to call. It will then bind to the address “localhost” and port
8000. This is the address and port that the server will listen to for requests. Note that if you have binding errors, you may use another
port as your computer may have an application that is using 8000. Most
of the time, however, this will work. Your server invocation must be
in the following form:
python server.py localhost 8000
These procedures to be supported are as follows: name – returns the
name of the server which is passed on the commandline during server
invocation help – returns a list of procedures that the server
supports servertime – returns the current time at the server in 24
hour format. I.e. 13:00:01 add(x,y) – returns the sum of x and y
sub(x,y) – returns x – y mult(x,y) – returns x * y div(x,y) – returns
x/y (be sure to handle the divid by 0 scenario)
Client
The client is to connect to the server using the server’s
address and the port that the server is listening on (see above). It
then will exercise each of the supported procedures using the values 8
and 6 for the values x and y respectively. Your client invocation must
be in the following form:
python client.py host_address host_port 8 6
where host_address and host_port are the address and port that the
server is listening on. If you are using a single computer for server
and client computers just use “localhost” for the address and the port
used above. The 8 and the 6 are the values for x and y.
Example Output Of Client:
8 * 6 is 48.0 8 / 6 is 1.3333333333333333 8 + 6 is 14.0 8 - 6 is 2.0 8
/ 0 is Infinity 13:50:22
I will give the code of both files so that someone might be able to help with it. It's more the Server.py file having issues than the Client.py file, but I will post both anyways.
Server.py
import sys
import time
from xmlrpc.server import SimpleXMLRPCServer
argumentList = sys.argv
hostAddress = argumentList[1]
port = argumentList[2]
server = SimpleXMLRPCServer((hostAddress, int(port)))
def addition(x, y):
return x + y
def subtraction(x, y):
return x - y
def multiplication(x, y):
return x * y
def division(x, y):
try:
return x / y
except ZeroDivisionError:
return "To Infinity and Beyond! Whee!"
def name():
return hostAddress
def helpMe():
return server.systemListMethods()
def serverTime():
return time.strftime("%H:%M:%S")
server.register_function(helpMe)
server.register_function(addition)
server.register_function(serverTime)
server.register_function(subtraction)
server.register_function(multiplication)
server.register_function(division)
server.serve_forever()
Errors/Warnings Screenshot
Client.py
import xmlrpc.client
import sys
argumentsList = sys.argv
hostAddress = argumentsList[1]
hostPort = argumentsList[2]
URI = "http://" + hostAddress + ":" + hostPort
num1 = int(argumentsList[3])
num2 = int(argumentsList[4])
proxy = xmlrpc.client.ServerProxy(URI)
print('{} + {} is {}'.format(num1, num2, proxy.add(num1, num2)))
print('{} - {} is {}'.format(num1, num2, proxy.sub(num1, num2)))
print('{} * {} is {}'.format(num1, num2, proxy.mul(num1, num2)))
print('{} / {} is {}'.format(num1, num2, proxy.div(num1, num2)))
print(proxy.name())
print(proxy.help())
print(proxy.serverTime())
Any assistance with this would be most appreciated.

There was many bugs in both your server.py and client.py. I rewrote the files with bug corrected.
server.py:
import sys
import time
from xmlrpc.server import SimpleXMLRPCServer
argumentList = sys.argv
hostAddress = '0.0.0.0'
port = '12345'
server = SimpleXMLRPCServer((hostAddress, int(port)))
def addition(x, y):
return x + y
def subtraction(x, y):
return x - y
def multiplication(x, y):
return x * y
def division(x, y):
try:
return x / y
except ZeroDivisionError:
return "To Infinity and Beyond! Whee!"
def name():
return hostAddress
def helpMe():
return server.system_listMethods()
def serverTime():
return time.strftime("%H:%M:%S")
server.register_function(name)
server.register_function(helpMe)
server.register_function(addition)
server.register_function(serverTime)
server.register_function(subtraction)
server.register_function(multiplication)
server.register_function(division)
server.serve_forever()
client.py
import xmlrpc.client
import sys
argumentsList = sys.argv
hostAddress = '127.0.0.1'
hostPort = '12345'
URI = "http://" + hostAddress + ":" + hostPort
num1 = int('7')
num2 = int('5')
proxy = xmlrpc.client.ServerProxy(URI)
print('{} + {} is {}'.format(num1, num2, proxy.addition(num1, num2)))
print('{} - {} is {}'.format(num1, num2, proxy.subtraction(num1, num2)))
print('{} * {} is {}'.format(num1, num2, proxy.multiplication(num1, num2)))
print('{} / {} is {}'.format(num1, num2, proxy.division(num1, num2)))
print(proxy.name())
print(proxy.helpMe())
print(proxy.serverTime())
Good luck

Related

Python class and objects within another function

I’m trying to learn how to utilize class and objects within my Python code. I'm totally overwhelmed by the fact that is is suppose to be a begginingers class and I got this assignment where if something like this:
Class name is IPAdress and there I want properties IP, hostname, ASN and ISP. Also, it has a method which creates similar print like this:
IP: 85.76.129.254
Hostname: 85-76-129-254-nat.elisa-mobile.fi
ASN: 719
ISP: Elisa Mobile
Method can be named as PrintDetails.
Once the class is ready, I want to use it within my Osio9 function as following
Function asks user to input IP, hostname, ASN and ISP. Object is created according to this information.
Object is added to list (initially empty) and information is printed by using the PrintDetails -method
After this user is asked if he/she wants to create a new IP and if answer is yes -> repeat the above process (ask for input), add the new object to a list and print all information from the list with PrintDetails
After input, the list is looped through and it calls each IPAddress object with PrintDetails -method. (Print can look like the example above)
If user doesn’t want to continue inputting IP-addresses, exit the function
I have no clue how to proceed and answer I receive from my teacher is to look from google so here I am.
class IPAddress: ##define class
def __init__(self, IP, hostname, ASN, ISP):
self.ip = ip
self.hostname = hostname
self.asn = asn
self.isp = isp
def PrintDetails(self): ## construction method
print("IP-address: " + str(self.ip) + " | Hostname: " + str(self.hostname) + " | ASN: " + str(self.asn) + "ISP: " + str(self.isp))
def Osio9():
addresses = []
while(true):
ip = str (input("Enter IP address: ")) #ask for user input
hostname = str (input("Enter Hostname: "))
asn = str (input("Enter ASN: "))
isp = str (input("Enter ISP: "))
address = IPAddress
address.isp = isp
addresses.append(address)
for IPAddress in addresses:
IPAddress.PrintDetails(self)
# continueInput = str (input("Do you want to add more IP-addresses (y/n): "))
# if (continueInput == "y"):
# return addresses
#
# else break
I just saw your last update and there are some good ideas in it. Here is one version of the program, which does not completely correspond to your assignment as the main execution is not within a loop but in a if __name__ == '__main__': statement which will execute only when the program is called directly, and not when it is imported or when function part of this program are imported. I highly encourage you to try a small part of the code, one at a time, and then to adapt it to your specific need.
Let's go piece by piece:
#%% Definition of IPAddress
class IPAddress:
def __init__(self, ip, hostname, asn, isp):
self.ip = ip
self.hostname = hostname
self.asn = asn
self.isp = isp
def prettyprint(self):
str2print = f' | IP: {self.ip}\n' +\
f' | Hostname: {self.hostname}\n' +\
f' | ASN: {self.asn}\n' +\
f' | ISP: {self.isp}\n'
print (str2print)
def __key(self):
"""
key method to uniquely identify an object IPAddress.
I defined it as a tuple of the 4 main attributes, but if one of them is
unique it could be directly used as a key.
"""
return (self.ip, self.hostname, self.asn, self.isp)
def __eq__(self, other):
""" == comparison method."""
return isinstance(self, type(other)) and self.__key() == other.__key()
def __ne__(self, other):
""" != comparison method."""
return not self.__eq__(other)
def __hash__(self):
"""Makes the object hashable. Sets can now be used on IPAddress."""
return hash(self.__key())
I am using spyder as an IDE, and the symbol #%% creates sections of code, very similar to matlab, which can be executed in the current console by doing Right-Click -> Run Cell.
I changed the print function to make it more explicit. Strings object can be denoted by 3 symbols: 'str', "str", """str""". Additionnaly, a flag in front can change the behavior of the string. The most usefull ones are f and r.
Formatting a string with either .format() method or the f flag.
value = 1
str1 = 'string to format with value v = {}'.format(value)
str2 = f'string to format with value v = {value}'
You can print both string to see that they are equivalent. The flag f is similar to a .format() call. It allows the element within the brackets {} to be executed before the print. It is especially usefull when you format a string with multiple values.
v1 = 1
v2 = 2
str1 = 'string to format with value v = {} and {}'.format(v1, v2)
str2 = f'string to format with value v = {v1} and {v2}'
I still chose to split the sring into 4 strings and to add them together for a cleaner look of the code. The backslash \ at the end of each line allows python to consider the current line and the next one as the same line. It's a line-split character.
N.B: If you want to know what the flag r does, look into the escape character ;) r flag is especially usefull when working with paths.
Objects can be compared together. For instace, if you try 5==3, python will return False because the integer object 5 is different from the integer object 3. You can implement the == and != method in any object/class you develop. To do so, I first define a unique key for this object in the function __key(). Then the function __eq__ implements == and returns True if both objects compared are created from the same class and have the same key. The method __ne__ implements != and returns True if __eq__ is not True.
N.B: I also added the hash method to make the object hashable. Once the key is define, creating a hash is trivial, since the idea is to be able to uniquely identify each object, which is also done by the key. This definition allows the use of sets, for instance to check if a list has multiple occurence of the same object.
def add_IPAddress(ListOfIPAddresses, IPAddress):
"""
Function adding IPAddress to ListOfIPAddresses if IPAddress is not already
in ListOfIPAddresses.
"""
if IPAddress not in ListOfIPAddresses:
ListOfIPAddresses.append(IPAddress)
print ('IP Address appended:')
IPAddress.prettyprint()
def input_IPAddress():
"""
Ask a user input to create an IPAddress object.
"""
ip = input("Enter IP address: ")
hostname = input("Enter Hostname: ")
asn = input("Enter ASN: ")
isp = input("Enter ISP: ")
return IPAddress(ip, hostname, asn, isp)
Then I splitted the input from the user and the addition to a list of objects into 2 different functions. The function input() already returns a string, thus I removed the str() call to convert.
N.B: Watchout when asking users to input numbers, usually you forget that the input is a string and then your code raises an error because you forget to convert the string to integer or float.
Improvements: I didn't do it here, but usually when using user input, you have to check if the input given is correct. Some simple syntax checks (e.g. the number of '.' characters in the ipadress) can already improve the robustness of a piece of code. You could also use regular expressions with regex to check if the input is conform.
The query_yes_no() is a clean yes/no util which I copied from somewhere.. I usually place it in a util module: folder within the environment path named util with a __init__.py file. More information if you look into the creation of python module.
#%% Main
if __name__ == '__main__':
ListOfIPAddresses = list()
while True:
if not query_yes_no('Do you want to input IP Address?'):
break
ListOfIPAddresses.append(input_IPAddress())
for ipaddress in ListOfIPAddresses:
ipaddress.prettyprint()
print ('--------------------------') # Just pretting a separator
Finally, in the main part, an infinite while loop is broke only if the user replies no (or any of the other negative keyworkds defined in query_yes_no()). Until it is broken, the user will be asked to add a new IPAddress to the list ListOfIPAddresses which will be added if it is not already present inside.
Full code snippet:
# -*- coding: utf-8 -*-
import sys
#%% Definition of IPAddress
class IPAddress:
def __init__(self, ip, hostname, asn, isp):
self.ip = ip
self.hostname = hostname
self.asn = asn
self.isp = isp
def prettyprint(self):
str2print = f' | IP: {self.ip}\n' +\
f' | Hostname: {self.hostname}\n' +\
f' | ASN: {self.asn}\n' +\
f' | ISP: {self.isp}\n'
print (str2print)
def __key(self):
"""
key method to uniquely identify an object IPAddress.
I defined it as a tuple of the 4 main attributes, but if one of them is
unique it could be directly used as a key.
"""
return (self.ip, self.hostname, self.asn, self.isp)
def __eq__(self, other):
""" == comparison method."""
return isinstance(self, type(other)) and self.__key() == other.__key()
def __ne__(self, other):
""" != comparison method."""
return not self.__eq__(other)
def __hash__(self):
"""Makes the object hashable. Sets can now be used on IPAddress."""
return hash(self.__key())
#%% Functions
def add_IPAddress(ListOfIPAddresses, IPAddress):
"""
Function adding IPAddress to ListOfIPAddresses if IPAddress is not already
in ListOfIPAddresses.
"""
if IPAddress not in ListOfIPAddresses:
ListOfIPAddresses.append(IPAddress)
print ('IP Address appended:')
IPAddress.prettyprint()
def input_IPAddress():
"""
Ask a user input to create an IPAddress object.
"""
ip = input("Enter IP address: ")
hostname = input("Enter Hostname: ")
asn = input("Enter ASN: ")
isp = input("Enter ISP: ")
return IPAddress(ip, hostname, asn, isp)
#%% Util
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
#%% Main
if __name__ == '__main__':
ListOfIPAddresses = list()
while True:
if not query_yes_no('Do you want to input IP Address?'):
break
ListOfIPAddresses.append(input_IPAddress())
for ipaddress in ListOfIPAddresses:
ipaddress.prettyprint()
print ('--------------------------') # Just pretting a separator

How can I specify a class method as a callback target in Python?

I'm using the sftp module of paramiko to transfer payloads to remote hosts. Part of the sftp.put call allows for specifying a callback method with signature func(int,int). I'm trying to put a transfer stats method into my Connection class to keep track of payload progress.
Here's the class I have currently:
class Connection:
def __init__(self, endpoint, RSAKeyObj):
self.displayHost = bcolors.OKGREEN + endpoint + bcolors.ENDC
self.transport = paramiko.Transport((endpoint,4022))
self.transport.connect(username='transit', pkey=RSAKeyObj)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
try:
# initial sftp directory setup
log.info('[{0}]: Setting up remote directories...'.format(self.displayHost))
log.info(self.sftp.mkdir(JAIL_DIR))
except:
pass
def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate
#static_vars(counter=0)
def TransferStats(self, transferedBytes, totalBytes):
if (transferedBytes / totalBytes) >= TransferStats.counter:
log.info('Transferred: {}% [{}/{}]'.format(round((transferedBytes/totalBytes)*100,2), transferedBytes, totalBytes))
TransferStats.counter += 0.025
def Transmit(self,targetDir, payloadPath):
displayText = 'Transferring package {}...'.format(payloadPath)
self.TransferStats().counter=0
log.info('[%s] ' % self.displayHost + displayText)
log.info(self.sftp.put(payloadPath, '%s/%s' % (targetDir,payloadPath), callback=self.TransferStats()))
However when I try this, I get the following error:
ERROR - (, TypeError('TransferStats() takes exactly 3 arguments (1 given)',), )
This makes me think that the callback isn't getting recognized by paramiko when it tries to send it's (int,int) because of the self declaration. Is there a way around this?
Your problem is in :
log.info(self.sftp.put(payloadPath, '%s/%s' % (targetDir,payloadPath), callback=self.TransferStats()))
Your error :
ERROR - (, TypeError('TransferStats() takes exactly 3 arguments (1 given)',), )
Is caused by calling TransferStats with no arguments (self.TransferStats() will result in 1 argument : the class (as it is a class method))
Just pass the classmethod:
log.info(self.sftp.put(payloadPath, '%s/%s' % (targetDir,payloadPath), callback=self.TransferStats))
EDIT : You have the same problem in the following line :
self.TransferStats().counter=0
Remove the parentheses :
self.TransferStats.counter=0
Also, your counter attribute on TransferStats is a hidden a global, resetted at each Transmit call.

Transferring File over TCP using Python

I am new to python and finding it really difficult trying to understand how to send files using sockets with a tcp connection
i found this code in another question that seems to be useful
Client Side
def _sendFile(self, path):
sendfile = open(path, 'rb')
data = sendfile.read()
self._con.sendall(encode_length(len(data))) # Send the length as a fixed size message
self._con.sendall(data)
# Get Acknowledgement
self._con.recv(1) # Just 1 byte
Server Side
def _recieveFile(self, path):
LENGTH_SIZE = 4 # length is a 4 byte int.
# Recieve the file from the client
writefile = open(path, 'wb')
length = decode_length(self.con.read(LENGTH_SIZE) # Read a fixed length integer, 2 or 4 bytes
while (length):
rec = self.con.recv(min(1024, length))
writefile.write(rec)
length -= sizeof(rec)
self.con.send(b'A') # single character A to prevent issues with buffering
Now i have two problems with this code
First
self._con.sendall(encode_length(len(data)))
in this line it gives me an error saying encode_length is undefined
Secondly these are functions that send and receive file
Where do i call them
Do i first form a TCP Connection and then call these functions
And how exactly to call them , if i call them directly it gives me an error on client side saying _sendFile(self, path) takes two arguments (since i am not passing self just the path)
Thirdly i am using function from os library to get complete path , So i am calling the function like
_sendFile(os.path.abspath("file_1.txt"))
is this the correct way to pass the argument
Sorry i know this question is pretty basic and lame but everywhere online i can basically get the function but not how to call it
right now this is how i am calling the function
serverIP = '192.168.0.102'
serverPort = 21000
clientSocket = socket(AF_INET, SOCK_STREAM)
message = "Want to Backup a Directory"
clientSocket.connect((serverIP, serverPort))
_sendFile(os.path.abspath("file_1.txt"))
Which is basically wrong
I am using the same computer for both Client and Server
Running Python on Ubuntu using terminal
First problem:
It's because you simply haven't defined functions encode/decode_lenght.
Second problem:
Your function is: def _sendFile(self, path): ....
Do you know how to use self? It is used in the classes. So define it without self, or use classes:
Example:
from socket import *
class Client(object):
def __init__(self):
self.clientSocket = socket(AF_INET, SOCK_STREAM)
def connect(self, addr):
self.clientSocket.connect(addr)
def _sendFile(self, path):
sendfile = open(path, 'rb')
data = sendfile.read()
self._con.sendall(encode_length(len(data))) # Send the length as a fixed size message
self._con.sendall(data)
# Get Acknowledgement
self._con.recv(1) # Just 1 byte
>>> client = Client()
>>> client.connect(("192.168.0.102", 21000))
>>> client._sendFile(os.path.abspath("file_1.txt")) # If this file is in your current directory, you may just use "file_1.txt"
And same (almost) for Server.
Where to define these functions? In the code ofcorse! What should your functions do?
OK, an example:
def encode_length(l):
#Make it 4 bytes long
l = str(l)
while len(l) < 4:
l = "0"+l
return l
# Example of using
>>> encode_length(4)
'0004'
>>> encode_length(44)
'0044'
>>> encode_length(444)
'0444'
>>> encode_length(4444)
'4444'
About self:
Just a little bit:
self redirects to your current object, ex:
class someclass:
def __init__(self):
self.var = 10
def get(self):
return self.var
>>> c = someclass()
>>> c.get()
10
>>> c.var = 20
>>> c.get()
20
>>> someclass.get(c)
20
>>>
How does someclass.get(c) work?
While executing someclass.get(c), we are not creating an new instance of someclass.
When we call .get() from an someclass instance, it automaticly sets self to our instance object. So someclass.get(c) == c.get()
And if we try to do someclass.get(), self was not defined, so it will raise an error:
TypeError: unbound method get() must be called with someclass instance as first argument (got nothing instead)
You can use decorator to call functions of a class (not its instance!):
class someclass:
def __init__(self):
self.var = 10
def get(self):
return 10 # Raises an error
#classmethod
def get2(self):
return 10 # Returns 10!
Sorry for my bad explanations, my English is not perfect
Here are some links:
server.py
client.py

Python error : X() takes exactly 1 argument (8 given)

I'm trying to bulid an Anonymous FTP scanner , but i got an error about calling function X , i defined X to recieve ony 1 arguement which is the ip address , the same code works if i don't use the loop and send the IPs one by one .
The error is : X() takes exactly 1 argument (8 given)
from ftplib import FTP
import ipcalc
from threading import Thread
def X (ip):
try:
ftp = FTP(ip)
x = ftp.login()
if 'ogged' in str(x):
print '[+] Bingo ! we got a Anonymous FTP server IP: ' +ip
except:
return
def main ():
global ip
for ip in ipcalc.Network('10.0.2.0/24'):
ip = str(ip)
t = Thread (target = X, args = ip)
t.start()
main ()
When constructing Thread objects, args should be a sequence of arguments, but you are passing in a string. This causes Python to iterate over the string and treat each character as an argument.
You can use a tuple containing one element:
t = Thread (target = X, args = (ip,))
or a list:
t = Thread (target = X, args = [ip])

Stopping the Avahi service and return a list of elements

Following this example I want to stop the service when I get all elements and return them in a list.
To stop the infinite loop is to call gobject.MainLoop().quit(), but do not know when or where to call.
Thanks
You'll want to stop the service browsing when the last service for now has arrived. This will give you a snapshot of the current available services.
There is a flag in the C layer allowing you to inspect whether more services are comming shortly. It's called AVAHI_BROWSER_ALL_FOR_NOW. I'm not familiar with the python bindings, but perhaps this flag can be inspected somehow in the stype or flags arguments of the callback?
When you see this flag is set - call gobject.MainLoop().quit()
You'll want to listen to the AllForNow signal as well. Consider CacheExhausted and Failure as well. The interface for org.freedesktop.Avahi.ServiceBrowser is declared here.
Running the following on my machine returns in about a second and prints:
browsing ...
cache exhausted
New service: name = Lexmark X264dn; address = 10.9.0.93; port = 80
that's all for now
done
0:00:01.004258
Hope it helps!
from _dbus_glib_bindings import DBusGMainLoop
import dbus, avahi
import gobject
class ServiceBrowser():
def __init__(self, service):
loop = DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus(mainloop=loop)
self._server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)
browser = self._server.ServiceBrowserNew(avahi.IF_UNSPEC, avahi.PROTO_INET, service, '', 0)
listener = dbus.Interface(bus.get_object(avahi.DBUS_NAME, browser), avahi.DBUS_INTERFACE_SERVICE_BROWSER)
listener.connect_to_signal("ItemNew", self.item_new_handler)
listener.connect_to_signal("ItemRemove", self.item_remove_handler)
listener.connect_to_signal("AllForNow", self.all_for_now_handler)
listener.connect_to_signal("CacheExhausted", self.cache_exhausted_handler)
listener.connect_to_signal("Failure", self.failure_handler)
self._mainloop = gobject.MainLoop()
def service_resolved(self, *args):
print 'New service: name = %s; address = %s; port = %s' % (args[2], args[7], args[8])
def print_error(self, *args):
print 'error_handler'
print args[0]
def item_new_handler(self, interface, protocol, name, stype, domain, flags):
self._server.ResolveService(interface, protocol, name, stype, domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), reply_handler=self.service_resolved, error_handler=self.print_error)
def item_remove_handler(self, interface, protocol, name, stype, domain, flags):
print "Removed service: %s" % name
def all_for_now_handler(self):
print "that's all for now"
self._mainloop.quit()
def cache_exhausted_handler(self):
print "cache exhausted"
def failure_handler(self, error):
print "failure: %s" % error
def browse(self):
self._mainloop.run()
def browse_avahi(service):
browser = ServiceBrowser(service)
browser.browse()
def main():
t0 = datetime.utcnow()
print "browsing ..."
browse_avahi('_http._tcp')
print "done"
print datetime.utcnow()-t0
if __name__ == '__main__':
main()

Categories

Resources