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

Python多线程Socket服务器调用accept()后直接退出问题求助

Python多线程Socket服务器启动后直接退出问题分析

问题描述

我近期正在学习Python的Socket编程,尤其是多线程Socket服务器开发。我的服务器代码如下:

import socket
import threading
class Server(object):
    def __init__(self):
        self.g_conn_pool = {}
        self.num = 0      
        self.address = ('', 8022)
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_socket.bind(self.address)
        self.server_socket.listen(128)
    def accept_client(self):
        print("accept_client\n")
        while True:
            print('in')
            client_socket, info = self.server_socket.accept()
            print('client name: ' + client_socket.getsockname())
            print(client_socket, info)
            thread = threading.Thread(target=self.recv_msg, args=(client_socket, info))
            thread.daemon = True
            thread.start()
    def recv_msg(self, client, info)
        pass
    def start_new_thread(self):
        thread = threading.Thread(target=self.accept_client, args=())
        thread.daemon = True
        thread.start()
        print("start_new_thread")
multi_server = Server()
multi_server.start_new_thread()

运行该程序时,发现程序总是在执行client_socket, info = self.server_socket.accept()这一行后直接退出,'client name: '相关内容并未打印。我原本预期服务器启动后会持续等待客户端连接,但还没来得及启动客户端程序,服务器就已快速退出。请问该问题由什么原因导致?是否缺少相关代码或操作?

问题原因

  1. 守护线程特性导致主程序提前退出
    你将监听客户端连接的accept_client线程设置为daemon=True,Python的规则是:当所有非守护线程(包括主线程)执行完毕后,程序会立即终止,所有守护线程会被强制停止。你的主程序在执行完multi_server.start_new_thread()后没有任何阻塞逻辑,主线程直接结束,导致作为守护线程的accept_client还没进入accept()的阻塞等待就被终止了。

  2. 存在语法错误
    recv_msg方法的定义末尾缺少冒号:,这会触发语法错误,虽然你描述程序是直接退出,但这个错误必须先修复才能保证程序正常运行。

解决方案

1. 修复语法错误

给recv_msg方法的定义添加冒号:

def recv_msg(self, client, info):
    pass

2. 阻止主线程提前退出

有两种常见方式可以让主线程保持运行,从而让监听线程正常工作:

方式一:使用输入阻塞

在主程序的最后添加input()语句,让主线程等待用户输入才会结束:

multi_server = Server()
multi_server.start_new_thread()
input("服务器已启动,按回车键退出...\n")

方式二:将监听线程设为非守护线程并让主线程等待

修改start_new_thread方法,去掉守护线程的设置,并返回线程对象,然后让主线程等待该线程结束:

def start_new_thread(self):
    thread = threading.Thread(target=self.accept_client, args=())
    thread.start()
    print("start_new_thread")
    return thread

# 主程序部分
multi_server = Server()
server_thread = multi_server.start_new_thread()
server_thread.join()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:33:24