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

如何在Python中通过键盘中断终止等待TCP连接的无限循环

解决TCP服务器阻塞在accept()时无法捕获KeyboardInterrupt的问题

这个问题我太熟悉了!当你的TCP服务器调用accept()进入阻塞状态后,底层的系统调用会“卡住”程序,导致KeyboardInterrupt信号无法被及时捕获,直到有新连接进来才会触发异常处理。下面给你两个实用的解决方案:

方法一:给Socket设置超时时间

通过给监听Socket设置超时时间,让accept()每隔一段时间就跳出阻塞状态,这样循环就有机会检测到KeyboardInterrupt信号。

修改你的可执行代码如下:

# coding=utf-8
from socket import *
port = 12000
servername = "127.0.0.1"
connection = socket(AF_INET, SOCK_STREAM)
connection.bind((servername, port))
connection.listen(1)
# 设置1秒超时,你可以根据需求调整时长
connection.settimeout(1)
print("SERVER STARTED")
while 1:
    try:
        x = connection.accept()
        # 这里可以处理新连接逻辑
        print("New connection from", x[1])
    except timeout:
        # 超时后继续循环,不做其他操作
        continue
    except KeyboardInterrupt:
        print("Keyboard Interrupt Occured")
        break
# 记得关闭socket
connection.close()
print("I am out of loop")

原理:设置超时后,accept()最多阻塞指定时长,超时会抛出timeout异常,我们捕获后继续循环,这样程序就有机会在每次超时后检查是否有键盘中断信号。

方法二:使用信号处理机制

注册SIGINT信号的处理函数,当按下Ctrl+C时,主动关闭监听Socket,让accept()抛出异常,从而退出循环。

代码示例:

# coding=utf-8
from socket import *
import signal
import sys

port = 12000
servername = "127.0.0.1"
connection = socket(AF_INET, SOCK_STREAM)
connection.bind((servername, port))
connection.listen(1)

# 定义信号处理函数
def handle_interrupt(signum, frame):
    print("\nKeyboard Interrupt Occured")
    # 关闭监听socket,让accept()抛出异常
    connection.close()
    sys.exit(0)

# 注册SIGINT信号处理
signal.signal(signal.SIGINT, handle_interrupt)

print("SERVER STARTED")
try:
    while 1:
        x = connection.accept()
        print("New connection from", x[1])
except OSError:
    # 关闭socket后,accept()会抛出OSError,这里捕获后退出循环
    pass
print("I am out of loop")

原理:当按下Ctrl+C时,系统会发送SIGINT信号,我们的处理函数会关闭监听Socket,此时阻塞的accept()会立刻抛出OSError,程序就能跳出循环并正常退出。

这两种方法都能解决你的问题,你可以根据自己的业务场景选择:如果需要服务器持续监听且对延迟不敏感,方法一更简单;如果希望立刻响应中断,方法二更高效。

内容的提问来源于stack exchange,提问作者Shubham Nigam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:25:26