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!