Я пишу базовый клиент / сервер UDP и хотел бы, чтобы сервер перехватывал ctrl-c / SIGINT. Сигнал не улавливает сигнал, и мой код соответствует 10+ примерам, которые я видел, которые делают это. Когда я нажимаю ctrl-c, программа закрывается и не печатает из обработчика, и, очевидно, не закрывает порт изящно.
Я везде искал, чтобы попытаться найти кого-то, у кого была такая же проблемано безрезультатно. Я попытался поставить вызов signal.signal () в разных местах, опять же безрезультатно.
import socket
import sys
import operator
import signal
from sys import exit
import re
def handler(signal_received, frame):
# Handle any cleanup here
print('SIGINT or CTRL-C detected. Exiting gracefully')
try:
sock.close()
print ("Socket Closed.")
except Exception as e:
print ("Socket not open. ")
finally:
exit(0)
ops = { "+": operator.add, "-": operator.sub, "/": operator.truediv, "*": operator.mul }
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind the socket to the port
server_address = ('localhost', 10000)
print ('starting up on %s port %s' % server_address)
sock.bind(server_address)
badResponse = "Status: 300, Result: -1"
badResponse = badResponse.encode()
signal.signal(signal.SIGINT, handler)
while True:
print ('\nwaiting to receive message')
data, address = sock.recvfrom(4096)
data.decode()
print ('received %s bytes from %s' % (len(data), address))
print (data)
if data:
message = data.decode()
operationCode = message[0]
integers = re.findall("\-?\d+", message)
integers = [int(x) for x in integers]
if re.search("[+\-*/]", operationCode) and len(integers)==2:
if (operationCode == '/' and integers[1]==0):
print ("Request not valid.")
sent = sock.sendto(badResponse, address)
else:
print ("Code: " + operationCode + ", Ints: " + str(integers[0]) + ", " + str(integers[1]))
result = ops[operationCode](integers[0],integers[1])
print ("Result: " + str(result))
response = "Status: 200, Result: " + str(result)
sent = sock.sendto(response.encode(), address)
print ('sent %s bytes back to %s' % (sent, address))
else:
print ("Request not valid.")
sent = sock.sendto(badResponse, address)
ОБНОВЛЕНИЕ: я пробовал другой метод, но он также не работал. Вместо того, чтобы использовать сигнал, я использовал попытку / исключение с KEYBOARDINTERRUPT. Еще раз, программа завершает работу, но не печатает из Except и не делает ничего, что могло бы предположить, что прерывание было перехвачено.
Ниже приведен код, который изменился (только цикл while, плюс исключение любого кода, связанного с сигналом).
while True:
try:
print ('\nwaiting to receive message')
data, address = sock.recvfrom(4096)
data.decode()
print ('received %s bytes from %s' % (len(data), address))
print (data)
if data:
message = data.decode()
operationCodeValid = re.search("^[+\-*/]{1}", message)
integers = re.findall("\-?\d+", message)
integers = [int(x) for x in integers]
if operationCodeValid and len(integers)==2:
operationCode = message[0]
if (operationCode == '/' and integers[1]==0):
badResponse(address)
else:
print ("Code: " + operationCode + ", Ints: " + str(integers[0]) + ", " + str(integers[1]))
result = ops[operationCode](integers[0],integers[1])
print ("Result: " + str(result))
response = "Status: 200, Result: " + str(result)
sent = sock.sendto(response.encode(), address)
print ('sent %s bytes back to %s' % (sent, address))
else:
badResponse(address)
else:
badResponse(address)
except KeyboardInterrupt:
print ("[CTRL+C detected]")
try:
sock.close()
print ("Socket Closed.")
except Exception as e:
print ("Socket not open. " + e)
finally:
exit(0)