closing a "forever" Server Socket

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • alessandro

    closing a "forever" Server Socket

    Hi all,

    This is my framework for create TCP server listening forever on a port
    and supporting threads:


    import SocketServer

    port = 2222
    ip = "192.168.0. 4"
    server_address = (ip, port)

    class ThreadingTCPSer ver(SocketServe r.ThreadingMixI n,
    SocketServer.TC PServer): pass

    class Handler(SocketS erver.BaseReque stHandler):
    def handle(self):
    # my handler

    print "Listening for events at " + ip + ":" + str(port)
    monitor_server = ThreadingTCPSer ver(server_addr ess, Handler)

    try:
    monitor_server. serve_forever()
    except KeyboardInterru pt:
    monitor_server. socket.close()
    print "Bye."


    This server will not run as a daemon and for quitting you have to send
    the SIGINT signal with Ctrl-C. It will rise the KeyboardInterru pt
    exception, during its handling I simply close the socket and print a
    message.

    I want to ask if someone knows a better way for closing a "forever
    server" or if there is a lack in my design.

    Thank you!

    Alessandro

  • Matimus

    #2
    Re: closing a "forever&q uot; Server Socket

    I want to ask if someone knows a better way for closing a "forever
    server" or if there is a lack in my design.
    Generally you don't create a 'forever server'. You create an 'until I
    say stop' server. I would do this by looking at the 'serve_forever'
    method, and implementing my own 'serve_until_?' method that is similar,
    but will stop if a flag is set. Then you have to create a method for
    setting that flag. It could be as simple as a keypress, or you could
    add a quit method to your dispatcher that sets the flag when a certain
    address is visited. That second method probably needs some added
    security, otherwise anybody can just visit 'your.server.co m/quit' and
    shut it down.

    Comment

    • alessandro

      #3
      Re: closing a "forever&q uot; Server Socket

      thanks

      infact the server_forever( ) method is only a serve() method inside an
      infinite loop.

      many thanks again,

      Alessandro

      Matimus ha scritto:
      I want to ask if someone knows a better way for closing a "forever
      server" or if there is a lack in my design.
      >
      Generally you don't create a 'forever server'. You create an 'until I
      say stop' server. I would do this by looking at the 'serve_forever'
      method, and implementing my own 'serve_until_?' method that is similar,
      but will stop if a flag is set. Then you have to create a method for
      setting that flag. It could be as simple as a keypress, or you could
      add a quit method to your dispatcher that sets the flag when a certain
      address is visited. That second method probably needs some added
      security, otherwise anybody can just visit 'your.server.co m/quit' and
      shut it down.

      Comment

      • Laszlo Nagy

        #4
        Re: closing a "forever&q uot; Server Socket

        alessandro írta:
        thanks
        >
        infact the server_forever( ) method is only a serve() method inside an
        infinite loop.
        >
        many thanks again,
        >
        Here is a snipped that show a "software terminateable threading TCP
        socker server". The "server" object is a SocketServer instance,
        server_stopped is a threading.Event instance. You should also import the
        "select" module.

        srvfd = server.fileno()
        while not server_stopped. isSet():
        ready = select.select([srvfd], [], [], 1) # Give one second
        for incoming connection so we can stop the server in seconds
        if srvfd in ready[0]:
        server.handle_r equest()
        else:
        pass # log('No incoming connection, retrying')

        Comment

        • alessandro

          #5
          Re: closing a "forever&q uot; Server Socket

          Oh my God! it's really so complicated?

          3 modules (threading, SocketServer, select) only for design a way to
          shutdown a TCP server????
          ....but they told me that python was easy... :)

          I'm working on a simulator and I have a monitor server that collects
          information. I can shutdown it using Ctrl-C from the keyboard but for
          my purpose could be very nice if I introduce a timer. So I could launch
          my monitor like this:

          ../monitor 100

          and my monitor will run for 100 seconds. For this I'm using the Timer
          class provided by threading module, I have implemented a function like
          this:

          def shutdown():
          sys.exit()

          but it doesen't work because the server remain alive...maybe
          SocketServer create immortal server...
          I need only to close my application, there is a way to force the server
          thread to close?

          thanks!
          Alessandro



          Laszlo Nagy ha scritto:
          alessandro írta:
          thanks

          infact the server_forever( ) method is only a serve() method inside an
          infinite loop.

          many thanks again,
          Here is a snipped that show a "software terminateable threading TCP
          socker server". The "server" object is a SocketServer instance,
          server_stopped is a threading.Event instance. You should also import the
          "select" module.
          >
          srvfd = server.fileno()
          while not server_stopped. isSet():
          ready = select.select([srvfd], [], [], 1) # Give one second
          for incoming connection so we can stop the server in seconds
          if srvfd in ready[0]:
          server.handle_r equest()
          else:
          pass # log('No incoming connection, retrying')

          Comment

          • Laszlo Nagy

            #6
            Re: closing a "forever&q uot; Server Socket

            alessandro írta:
            Oh my God! it's really so complicated?
            >
            3 modules (threading, SocketServer, select) only for design a way to
            shutdown a TCP server????
            ...but they told me that python was easy... :)
            >
            I believe that SockerServer was created for testing purposes, although
            there are some programs using it in production. Yes, Python is easy. The
            language is very clear, and you do not need to install third party
            modules in order to create a server. :-) Of course the easiest way is to
            call serve_forever. Isn't it easy? The other way is to implement your
            own message handling loop. The SocketServer is flexible enough to do
            this; and I don't think it is complicated. 7 lines of code will allow
            you to stop the server safely from anywhere, even from other threads.
            Try to implement the same in C or Delphi...
            but it doesen't work because the server remain alive...maybe
            SocketServer create immortal server...
            I need only to close my application, there is a way to force the server
            thread to close?
            >
            In pure Python, no. Python threads are "cooperativ e". In other words,
            they cannot be terminated from outside. A thread will stop after the
            execution exits its "run" method. (You can, of course terminate the
            tread with an operating system function, but it is not recommended.)


            Here is a class that can be stopped with an event:

            import threading

            stop_requested = threading.Event ()

            class SoftWaitThread( threading.Threa d):
            """SoftWaitThre ad can wait for a given time except if the thread was
            asked
            to terminate itself."""
            def waitsome(self,a mount=10):
            """Wait the specified amount of time.

            This can be terminated by stop_requested within 0.1 seconds."""
            for idx in range(int(10*am ount)):
            time.sleep(0.1)
            if stop_requested. isSet():
            break


            Then you can do this:

            class MyServerThread( SoftWaitThread) :
            def run(self):
            server = MySocketServerC lass()
            srvfd = server.fileno()
            while not stop_requested. isSet():
            ready = select.select([srvfd], [], [], 1)
            if srvfd in ready[0]:

            server.handle_r equest()
            else:
            pass


            And then:

            import time
            def main():
            sth = MyServerThread( ) # Create your thread
            sth.start() # Start handling requests in another thread
            try:
            time.sleep(TIME OUT_IN_SECONDS) # Wait...
            finally:
            stop_requested. set() # Request the server thread to stop itself
            sth.join() # Wait until the server thread stops
            print "Stopped."

            You could start several threads and request them to stop with the same
            event. I hope this helps.

            Laszlo


            p.s.: Not all of the above was tested, be careful.

            Comment

            • Gabriel Genellina

              #7
              Re: closing a "forever&q uot; Server Socket

              At Monday 22/1/2007 14:49, alessandro wrote:
              >Oh my God! it's really so complicated?
              >
              >3 modules (threading, SocketServer, select) only for design a way to
              >shutdown a TCP server????
              >...but they told me that python was easy... :)
              You already have the answer: replace serve_forever with your own loop.
              >I'm working on a simulator and I have a monitor server that collects
              >information. I can shutdown it using Ctrl-C from the keyboard but for
              >my purpose could be very nice if I introduce a timer. So I could launch
              >my monitor like this:
              >./monitor 100
              >
              >and my monitor will run for 100 seconds. For this I'm using the Timer
              This is simple enough, I presume:

              try:
              stopt = time.time()+100
              while time.time()<sto pt:
              server.handle_r equest()
              except KeyboardInterru pt: pass
              # shutdown

              The drawback is that it won't leave the loop until a request arrives,
              but this may not be a problem for you. (Other suggestions are more
              complicated because of this issue.)


              --
              Gabriel Genellina
              Softlab SRL






              _______________ _______________ _______________ _____
              Preguntá. Respondé. Descubrí.
              Todo lo que querías saber, y lo que ni imaginabas,
              está en Yahoo! Respuestas (Beta).
              ¡Probalo ya!


              Comment

              Working...