can't close socket on KeyboardInterrupt

  1. To break to get out the while loop. Without break, the loop will not end.
  2. To be safe, check whether connection is set.

from socket import socket, AF_INET, SOCK_STREAM

sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
while True:
    connection = None # <---
    try:
        connection, address = sock.accept()
        print("connected from ", address)
        received_message = connection.recv(300)
        if not received_message:
            break
        connection.sendall(b"hello")
    except KeyboardInterrupt:
        if connection:  # <---
            connection.close()
        break  # <---

UPDATE

  • There was a typo: KeyBoardInterrupt should be KeyboardInterrupt.
  • sock.recv should be connection.recv.

Try adding a timeout to the socket, like so:

from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.settimeout(1.0)
sock.listen(1)
while True:
    try:
        connection, address = sock.accept()
        print("connected from " + address)
        received_message = sock.recv(300)
        if not received_message:
            break
        connection.sendall(b"hello")
    except IOError as msg:
        print(msg)
        continue    
    except KeyboardInterrupt:
        try:
            if connection:
                connection.close()
        except: pass
        break
sock.shutdown
sock.close()

I had this issue on Windows. Here's how I handle stopping the process:

    try:
        while self.running:
            try:
                c, addr = self.socket.accept()
                print("Connection accepted from " + repr(addr[1]))
                # do special stuff here...
                print("sending...")
                continue
            except (SystemExit, KeyboardInterrupt):
                print("Exiting....")
                service.stop_service()
                break
            except Exception as ex:
                print("======> Fatal Error....\n" + str(ex))
                print(traceback.format_exc())
                self.running = False
                service.stop_service()
                raise
    except (SystemExit, KeyboardInterrupt):
        print("Force Exiting....")
        service.stop_service()
        raise

def stop_service(self):
    """
    properly kills the process: https://stackoverflow.com/a/16736227/4225229
    """
    self.running = False
    socket.socket(socket.AF_INET,
                  socket.SOCK_STREAM).connect((self.hostname, self.port))
    self.socket.close()

Note that in order to trigger a KeyboardInterrupt exception, use:

Ctrl+Fn+PageUp(Pause/Break)

Tags:

Python

Sockets