Closed socket still in LISTENING and CLOSE_WAIT state after it is closed (Python)

1k views Asked by At

I am opening sockets on my localhost to receive connections from another virtual machine. I want to be able to close the socket/connection when I hit a button, however, even though the socket is closed, it is still in listening/close_wait state.

My code is the following:

def screen_cast(self, emulator_identifier, mode, server_ip, server_port, username):
    global tcp_server_mode_dict
    logging.info('Processing screen cast request on emulator ' + emulator_identifier)
    try:
        # change port so that there's a different one used for every vm ip
        server_port = str(int(server_port) + int(emulator_identifier.split('.')[3].split(':')[0]))
        if mode == "on":
            args = [self.__ADB_EXE, "-s", emulator_identifier, "shell", "am", "startservice", "-a", server_ip + ":" + server_port, "com.conti.its.philipp.screener/.StartScreening"]
            tcp_server_mode_dict[emulator_identifier] = "on"
            logging.info('Starting screencast')
        elif mode == "off":
            args = [self.__ADB_EXE, "-s", emulator_identifier, "shell", "am","force-stop", "com.conti.its.philipp.screener"]
            tcp_server_mode_dict[emulator_identifier] = "off"
            logging.info('Stopping screencast')
        if (mode in ["on", "off"]):
            sp.call(args)
            t = threading.Thread(target=self.screen_cast_service, args=[server_ip, server_port, emulator_identifier, username])
            t.setDaemon(True)
            t.start()
        else:
            return 'failed'
        return tcp_server_mode_dict[emulator_identifier]
    except:
        logging.exception('Invoking screencast on mode ' + mode)
        return 'failed'

def screen_cast_service(self, server_ip, server_port, emulator_identifier, username):
    global tcp_server_mode_dict
    logging.info('Handling screen cast service. Status: ' + tcp_server_mode_dict[emulator_identifier])
    logging.info('Emulator IP: ' + emulator_identifier + ', Port: ' + server_port)
    username_ext = username + "/"
    try:
        # create the dir to store the screenshot if not existing
        if not os.path.exists(settings.DWD_DIR + username + "/screen/"):
            os.makedirs(settings.DWD_DIR + username + "/screen/")

        if not emulator_identifier in tcp_sockets:
            s = socket.socket()
            tcp_sockets[emulator_identifier] = s 

        if tcp_server_mode_dict[emulator_identifier] == "on":
            tcp_sockets[emulator_identifier].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            ADDR = (server_ip, int(server_port))

            tcp_sockets[emulator_identifier].bind(ADDR)
            tcp_sockets[emulator_identifier].listen(10)

            while (tcp_server_mode_dict[emulator_identifier] == "on"):

                ss, address = tcp_sockets[emulator_identifier].accept()
                logging.info("Got Connection from: " + address[0])

                with open(settings.DWD_DIR + username + "/screen/" + 'screen.png', 'wb') as f:
                    while True:
                        data = ss.recv(1024)
                        if not data:
                            break
                        f.write(data)

        elif tcp_server_mode_dict[emulator_identifier] == "off":
            tcp_sockets[emulator_identifier].close()
            del tcp_sockets[emulator_identifier]

    except Exception as e:
        logging.exception('ScreenCast Server')

When I check for open ports, the following shows up:

$ sudo lsof -i :9448
COMMAND     PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Python    17930 philipp   12u  IPv4 0x6c021ad25d0cb947      0t0  TCP 192.168.56.1:9448 (LISTEN)
Python    17930 philipp   14u  IPv4 0x6c021ad2535e9947      0t0  TCP 192.168.56.1:9448->192.168.56.1:52964 (CLOSE_WAIT)
VBoxHeadl 17963 philipp   35u  IPv4 0x6c021ad26bfaa567      0t0  TCP 192.168.56.1:52964->192.168.56.1:9448 (FIN_WAIT_2)

This doesn't throw an error or anything but when I wan't to turn the service back on again and create another socket, I get an error that the address is already used.

Can anybody help? Thanks in advance!

0

There are 0 answers