У меня есть приемник, который прослушивает как TCP, так и UDP пакеты. У меня также есть функция foo (), которая запускается одновременно, печатает текущее время и отправляет пакет UDP каждые 5 секунд.
Проблема в том, что когда я нажимаю кнопки Ctrl + C, чтобы завершить программу, в первый раз она не завершается, и я должен нажать эти кнопки как минимум два раза.
Я добавил рейз, как это было предложено в этом посте . Это сработало у меня в предыдущем вопросе, но после того, как я добавил некоторые другие части, оно снова не сработало.
Вот код:
from __future__ import print_function
from select import select
import socket
from struct import pack
from struct import unpack
from collections import deque
host = '10.0.0.2'
port = 5005
backlog = 5
BUFSIZE = 4096
q = deque()
import time, threading
def foo():
try:
print(time.ctime())
threading.Timer(5, foo).start()
except KeyboardInterrupt:
print('\nClosing')
raise
class Receiver:
''' Buffer binary data from socket conn '''
def __init__(self, conn):
self.conn = conn
self.buff = bytearray()
def get(self, size):
''' Get size bytes from the buffer, reading
from conn when necessary
'''
while len(self.buff) < size:
data = self.conn.recv(BUFSIZE)
if not data:
break
self.buff.extend(data)
# Extract the desired bytes
result = self.buff[:size]
# and remove them from the buffer
del self.buff[:size]
return bytes(result)
def save(self, fname):
''' Save the remaining bytes to file fname '''
with open(fname, 'wb') as f:
if self.buff:
f.write(bytes(self.buff))
while True:
data = self.conn.recv(BUFSIZE)
if not data:
break
f.write(data)
def send(sock2, data2):
while data2:
sent = sock2.send(data2)
data2 = data2[sent:]
def send_file(ipToTransfer, fname):
with open(fname, 'rb') as f:
sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock2.connect((ipToTransfer, 5005))
except socket.error as err:
print(err, ipToTransfer, 5005)
sock2.close()
return
# Send the file name length & the filename itself in one packet
send(sock2, pack('B', len(fname)) + fname.encode())
while True:
data2 = f.read(BUFSIZE)
if not data2:
break
send(sock2, data2)
sock2.close()
def read_tcp(s):
conn, addr = s.accept()
print('Connected with', *addr)
# Create a buffer for this connection
receiver = Receiver(conn)
# Get the length of the file name
name_size = unpack('B', receiver.get(1))[0]
name = receiver.get(name_size).decode()
q.append(name)
print('name', name)
# Save the file
receiver.save(name)
conn.close()
print('saved\n')
def read_udp(s):
data,addr = s.recvfrom(1024)
print("received message:", data)
def run():
# create tcp socket
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
tcp.bind((host,port))
except socket.error as err:
print('Bind failed', err)
return
tcp.listen(1)
# create udp socket
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
udp.bind((host,port))
print('***Socket now listening at***:', host, port)
input = [tcp,udp]
try:
while True:
inputready,outputready,exceptready = select(input,[],[])
for s in inputready:
if s == tcp:
read_tcp(s)
elif s == udp:
read_udp(s)
else:
print("unknown socket:", s)
# Hit Break / Ctrl-C to exit
except KeyboardInterrupt:
print('\nClosing')
raise
tcp.close()
udp.close()
if __name__ == '__main__':
foo()
run()
При первом нажатии Ctrl + C
программа не завершается, и мне нужно нажать их во второй раз. В чем дело? Как я могу убить программу, нажав Ctrl + C
в первый раз?