0

This is interesting. I did a simple script to bind and serve http but I hadn't done this in Python3. I can write a simple server:

import http.server
import socketserver

PORT = 8002

Handler = http.server.SimpleHTTPRequestHandler
#https://docs.python.org/3/library/http.server.html
class MyHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, request, client_addr, server):
        super().__init__(request, client_addr, server)
    def do_GET(self, ):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.wfile.write('Hey!'.encode())

httpd = socketserver.TCPServer(("0.0.0.0", PORT), MyHandler)

print("serving at port", PORT)
httpd.serve_forever()

but when I run it, then Ctrl+c, then run it again it says:

OSError: [Errno 98] Address already in use

Why is that if I kill the previous process?

Also, is there any reason other than that that this couldn't be used as a simple, testing webapp for a test server at IP:port/somesamplewebapp - They say "http.server is not recommended for production. It only implements basic security checks." but if it does not need https or extra security... what are the risks?

NoBugs
  • 9,310
  • 13
  • 80
  • 146
  • The operating system prevents the re-use of a port in an address for a couple of minutes, if it's a different PID. You can set the socket option SO_REUSEADDR to remove the check before calling bind() on it. – Keith Apr 11 '20 at 07:36
  • How so?? can you add an answer? – NoBugs Apr 11 '20 at 07:59

1 Answers1

0

The operating system prevents, by default, the reuse of an address by a different PID. You can defeat that with the socket option SO_REUSEADDR. However, since you are using the TCPServer class and it has it's own, different, way of specifying that. You can use this code.


import http.server
import socketserver

PORT = 8002

Handler = http.server.SimpleHTTPRequestHandler

#https://docs.python.org/3/library/http.server.html

class MyHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, request, client_addr, server):
        super().__init__(request, client_addr, server)

    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.wfile.write('Hey!'.encode())


class MyServer(socketserver.TCPServer):
    allow_reuse_address = True  # <-- This is what you need


httpd = MyServer(("0.0.0.0", PORT), MyHandler)

print("serving at port", PORT)

httpd.serve_forever()
Keith
  • 42,110
  • 11
  • 57
  • 76