0
I have a server program using a python socket that has two threads: the Accept thread, responsible for accepting new connections from clients, and the clientThread thread, responsible for handling connections and receiving messages. The clientThread thread is created by the Accept thread - I don’t know if this is a good way to do it.
I am running this application on the console and what I want to do is close the program by pressing CTRL + C. I am using signal.signal
to capture when the user presses CTRL+C and manipulates a variable that indicates that the key combination has been pressed. Also, I’m using the sys.exit()
to terminate the program. However, by pressing CTRL+C, the code interprets that this combination has been pressed, but is not terminated. I have read some similar topics and all indicate the sys.exit()
to end the program, but, it doesn’t work with me. Any idea what I’m doing wrong?
Here is my code:
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)
The
ctrl + c
will kill themain thread
but not the "daughters". Make each daughter onedaemon
with, for examplesua_thread.daemon = True
before doing thestart
– Paulo Marques