Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Async (non-twisted) poetry server
- """
- import datetime, errno, optparse, select, socket, os, time, traceback, sys
- def parse_args():
- usage = """usage: %prog [options] [hostname]:port ...
- This is the Get Poetry Now! server, ASYNC edition.
- Run it like this:
- python my-server-5.py--host=host --port=port poetry_file
- If you are in the base directory of the twisted-intro package,
- you could run it like this:
- python my-server/my-server-5.py --host localhost --port 10080 path/to/file
- """
- parser = optparse.OptionParser(usage)
- help = "The port to listen on. Default to a random available port."
- parser.add_option('--port', type='int', help=help)
- help = "The interface to listen on. Default is localhost."
- parser.add_option('--host', help=help, default='localhost')
- help = "The number of seconds between sending bytes."
- parser.add_option('--delay', type='float', help=help, default=.1)
- help = "The number of bytes to send at a time."
- parser.add_option('--num-bytes', type='int', help=help, default=10)
- options, args = parser.parse_args()
- if len(args) != 1:
- parser.error('Provide exactly one poetry file.')
- poetry_file = args[0]
- if not os.path.exists(args[0]):
- parser.error('No such file: %s' % poetry_file)
- return options, poetry_file
- def send_poetry(sock, addr, inputf, clients, clients_delete_queue, num_bytes = 100, delay = 0.1):
- """Send some poetry slowly down the socket."""
- bytes = inputf.read(num_bytes)
- if not bytes: # no more poetry :(
- print 'Close %s (ok)' % (addr,)
- return sending_finished(sock, addr, inputf, clients, clients_delete_queue)
- try:
- print 'Sending %d bytes to %s' % (len(bytes), addr,)
- sock.sendall(bytes) # this is a blocking call
- time.sleep(delay)
- return
- except socket.error:
- print 'Close %s (error)' % (addr,)
- return sending_finished(sock, addr, inputf, clients, clients_delete_queue)
- def sending_finished(sock, addr, inputf, clients, clients_delete_queue):
- clients_delete_queue.append(addr[1])
- clients.remove(sock)
- sock.close()
- inputf.close()
- return
- def serve(listen_socket, poetry_file, server, clients):
- clients_additional_data = {}
- clients_delete_queue = []
- while True:
- try:
- inputready, outputready, _ = select.select(server, clients, [])
- except select.error, e:
- print 'select error', e
- break
- except socket.error, e:
- #print 'socket error', e
- break
- except ValueError, e:
- print 'ValueError', e, 'server = ', len(server), 'otputs = ', len(clients)
- break
- except KeyboardInterrupt, e:
- print 'KeyboardInterrupt', e
- sys.exit(0)
- break
- except:
- #traceback.print_stack()
- print 'other error = ', sys.exc_info()[0]
- break
- """
- Add new clients
- """
- for s in inputready:
- sock, addr = listen_socket.accept()
- print '-' * 20
- print 'added new client %s' % (addr,)
- print '-' * 20
- clients.append(sock)
- inputf = open(poetry_file)
- clients_additional_data[addr[1]] = (sock, addr, inputf)
- """
- Remove clients if connection loosed
- """
- if len(clients_delete_queue):
- for key in clients_delete_queue:
- print 'delete %s' % (key,)
- del clients_additional_data[key]
- clients_delete_queue = []
- """
- Send data to active clients
- """
- for key in clients_additional_data:
- sock, addr, inputf = clients_additional_data[key]
- send_poetry(sock, addr, inputf, clients, clients_delete_queue)
- def main():
- opts, poetry_file = parse_args()
- server = []
- clients = []
- print 'Server started %s:%d/%s' % (opts.host, opts.port, poetry_file)
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- sock.bind((opts.host, opts.port))
- #sock.setblocking(0)
- sock.listen(5)
- print 'Serving on port %s.' % (sock.getsockname()[1])
- server.append(sock)
- while True:
- serve(sock, poetry_file, server, clients)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement