<p>I'm writing a small web server in Python, using BaseHTTPServer and a custom subclass of BaseHTTPServer.BaseHTTPRequestHandler. Is it possible to make this listen on more than one port?</p>

<p>What I'm doing now:</p>

<pre><code>class MyRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def doGET
  [...]

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): 
    pass

server = ThreadingHTTPServer(('localhost', 80), MyRequestHandler)
server.serve_forever()
</code></pre>

[{'answer_id': 60753, 'author': 'Eli Courtwright', 'author_id': 1694, 'author_profile': 'https://Stackoverflow.com/users/1694', 'pm_score': 6, 'selected': True, 'text': '<p>Sure; just start two different servers on two different ports in two different threads that each use the same handler.  Here\'s a complete, working example that I just wrote and tested.  If you run this code then you\'ll be able to get a Hello World webpage at both <a href="http://localhost:1111/" rel="noreferrer">http://localhost:1111/</a> and <a href="http://localhost:2222/" rel="noreferrer">http://localhost:2222/</a></p>\n\n<pre><code>from threading import Thread\nfrom SocketServer import ThreadingMixIn\nfrom BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler\n\nclass Handler(BaseHTTPRequestHandler):\n    def do_GET(self):\n        self.send_response(200)\n        self.send_header("Content-type", "text/plain")\n        self.end_headers()\n        self.wfile.write("Hello World!")\n\nclass ThreadingHTTPServer(ThreadingMixIn, HTTPServer):\n    daemon_threads = True\n\ndef serve_on_port(port):\n    server = ThreadingHTTPServer(("localhost",port), Handler)\n    server.serve_forever()\n\nThread(target=serve_on_port, args=[1111]).start()\nserve_on_port(2222)\n</code></pre>\n\n<p><em>update:</em></p>\n\n<p>This also works with Python 3 but three lines need to be slightly changed:</p>\n\n<pre><code>from socketserver import ThreadingMixIn\nfrom http.server import HTTPServer, BaseHTTPRequestHandler\n</code></pre>\n\n<p>and</p>\n\n<pre><code>self.wfile.write(bytes("Hello World!", "utf-8"))\n</code></pre>\n'}, {'answer_id': 60754, 'author': 'Douglas Leeder', 'author_id': 3978, 'author_profile': 'https://Stackoverflow.com/users/3978', 'pm_score': 3, 'selected': False, 'text': '<p>Not easily. You could have two ThreadingHTTPServer instances, write your own serve_forever() function (don\'t worry it\'s not a complicated function).</p>\n\n<p>The existing function:</p>\n\n<pre><code>def serve_forever(self, poll_interval=0.5):\n    """Handle one request at a time until shutdown.\n\n    Polls for shutdown every poll_interval seconds. Ignores\n    self.timeout. If you need to do periodic tasks, do them in\n    another thread.\n    """\n    self.__serving = True\n    self.__is_shut_down.clear()\n    while self.__serving:\n        # XXX: Consider using another file descriptor or\n        # connecting to the socket to wake this up instead of\n        # polling. Polling reduces our responsiveness to a\n        # shutdown request and wastes cpu at all other times.\n        r, w, e = select.select([self], [], [], poll_interval)\n        if r:\n            self._handle_request_noblock()\n    self.__is_shut_down.set()\n</code></pre>\n\n<p>So our replacement would be something like:</p>\n\n<pre><code>def serve_forever(server1,server2):\n    while True:\n        r,w,e = select.select([server1,server2],[],[],0)\n        if server1 in r:\n            server1.handle_request()\n        if server2 in r:\n            server2.handle_request()\n</code></pre>\n'}, {'answer_id': 61322, 'author': 'Thomas Vander Stichele', 'author_id': 2900, 'author_profile': 'https://Stackoverflow.com/users/2900', 'pm_score': 3, 'selected': False, 'text': '<p>I would say that threading for something this simple is overkill.  You\'re better off using some form of asynchronous programming.</p>\n\n<p>Here is an example using <a href="http://twistedmatrix.com/" rel="noreferrer">Twisted</a>:</p>\n\n<pre><code>from twisted.internet import reactor\nfrom twisted.web import resource, server\n\nclass MyResource(resource.Resource):\n    isLeaf = True\n    def render_GET(self, request):\n        return \'gotten\'\n\nsite = server.Site(MyResource())\n\nreactor.listenTCP(8000, site)\nreactor.listenTCP(8001, site)\nreactor.run()\n</code></pre>\n\n<p>I also thinks it looks a lot cleaner to have each port be handled in the same way, instead of having the main thread handle one port and an additional thread handle the other.  Arguably that can be fixed in the thread example, but then you\'re using three threads.</p>\n'}]
['https://Stackoverflow.com/questions/60680', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4321/']