import signal, sys, threading, time, urllib2 class Client: '''A generic web client; this is the base class for other types of clients having more interesting behaviors. ''' def __init__ (self): self._url = 'http://www.python.org/ftp/python/2.4/Python-2.4.tgz' class WellBehavedClient (Client): '''A well-behaved client. It tries to follow all the HTTP rules properly. ''' def __init__ (self, bandwidth): Client.__init__ (self) self._bandwidth = bandwidth def run (self, iterationLimit=None): '''Run, repeating iterationLimit times. If iterationLimit is None or 0, repeat forever. ''' while True: self.runOnce () if iterationLimit > 0: iterationLimit -= 1 if iterationLimit == 0: break def runOnce (self): '''Fetch one file. ''' sys.stderr.write ('c') connection = urllib2.urlopen (self._url) sys.stderr.write ('C') while True: data = connection.read (self._bandwidth) sys.stderr.write ('.') time.sleep (1.0) # Note granular sleep resolution makes our rate approximate if not data: break def run (clientCount): '''Launch a barrage of clients; each running in its own daemon thread. Return the list of client threads. ''' # Make a list of clients: clients = [WellBehavedClient (64000) for i in range (clientCount)] # Create a list of threads; each thread is poised to execute one of the clients: threads = [threading.Thread (target=client.run, args=()) for client in clients] # Start the threads: for thread in threads: thread.setDaemon (True) thread.start () # Block until all of the threads have finished (or a signal is received): for thread in threads: thread.join (1.0) def main (argv): run (20)