单入口Python客户端服务端:关闭客户端后服务端终止问题求助
问题原因及解决方案
核心原因
你遇到的问题和Shared.py无关,本质是终端进程组的信号传递机制:默认情况下,Popen创建的服务端进程与客户端同属一个前台进程组。当按下Ctrl+C时,终端会向整个进程组发送SIGINT终止信号,导致服务端和客户端同时被终止。
解决方案
1. 让服务端脱离客户端进程组
修改Client.py中启动服务端的代码,让服务端成为独立进程组,避免被客户端的终止信号影响:
跨平台兼容写法
from subprocess import Popen, CREATE_NEW_PROCESS_GROUP import sys import os # 根据系统设置进程隔离参数 startup_kwargs = {} if sys.platform == 'win32': startup_kwargs['creationflags'] = CREATE_NEW_PROCESS_GROUP else: startup_kwargs['preexec_fn'] = os.setpgrp # 启动独立的服务端进程 process = Popen([sys.executable, 'Server.py'], **startup_kwargs)
- Linux/macOS:
os.setpgrp()会让子进程成为新进程组的组长,脱离父进程的进程组,不再接收父进程所在终端的SIGINT信号。 - Windows:
CREATE_NEW_PROCESS_GROUP标记会创建独立的进程组,避免被客户端的终止信号波及。
2. 优化服务端连接逻辑(可选)
当前服务端在客户端断开后无法接受新连接,若需要服务端持续监听新客户端,可修改Server.py:
from multiprocessing.connection import Listener, Connection from Shared import ADDRESS, logger import time listener = Listener(ADDRESS) logger.info('Server started and listening for connections!') while True: try: # 等待新客户端连接 conn: Connection = listener.accept() logger.info('New client connected') # 处理当前客户端的消息 while True: try: msg = conn.recv() logger.info(msg) if msg == 'exit': conn.close() logger.info('Client disconnected normally') break except EOFError: conn.close() logger.info('Client disconnected unexpectedly') break except Exception as e: logger.error(f'Server error: {str(e)}') time.sleep(1)
3. 打包成独立可执行文件的注意事项
使用pyinstaller等工具打包时:
- 若打包为单文件,需将服务端也打包为独立可执行文件,启动时改为调用该可执行文件(而非
sys.executable + Server.py) - 确保日志文件路径正确,避免因打包后的路径问题导致日志无法写入
内容的提问来源于stack exchange,提问作者Rrr
相关产品推荐
相关产品推荐

