Python Socket多线程聊天客户端输入被干扰问题求助
解决多线程聊天客户端输入被打断的问题
核心原因
input()是阻塞式函数,用户输入过程中,接收线程的print()会直接输出到当前终端行,打乱正在输入的内容。
解决方案1:线程锁同步输入输出
给终端操作加全局锁,确保同一时间只有一个线程读写终端,避免冲突:
首先定义全局锁:
import threading print_lock = threading.Lock()
修改接收消息的函数:
def recieve(): while True: try: message = client.recv(1024).decode('ascii') with print_lock: # 回到行首清空当前输入内容,打印消息后重新显示输入提示 print('\r', end='') print(message) print("Me: ", end='', flush=True) except: print("连接断开") client.close() break
修改发送消息的函数:
def write(): while True: with print_lock: message = input("Me: ") message = formatMess(nickname, message) client.send(message.encode('ascii'))
解决方案2:非阻塞输入监听(需额外库)
用pynput监听键盘输入,实时控制输入状态,收到消息时自动调整显示:
先安装依赖:
pip install pynput
示例代码:
from pynput.keyboard import Listener, Key import threading current_input = "" print_lock = threading.Lock() def on_press(key): global current_input try: current_input += key.char with print_lock: print(f"\rMe: {current_input}", end='', flush=True) except AttributeError: if key == Key.backspace: current_input = current_input[:-1] with print_lock: print(f"\rMe: {current_input}", end='', flush=True) elif key == Key.enter: with print_lock: print() message = formatMess(nickname, current_input) client.send(message.encode('ascii')) current_input = "" with print_lock: print("Me: ", end='', flush=True) def recieve(): while True: try: message = client.recv(1024).decode('ascii') with print_lock: print(f"\r{message}\nMe: {current_input}", end='', flush=True) except: print("连接断开") client.close() break # 启动线程 recieve_thread = threading.Thread(target=recieve) recieve_thread.start() # 启动键盘监听 with Listener(on_press=on_press) as listener: listener.join()
注意事项
- 线程锁方案更轻量,适合基础场景;非阻塞输入更灵活,但需要额外依赖。
- 所有终端输出操作必须通过锁保护,避免并发冲突。
内容的提问来源于stack exchange,提问作者Beni
相关产品推荐
相关产品推荐

