#!/usr/bin/env python # Module imports import sys import os import time import socket from optparse import OptionParser # Globals for this module opts = None args = None PROFILE = 0 def main(argv=None): global opts # Process command line arguments if argv is None: processOptions(sys.argv[1:]) else: processOptions(argv) listensock = serverSocket(opts) running = True while running: # The basic client loop: accept-process-close clientsock, addr = listensock.accept() if opts.verbose > 0: print 'Connected with %s:%d' % (addr[0],addr[1]) # Get a "request" request = readLine(clientsock) if request != '': # Send a "response" timestr = time.asctime() + '\n' n = clientsock.sendall(timestr) elif opts.verbose > 0: print 'close received by client' clientsock.close() return # Common network functions def serverSocket(opts): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((opts.addr, opts.port)) if opts.reuse: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.listen(opts.backlog) except socket.error, msg: print 'Failed to create/bind socket. Error code: %d, Error message: %s' % (msg[0],msg[1]) sys.exit(1) # Get here on success of try block if opts.verbose > 0: print 'Socket created, bound, and listening' return s def readLine(sock): buffer = '' ch = sock.recv(1) while ch != '\n' and ch != '': buffer += ch ch = sock.recv(1) if ch == '': buffer = '' else: buffer += ch return buffer # Put together all command line options parsing in one place def processOptions(argv): global opts global args try: # setup option parser parser = OptionParser() parser.add_option("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %default]") parser.add_option("-r", "--reuse", dest="reuse", action="store_false", help="set socket to not reuseaddr [default: %default]") parser.add_option("-a", "--addr", dest="addr", action='store', help="set server listen address [default: \"%default\"]") parser.add_option("-p", "--port", dest="port", action='store', type='int', help="set server port number [default: %default]") parser.add_option("-b", "--backlog", dest="backlog", action='store', type='int', help="set server connection backlog [default: %default]") # set defaults parser.set_defaults(verbose=0, reuse=True, addr='', port=6666, backlog=32) # process options (opts, args) = parser.parse_args(argv) except Exception, e: sys.stderr.write("Error processing options; for help use --help") return 2 if opts.verbose > 0: print("verbosity level = %d" % opts.verbose) print("args =", args) if opts.verbose > 0 and opts.reuse: print("reuse = %s" % str(opts.reuse)) if opts.verbose > 0 and opts.addr: print("addr = %s" % opts.addr) if opts.verbose > 0 and opts.port: print("port = %d" % opts.port) if opts.verbose > 0 and opts.backlog: print("backlog = %d" % opts.backlog) if __name__ == "__main__": if PROFILE: import cProfile import pstats profile_filename = '%s.txt' % sys.argv[0] cProfile.run('main()', profile_filename) statsfile = open("%s_stats.txt" % sys.argv[0], "wb") p = pstats.Stats(profile_filename, stream=statsfile) stats = p.strip_dirs().sort_stats('cumulative') stats.print_stats() statsfile.close() sys.exit(0) sys.exit(main())