如何实现Socket服务器后台持续接收客户端连接请求?
解决实时监听客户端连接 + 命令输入并行的问题
我明白你的困扰——当前代码里command_accept()的input()会死死卡住主线程,导致只有输入命令后才会去检查有没有新客户端连接,完全做不到实时响应。要实现后台持续监听客户端,同时不阻塞命令输入,用多线程是最直接且容易理解的方案。
核心思路
把客户端监听的逻辑(client_accept)放到一个独立的后台线程里,让它专门负责等待新连接;主线程则专注处理命令输入。这样两个任务互不干扰,新客户端一发起连接就能立刻被捕获并打印日志。
修改后的完整代码
import socket import time import sys import threading host = '127.0.0.1' port = 1344 id_counter = 0 server = socket.socket() server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((host, port)) server.listen() clients = {} def client_accept(server): global id_counter while True: # 这里直接用accept阻塞,线程会一直等待新连接,不影响主线程 conn, addr = server.accept() id_counter += 1 clients[id_counter] = (conn, addr) # 打印日志后主动刷新命令提示符,避免和输入混在一起 print(f'\n{time.ctime()} New client [ID {id_counter}] with address {str(addr[0])}:{str(addr[1])}') print('server > ', end='', flush=True) def command_accept(): while True: command = input('server > ') if command == 'exit': # 退出前关闭所有客户端连接和服务器socket for conn, _ in clients.values(): conn.close() server.close() sys.exit() else: print(f'command {command} accepted!') # 启动后台监听线程,设置为守护线程,主线程退出时自动终止 accept_thread = threading.Thread(target=client_accept, args=(server,), daemon=True) accept_thread.start() # 主线程专注处理命令输入 command_accept()
关键改动说明
- 引入多线程:用
threading.Thread把client_accept放到后台,它会独立运行,一直阻塞在server.accept()上等待新连接,不会被主线程的input()卡住。 - 移除socket超时:原来的超时是为了让
client_accept能退出循环,但现在线程可以一直运行,不需要超时了。 - 优化日志显示:打印新客户端日志后,手动输出
server >并刷新缓冲区,这样日志不会和命令提示符混在一起,交互体验更顺畅。 - 守护线程设置:
daemon=True确保主线程执行exit退出时,后台线程会自动跟着结束,不会留下残留进程。
扩展提示
如果之后需要处理客户端发送的消息,还可以在client_accept里为每个新连接再启动一个线程,这样多个客户端的消息处理也不会互相阻塞,实现真正的多客户端并发处理。
内容的提问来源于stack exchange,提问作者Dmytro Ohorodnik
相关产品推荐
相关产品推荐

