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

如何退出Python的TCP accept函数?实现超时后自动退出

解决accept阻塞导致程序无法超时退出的方案

方法1:给监听socket设置超时时间

通过settimeout()给监听socket指定超时时长,当accept()在设定时间内未接收到连接时,会抛出socket.timeout异常,捕获该异常即可让程序正常退出。

修改后的代码:

import socket

HOST = "127.0.0.1"
PORT = 65432

def connect():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        print("listening")
        s.listen()
        # 设置超时时间为10秒
        s.settimeout(10)
        print("accepting,10秒内无连接则退出")
        try:
            conn, addr = s.accept()
            with conn:
                print(f"Connected by {addr}")
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    conn.sendall(data)
        except socket.timeout:
            print("超时,程序退出")

def main():
    connect()

if __name__ == "__main__":
    main()

方法2:使用select.select监听连接

利用select.select监听监听socket的可读状态,同时设置超时参数,超时后直接终止程序。这种方式更灵活,适合需要同时处理多个socket的场景。

修改后的代码:

import socket
import select

HOST = "127.0.0.1"
PORT = 65432

def connect():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        print("listening")
        s.listen()
        print("accepting,10秒内无连接则退出")
        # 监听可读事件,超时10秒
        readable, _, _ = select.select([s], [], [], 10)
        if not readable:
            print("超时,程序退出")
            return
        # 有可读事件,说明有连接请求
        conn, addr = s.accept()
        with conn:
            print(f"Connected by {addr}")
            while True:
                data = conn.recv(1024)
                if not data:
                    break
                conn.sendall(data)

def main():
    connect()

if __name__ == "__main__":
    main()

方法3:线程+定时器强制关闭socket

启动定时器线程,超时后关闭监听socket,此时accept()会触发OSError异常,捕获异常后即可退出程序。这种方式适合需要强制终止阻塞操作的场景。

修改后的代码:

import socket
import threading

HOST = "127.0.0.1"
PORT = 65432

def connect():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        print("listening")
        s.listen()
        print("accepting,10秒内无连接则退出")
        
        # 定义超时后关闭socket的函数
        def timeout_close():
            print("超时,关闭监听socket")
            s.close()
        
        # 启动10秒定时器
        timer = threading.Timer(10, timeout_close)
        timer.start()
        
        try:
            conn, addr = s.accept()
            # 有连接接入,取消定时器
            timer.cancel()
            with conn:
                print(f"Connected by {addr}")
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    conn.sendall(data)
        except OSError:
            # socket被关闭,捕获异常退出
            print("程序退出")

def main():
    connect()

if __name__ == "__main__":
    main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:50:14