Python Socket服务器按下Ctrl+C无法触发KeyboardInterrupt问题求助
解决Python Socket服务器Ctrl+C无法终止的问题
问题根源在于socket.accept()是阻塞式系统调用,当服务器卡在这个调用上时,操作系统可能不会及时将KeyboardInterrupt信号传递给Python解释器,导致异常无法被捕获。以下是几种可行的解决思路:
1. 给Socket设置超时时间
让accept()定期退出阻塞状态,给主线程留出捕获信号的机会:
import socket def run(self) -> None: try: self.socket.listen() self.socket.settimeout(1.0) # 设置1秒超时 print(f'$ - Server {self.host}:{self.port} is running.') while True: try: client, address = self.socket.accept() Thread(target=clientHandler, args=[client, address], daemon=True).start() except socket.timeout: continue # 超时后回到循环,等待下一次连接 except KeyboardInterrupt: print('! - Server interrupted.') finally: self.socket.close() # 确保关闭Socket资源
2. 使用select模块监听连接
select.select()可以在等待Socket可读时响应信号,避免完全阻塞:
import select def run(self) -> None: try: self.socket.listen() print(f'$ - Server {self.host}:{self.port} is running.') while True: # 监听Socket的可读状态,超时1秒 readable, _, _ = select.select([self.socket], [], [], 1.0) if self.socket in readable: client, address = self.socket.accept() Thread(target=clientHandler, args=[client, address], daemon=True).start() except KeyboardInterrupt: print('! - Server interrupted.') finally: self.socket.close()
3. 将客户端线程设为守护线程
如果客户端处理线程是非守护线程,主线程捕获KeyboardInterrupt后会等待所有非守护线程结束才退出,导致看起来服务器没停止。创建线程时添加daemon=True:
Thread(target=clientHandler, args=[client, address], daemon=True).start()
内容的提问来源于stack exchange,提问作者Taras Z
相关产品推荐
相关产品推荐

