Advertisement
Guest User

Untitled

a guest
Nov 28th, 2016
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.83 KB | None | 0 0
  1. # This is the Twisted Get Poetry Now! client, version 1.0.
  2.  
  3. # NOTE: This should not be used as the basis for production code.
  4. # It uses low-level Twisted APIs as a learning exercise.
  5.  
  6. import datetime, errno, optparse, socket
  7.  
  8. from twisted.internet import main
  9.  
  10.  
  11. def parse_args():
  12.     usage = """usage: %prog [options] [hostname]:port ...
  13.  
  14. This is the Get Poetry Now! client, Twisted version 1.0.
  15. Run it like this:
  16.  
  17.  python get-poetry.py port1 port2 port3 ...
  18.  
  19. If you are in the base directory of the twisted-intro package,
  20. you could run it like this:
  21.  
  22.  python twisted-client-1/get-poetry.py 10001 10002 10003
  23.  
  24. to grab poetry from servers on ports 10001, 10002, and 10003.
  25.  
  26. Of course, there need to be servers listening on those ports
  27. for that to work.
  28. """
  29.  
  30.     parser = optparse.OptionParser(usage)
  31.  
  32.     _, addresses = parser.parse_args()
  33.  
  34.     if not addresses:
  35.         print parser.format_help()
  36.         parser.exit()
  37.  
  38.     def parse_address(addr):
  39.         if ':' not in addr:
  40.             host = '127.0.0.1'
  41.             port = addr
  42.         else:
  43.             host, port = addr.split(':', 1)
  44.  
  45.         if not port.isdigit():
  46.             parser.error('Ports must be integers.')
  47.  
  48.         return host, int(port)
  49.  
  50.     return map(parse_address, addresses)
  51.  
  52.  
  53. class PoetrySocket(object):
  54.  
  55.     poem = ''
  56.  
  57.     def __init__(self, task_num, address):
  58.         from twisted.internet import reactor
  59.         self.task_num = task_num
  60.         self.address = address
  61.         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  62.         try:
  63.             self.sock.connect(address)
  64.             self.sock.setblocking(0)
  65.             reactor.addReader(self)
  66.         except socket.error as e:
  67.             print "Error %s, could not connect to %s" % (e, address)
  68.  
  69.         reactor.callLater(3, self.finishjob)
  70.  
  71.     def finishjob(self):
  72.         print "Socket %s timedout!!!" % self.task_num
  73.         self.connectionLost("Timeout!")
  74.  
  75.     def fileno(self):
  76.         try:
  77.             return self.sock.fileno()
  78.         except socket.error:
  79.             return -1
  80.  
  81.     def connectionLost(self, reason):
  82.         self.sock.close()
  83.  
  84.         # stop monitoring this socket
  85.         from twisted.internet import reactor
  86.         reactor.removeReader(self)
  87.  
  88.         # see if there are any poetry sockets left
  89.         for reader in reactor.getReaders():
  90.             if isinstance(reader, PoetrySocket):
  91.                 return
  92.  
  93.         reactor.stop() # no more poetry
  94.  
  95.     def doRead(self):
  96.         bytes = ''
  97.  
  98.         while True:
  99.             try:
  100.                 bytesread = self.sock.recv(1024)
  101.                 if not bytesread:
  102.                     break
  103.                 else:
  104.                     bytes += bytesread
  105.             except socket.error, e:
  106.                 if e.args[0] == errno.EWOULDBLOCK:
  107.                     break
  108.                 return main.CONNECTION_LOST
  109.  
  110.         if not bytes:
  111.             print 'Task %d finished' % self.task_num
  112.             return main.CONNECTION_DONE
  113.         else:
  114.             msg = 'Task %d: got %d bytes of poetry from %s'
  115.             print  msg % (self.task_num, len(bytes), self.format_addr())
  116.  
  117.         self.poem += bytes
  118.  
  119.     def logPrefix(self):
  120.         return 'poetry'
  121.  
  122.     def format_addr(self):
  123.         host, port = self.address
  124.         return '%s:%s' % (host or '127.0.0.1', port)
  125.  
  126. def poetry_main():
  127.     addresses = parse_args()
  128.  
  129.     start = datetime.datetime.now()
  130.  
  131.     sockets = [PoetrySocket(i + 1, addr) for i, addr in enumerate(addresses)]
  132.  
  133.     from twisted.internet import reactor
  134.     reactor.run()
  135.  
  136.     elapsed = datetime.datetime.now() - start
  137.  
  138.     for i, sock in enumerate(sockets):
  139.         print 'Task %d: %d bytes of poetry' % (i + 1, len(sock.poem))
  140.  
  141.     print 'Got %d poems in %s' % (len(addresses), elapsed)
  142.  
  143.  
  144. if __name__ == '__main__':
  145.     poetry_main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement