Reputation: 171
I am new to Python socket server programming, I am following this example to setup a server using the socketserver framework. Based on the comment, pressing Ctrl-C will stop the server but when I try to run it again, I get
OSError: [Errno 98] Address already in use
which makes me have to kill the process manually using the terminal.
Based on my understanding, KeyboardInterrupt is considered one type of exception in Python, and when an exception happens in a with
block, Python will also call the __exit__()
function to clean up. I have tried to create a __exit__()
function in the TCP hanlder class but that does not seems to fix the problem.
Does anyone know a way to unbind the socket when an exception is raised?
server.py
import socketserver
from threading import Thread
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
# Self-written function to try to make Python close the server properly
def __exit__(self):
shutdown_thread = Thread(target=server.shutdown)
shutdown_thread.start()
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
Upvotes: 2
Views: 694
Reputation: 1994
As @Tim Roberts explained that it's an artifact of TCP. Aside from his method you can also manually pass the SO_REUSEADDR
flag by using
socket.setsockopt(socket.SO_REUSEADDR)
This might be useful when you're passing multiple socketopt
s or when you want something more familiar to low level networking in C.
Upvotes: 1
Reputation: 54718
This is not a Python thing, this is an artifact of TCP. A socket that seems to be closed is actually left in a partially open state even after the application has died. To get around that, use
socketterver.TCPServer.allow_reuse_address = True
before creating your server. This enables the SO_REUSEADDR socket option that overrides this behavior.
Upvotes: 3