Olá a todos.
Tenho um programa servidor utilizando socket em python que possui duas threads: a thread accept, responsável por aceitar novas conexões dos clientes, e a thread clientThread, responsável por tratar as conexões e receber mensagens. A thread clientThread é criada pela thread accept (não sei se essa é uma boa forma de ser feita).
Estou rodando essa aplicação no console e o que desejo fazer é encerrar o programa ao pressionar CTRL + C. Estou utilizando signal.signal
para capturar quando o usuário pressiona CTRL + C e manipular uma variável que indica que a combinação de teclas foi pressionada e estou utilizando o sys.exit()
para encerrar o programa. No entanto, ao pressionar CTRL + C o código interpreta que essa combinação foi pressionada mas não é encerrado. Já li alguns tópicos semelhantes e todos indicam o sys.exit()
para encerrar o programa, mas ele não funciona comigo. Alguma ideia do que estou fazendo de errado?
Aqui está meu código:
import socket
import select
import sys
import _thread
import json
import threading
import signal
import time
import os
from datetime import datetime
fechada = False
clienteThread = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if len(sys.argv) != 2:
print ("numero da porta?")
exit()
header = 10
listaComandos = ['SEND','SENDTO','WHO','HELP']
aux_ListaSockets = []
# endereco localhost
enderecoIP = "127.0.0.1"
#numero da porta
port = int(sys.argv[1])
#liga o servidor no localhost e na porta especificada
server.bind((enderecoIP, port))
#no maximo 20 conexoes ativas
server.listen(20)
listaDeSockets = [server]
# fim da configuracao do servidor
listaDeClientes = []
# Função para o tratamento das mensagens
def _message(client_socket):
try:
message_header = client_socket.recv(header)
if not len(message_header):
return False
message_length = int(message_header.decode('utf-8').strip())
return {'header': message_header, 'data': client_socket.recv(message_length)}
except:
return False
def clientThread(sockCliente, endereco):
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
usuario = _message(sockCliente)
#Checando se o usuário já existe
usuario_decode = usuario['data'].decode('utf-8')
if usuario_decode in listaDeClientes:
str_fechamento = "recusada".encode('utf-8')
sockCliente.send(str_fechamento)
sockCliente.close()
else:
str_fechamento = "aceita".encode('utf-8')
sockCliente.send(str_fechamento)
print(data_hora + '\t'+ usuario['data'].decode('utf-8') + '\t' +'Conectado')
listaDeClientes.append(usuario_decode)
aux_ListaSockets.append(sockCliente)
while True:
try:
if fechada:
sys.exit(0)
break
message = sockCliente.recv(2048)
#print(message.decode('UTF-8'))
if message:
if 'SEND' in message.decode("UTF-8") and ('SENDTO' not in message.decode("UTF-8")):
msg = message.decode("UTF-8")
if " " in msg:
msg = msg.replace("SEND","")
if not msg or ('SEND' in msg):
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SEND\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SEND\t' + 'Executado: Sim')
print(usuario_decode + ' diz: ' + msg)
sockCliente.send("executada".encode('utf-8'))
elif 'SENDTO' in message.decode("UTF-8"):
msg = message.decode("UTF-8")
if " " in msg:
msg = msg.replace("SENDTO","")
if not msg or ('SENDTO' in msg):
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SENDTO\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'SENDTO\t' + 'Executado: Sim')
destino = msg.split()[0]
if destino in listaDeClientes:
indexDestino = listaDeClientes.index(destino)
socketDestino = aux_ListaSockets[indexDestino]
message_sendto = 'mensagem->' + usuario_decode + ' diz: ' + msg.split()[1]
socketDestino.send(message_sendto.encode('utf-8'))
sockCliente.send("cliente existe".encode('utf-8'))
else:
sockCliente.send("cliente não existe".encode('utf-8'))
elif 'WHO' == message.decode("UTF-8"):
msg = message.decode("UTF-8")
if not msg:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'WHO\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'WHO\t' + 'Executado: Sim')
msg = json.dumps(listaDeClientes).encode()
sockCliente.send(msg)
elif 'HELP' == message.decode("UTF-8"):
msg = message.decode("UTF-8")
if not msg:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'HELP\t' + 'Executado: Não')
sockCliente.send("nao_executada".encode('utf-8'))
else:
data_atual = datetime.now()
data_hora = data_atual.strftime('%H:%M')
print(data_hora + '\t' + usuario_decode + '\t' + 'HELP\t' + 'Executado: Sim')
msg = json.dumps(listaComandos).encode()
sockCliente.send(msg)
elif message:
sockCliente.send("comando não existe".encode('utf-8'))
else:
remove(sockCliente)
except:
break
def signal_handler(arg1, arg2):
global fechada
fechada = True
def acceptConnection():
while True:
if fechada:
for cliente in clienteThread:
cliente.join()
sys.exit(0)
break
else:
cliente_socket, enderecoIpDoCliente = server.accept()
listaDeSockets.append(cliente_socket)
cliente = threading.Thread(target=clientThread, args=(cliente_socket, enderecoIpDoCliente))
cliente.daemon = True
clienteThread.append(cliente)
cliente.start()
accept = threading.Thread(target=acceptConnection, args=())
accept.start()
while True:
signal.signal(signal.SIGINT, signal_handler)
if fechada:
accept.join()
sys.exit(0)