I'm about to do a simple testimplementation to use PagSeguro (brazilian "PayPal"), and for this I downloaded their Python server to do tests on my localhost. I work on a Mac, have a XAMPP server (Apache and MySQL parts on during my process).
My problem should be very simple for someone who knows Python and sockets etc, and I did found a lot of clues in my information searches. However - with my own poor knowledge in this area, I wasn't able to put two and two together to fix it.
Short question: How do I free a socket (from Terminal) whos program quit before it had closed the socket. Alt - how do I make a Python function for me to call when I want to close the socket and stop/restart the server.
Scenario: I start the server (In terminal with #: sudo python ./PagSeguroServer.py) and it works fine, I did some of the tests I wanted to. Then, I needed to change some settings for the server, and to make it work i need to restart the server. I resolved by closing the terminal window, but then when I reopen and type the same command to start the server again I get the "socket.error: [Errno 48] Address already in use". Ok I can see why but not how to fix, so I Google that, and find the tip to add
socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
in the code. Looked at the Python class and tried to put it there to my best knowledge (as below). However, didn't solve my problem. Since my "search and puzzle" doesnt seem to be able to help me - I'm now giving it up and posting this customized question instead!
This is part of the server code:
class SecureHTTPServer(HTTPServer):
'''Servidor HTTPS com OpenSSL.'''
def __init__(self, server_address, HandlerClass,fpem):
BaseServer.__init__(self, server_address, HandlerClass)
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file (fpem)
ctx.use_certificate_file(fpem)
self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
self.socket_type))
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_bind()
self.server_activate()
....
def run(HandlerClass = HTTPSHandler, ServerClass = SecureHTTPServer):
'''Roda o servidor'''
server_address = ('', 443) # (address, port)
httpd = ServerClass(server_address, HandlerClass, fpem)
httpd.serve_forever()
if __name__ == '__main__':
run()
Note: One time I actually did managed to reopen it - it was before I added the setsockopt call, and I got the feeling that the socket had closed after a timeout - read about that somewhere. This however doesn't seem to happen again - have waited and tried several times.
Edit: In the end this is how I resolved: Needed to kill the python process that was holding the socket (see comment on jd's answer), then added the KeyboardInterrupt catch to be able to close the socket correctly. Thanks all!