Search code examples
pythonhttpservertcpserver

TCPServer vs HTTPServer


I am writing a simple python3 webserver. I have tried various tutorials and all work pretty well. Nevertheless there is a difference that I don't understand.

In one tutorial, they use HTTPServer as follows:

server = HTTPServer(('', PORT_NUMBER), myHandler) 
server.serve_forever()

In another tutorial, they use socketserver.TCPServer as follows:

with socketserver.TCPServer(('', PORT_NUMBER), myHandler) as httpd:
    httpd.serve_forever()

What is the difference between both methods? All I need is a simple webserver that is able to receive JSON files through POSTs and aswer with another JSON. In both cases, I would use the same handler:

class myHandler(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        self.wfile.write("{dummy:'dummy'}")

    def do_POST(self):
        # Doesn't do anything with posted data for this example
        self._set_headers()
        self.wfile.write("{dummy:'dummy'}")

Does one of the methods suit my needs better? Is there an even better way of writing this server for my needs?

Thanks for your help and time!


Solution

  • TCP is an OSI Layer 4 transport protocol, whereas HTTP is a higher Layer 7 application protocol, built on top of TCP.

    In fact, it looks like HTTPServer inherits directly from socketserver.TCPServer, according to the documentation:

    One class, HTTPServer, is a socketserver.TCPServer subclass. It creates and listens at the HTTP socket, dispatching the requests to a handler.

    For example, TCP will take care of establishing a connection (the three-way handshake with SYN, SYN-ACK and ACK) but it doesn't really prescribe much in terms of the structure of the data interaction (request/response). If you use the TCP protocol, you'll generally need to write all your own data processing code.

    All I need is a simple webserver that is able to receive JSON files through POSTs and aswer with another JSON

    This suggests the HTTP server is better suited for your need here, as the concept of a POST, and your description of an answer with another JSON is probably going to include a response (with a response body, response headers, and a response status). All of these will be HTTP concepts. As the documentation for http.server. BaseHTTPRequestHandler states, it will include an instance variable called command that is your request method (GET, for instance).

    I can't tell exactly how myhandler is assigned in your example code, but looking at some of the other documentation examples, it looks like a http.server.SimpleHTTPRequestHandler:

    import http.server
    import socketserver
    
    PORT = 8000
    Handler = http.server.SimpleHTTPRequestHandler
    
    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        print("serving at port", PORT)
        httpd.serve_forever()
    

    A frequently pattern of instantiating work for a server appears to be

    1. To instantiate a lower-level protocol server (ie. TCP) and pass in a higher level handler (like http.server.SimpleHTTPRequestHandler), hence the socketserver.TCPServer(("", PORT), myhandler).
    2. To use it within a context manager (with keyword), most likely because you need to tear down / deallocate resources after the server finishes execution.