1
I have a Python App that uses Socket, this App runs on XBMC’s Kodi, and when I close the App I would like to close the Socket and take down customers, the problem is that even I using shutdown(socket.SHUT_RDWR)
and close()
in the client the Socket is open occupying the port, the Socket is only closed if the client also closes the connection. In all languages I have worked with Socket (C++, Java, PHP and Swift), if the Host closes the connection everyone falls. But in Python it’s different, I wonder what I have to do to kill the connection.
Python script:
import sys
import socket
import xbmcgui
import xbmc
import thread
import json
class GUI(xbmcgui.WindowXML):
def onInit(self):
# start socket server
self.running = True
xbmc.log("Inciando server")
# thread client users
self.users = [];
# get exit ids
self.action_exitkeys_id = [10, 13]
# get control ids
self.texto = 30
self.conteudo = 31
self.logo = 32
self.erro = 33
# get control instance
self.texto_label = self.getControl(self.texto)
self.conteudo_label = self.getControl(self.conteudo)
self.logo_img = self.getControl(self.logo)
self.erro_img = self.getControl(self.erro)
self.texto_label.setLabel("")
self.conteudo_label.setLabel("")
self.logo_img.setVisible(True)
self.erro_img.setVisible(False)
try:
thread.start_new_thread( self.server_listerner, () )
except:
xbmc.log( "Error: unable to start thread" )
def onAction(self, action):
xbmc.log(str(action.getId()))
if action.getId() == 10 :
xbmc.log("Tentando fechar conexao");
self.running = False
for user in self.users :
xbmc.log("Matando Cliente");
user.shutdown(socket.SHUT_RDWR);
user.close();
del user
del self.users
try :
tmp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tmp.connect( self.server_address )
tmp.close();
del tmp
except :
xbmc.log("Conexao ja fechada!")
self.close()
def parseJson(self, json_string):
xbmc.log(json_string)
data = json.loads(json_string)
if data["command"] == "setText" :
self.logo_img.setVisible(False)
self.texto_label.setLabel(data["param1"])
self.conteudo_label.setLabel(data["param2"])
if data["command"] == "clean" :
self.logo_img.setVisible(True)
self.texto_label.setLabel("")
self.conteudo_label.setLabel("")
if data["command"] == "play" :
xbmc.Player().pause()
if data["command"] == "pause" :
xbmc.Player().pause()
def server_listerner(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_address = ('localhost', 9191)
try:
self.sock.bind(self.server_address)
except Exception, e:
self.erro_img.setVisible(True)
return
self.sock.listen(1)
while self.running:
# Wait for a connection
connection, client_address = self.sock.accept()
self.users.append(connection);
try:
#xbmc.log( 'connection from ' + client_address )
# Receive the data in small chunks and retransmit it
while True:
data = connection.recv(4096)
#xbmc.log( 'received "%s"' % data )
if data:
#xbmc.log( 'sending data back to the client' )
self.parseJson(data)
else:
xbmc.log( 'no more data from' )
break
except:
xbmc.log("Cliente deu pau")
connection.shutdown(socket.SHUT_RDWR);
connection.close()
del connection
continue;
xbmc.log("Matando cliente")
#connection.shutdown(socket.SHUT_RDWR);
connection.close()
del connection
xbmc.log("fechando conexao");
self.sock.shutdown(socket.SHUT_RDWR);
self.sock.close()
del self.sock