2015-08-10 4 views
0

У меня есть многопоточная программа на python, и я хотел бы закрыть сокет после CTRL + C (или Z). Я пробовал this и this, но никто из них не работал.Как закрыть сокет Python, запущенный в потоке после CTRL + C?

При попытке повторного запуска программы появляется сообщение об ошибке:

Bind failed. Error code: 98 Message Address already in use called Traceback (most recent call last): File "main.py", line 16, in main.connection.close() NameError: name 'main' is not defined

from connection import Connection 
class Main(): 
    def __init__(self): 
     self.connection = Connection()      
     self.connection.start()      
if __name__ == '__main__': 
    try: 
     main = Main() 
    except: 
     main.connection.close() 


import socket 
import sys 
import threading 
import time 
class Connection(threading.Thread): 
    def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None): 
     threading.Thread.__init__(self, group=group, target=target, name=name, args=args, kwargs=kwargs, verbose=verbose) 

     self.server = None 
     self.connection = self.start_connention() 
     self.data = "null"  
     self.lock = threading.Lock() 
     self.OK = True   

    def start_connention(self): 
     host = '192.168.42.1' 
     port = 8888 

     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     print 'Socket created' 

     #Bind socket to local host and port 
     try: 
      s.bind((host, port)) 
     except socket.error, msg: 
      print 'Bind failed. Error code: ' + str(msg[0]) + ' Message ' + msg[1] 
      sys.exit() 

     print 'Socket bind complete' 

     #Start listening on socket 
     s.listen(10) 
     print 'Socket now listening on ' + str(port) 

     connection, addr = s.accept() 
     print 'Connected with ' + addr[0] + ':' + str(addr[1])     

     self.server = s 

     return connection 

    def close(self): 
     print("closing") 
     self.OK = False 
     self.server.close() 

    def run(self): 
     while self.OK:    
      with self.lock: 
       self.data = self.connection.recv(4096) 
       print(str(self.data)) 
      time.sleep(0.02) 


    def send(self, message): 
     self.connection.sendall(message) 

ответ

0

Из документации: KeyboardInterrupt наследует от BaseException так, чтобы не быть случайно пойманы код, который перехватывает исключение и тем самым предотвратить переводчик от выхода. docs

if __name__ == '__main__': 
    try: 
     main = Main() 
    except KeyboardInterrupt: 
     pass 
    finally: 
     main.connection.close() 
+0

Он работает, но после того, как устройство подключается код в конце концов вызывается непосредственно, и закрывает соединение без нажатия клавиши CTRL + C. – Alex

+0

Попробуйте добавить - main.connection.run(), чтобы попробовать блок –

+0

Это очень интересно: если я добавлю main.connection.run() в блок try, устройство подключится и после нажатия ctrl + c код в наконец, ** не ** называется: O – Alex

-1

Я хотел бы предложить вам использовать atexit модуль для этого материала. Просто поместите эту строку в __init__ и в случае любого завершении процесса питона соединения будет близко

atexit.register(self.close) 
Смежные вопросы