1

I have the following code in my main function:

def main():
    server = socket.socket();
    server.bind((address, port))
    server.listen(1)

    sock, addr = server.accept()
    try:
        while True:
            message = sock.recv(buffer_size)
            # Do some stuff...
            sock.send(answer)
    except KeyboardInterrupt:
        pass
    finally:
        sock.close()
        server.close()

The program runs completely fine, and everything works perfectly, until I decide to end it.

I end my program using Ctrl-C (or ^C). The KeyboardInterrupt exception is getting handled properly and the finally block IS reached, however for some reason when I run the program again, I get an OSError about the port being in use, and I have to wait about 1 minute until the socket gets closed before I can re-run the code. I am on Linux if that matters.

What am I missing here? Why isn't the socket closed properly?

EDIT: This is not a duplicate of How to close a socket left open by a killed program? because in my case the socket was gracefully closed, as opposed to that question.

Community
  • 1
  • 1
Amit Gold
  • 727
  • 7
  • 22
  • How is your code exiting the `while` loop? If you do not break the while loop, your `finally` statement will never be executed – Moinuddin Quadri Dec 18 '16 at 13:20
  • 1
    What you are missing is the TCP TIME-WAIT state which is the state an endpoint sits in after it has sent the last ack but during which the other end, if the ack was lost, might retransmit its last request. –  Dec 18 '16 at 13:38
  • 1
    Possible duplicate of [How to close a socket left open by a killed program?](http://stackoverflow.com/questions/5875177/how-to-close-a-socket-left-open-by-a-killed-program) – mark4o Dec 18 '16 at 13:44
  • @tfb This fits more as an answer, together with the solution from the linked question... I will do it myself, no worries, give me a min :) – Amit Gold Dec 18 '16 at 13:55

1 Answers1

4

This is because the socket is left in the TCP TIME-WAIT state, which is the state an endpoint sits in after it has sent the last ack but during which the other end, if the ack was lost, might retransmit its last request. (As tfb said).

In order to fix that, this code needs to be inserted before the bidding of the socket:

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Amit Gold
  • 727
  • 7
  • 22