You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:40:35