【问题标题】:How to close Python socket running in a thread after CTRL+C?CTRL+C后如何关闭线程中运行的Python套接字?
【发布时间】:2015-11-02 19:38:53
【问题描述】:

我在 python 中有一个多线程程序,我想在 CTRL+C(或 Z)之后关闭套接字。我试过thisthis,但都没有奏效。

尝试重新运行程序时,出现错误消息:

绑定失败。错误代码:98 消息地址已在使用中调用 Traceback(最近一次调用最后一次):文件“main.py”,第 16 行,在 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)

【问题讨论】:

    标签: python multithreading python-2.7 sockets python-3.x


    【解决方案1】:

    来自文档:KeyboardInterrupt 继承自 BaseException,以免被捕获 Exception 的代码意外捕获,从而阻止解释器退出。 docs

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

    【讨论】:

    • 可以,但是设备连接后,立即调用finally中的代码,不按CTRL+C就关闭连接。
    • 尝试添加到添加-main.connection.run() 尝试阻塞
    • 很有意思:如果我在try块中加入main.connection.run(),设备就连接了,按ctrl+c后finally中的代码是not 叫:O
    • self.connection.start() 。从哪里开始方法?
    • 它启动线程。但是在将 main.connection.run() 添加到 try 块之后,它被从构造函数中删除了
    【解决方案2】:

    我建议你对这些东西使用atexit 模块。 只需将此行放在__init__ 中,以防任何 python 进程终止,连接将关闭

    atexit.register(self.close) 
    

    【讨论】:

      猜你喜欢
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      • 2017-09-10
      相关资源
      最近更新 更多