[code.view]

[top] / python / PyMOTW / zlib / zlib_server.py

     #!/usr/bin/env python
     # encoding: utf-8
     #
     # Copyright (c) 2008 Doug Hellmann All rights reserved.
     #
     """
     """
     
     #__version__ = "$Id$"
     #end_pymotw_header
     import zlib
     import logging
     import SocketServer
     import binascii
     
     BLOCK_SIZE = 64
     
     class ZlibRequestHandler(SocketServer.BaseRequestHandler):
     
         logger = logging.getLogger('Server')
         
         def handle(self):
             compressor = zlib.compressobj(1)
             
             # Find out what file the client wants
             filename = self.request.recv(1024)
             self.logger.debug('client asked for: "%s"', filename)
             
             # Send chunks of the file as they are compressed
             with open(filename, 'rb') as input:
                 while True:            
                     block = input.read(BLOCK_SIZE)
                     if not block:
                         break
                     self.logger.debug('RAW "%s"', block)
                     compressed = compressor.compress(block)
                     if compressed:
                         self.logger.debug('SENDING "%s"', binascii.hexlify(compressed))
                         self.request.send(compressed)
                     else:
                         self.logger.debug('BUFFERING')
             
             # Send any data being buffered by the compressor
             remaining = compressor.flush()
             while remaining:
                 to_send = remaining[:BLOCK_SIZE]
                 remaining = remaining[BLOCK_SIZE:]
                 self.logger.debug('FLUSHING "%s"', binascii.hexlify(to_send))
                 self.request.send(to_send)
             return
     
     
     if __name__ == '__main__':
         import socket
         import threading
         from cStringIO import StringIO
     
         logging.basicConfig(level=logging.DEBUG,
                             format='%(name)s: %(message)s',
                             )
         logger = logging.getLogger('Client')
     
         # Set up a server, running in a separate thread
         address = ('localhost', 0) # let the kernel give us a port
         server = SocketServer.TCPServer(address, ZlibRequestHandler)
         ip, port = server.server_address # find out what port we were given
     
         t = threading.Thread(target=server.serve_forever)
         t.setDaemon(True)
         t.start()
     
         # Connect to the server
         logger.info('Contacting server on %s:%s', ip, port)
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         s.connect((ip, port))
     
         # Ask for a file
         requested_file = 'lorem.txt'
         logger.debug('sending filename: "%s"', requested_file)
         len_sent = s.send(requested_file)
     
         # Receive a response
         buffer = StringIO()
         decompressor = zlib.decompressobj()
         while True:
             response = s.recv(BLOCK_SIZE)
             if not response:
                 break
             logger.debug('READ "%s"', binascii.hexlify(response))
     
             # Include any unconsumed data when feeding the decompressor.
             to_decompress = decompressor.unconsumed_tail + response
             while to_decompress:
                 decompressed = decompressor.decompress(to_decompress)
                 if decompressed:
                     logger.debug('DECOMPRESSED "%s"', decompressed)
                     buffer.write(decompressed)
                     # Look for unconsumed data due to buffer overflow
                     to_decompress = decompressor.unconsumed_tail
                 else:
                     logger.debug('BUFFERING')
                     to_decompress = None
     
         # deal with data reamining inside the decompressor buffer
         remainder = decompressor.flush()
         if remainder:
             logger.debug('FLUSHED "%s"', remainder)
             buffer.write(reaminder)
         
         full_response = buffer.getvalue()
         lorem = open('lorem.txt', 'rt').read()
         logger.debug('response matches file contents: %s', full_response == lorem)
     
         # Clean up
         s.close()
         server.socket.close()
     

[top] / python / PyMOTW / zlib / zlib_server.py

contact | logmethods.com