Python 防止print()语句覆盖input()语句中的文本
所以我正在用python开发一个简单的聊天服务器。 服务器运行良好,在客户机上,我有一个线程用于接收传入数据,另一个用于发送消息 我可以从客户端_1向服务器发送消息,服务器将消息传递给所有其他客户端,然后这些客户端将打印消息 尽管技术上一切正常,但有一件事无论何时发生都非常恼人: 假设客户端1正在控制台中键入文本。 客户机_2向服务器发送消息的同时,服务器向客户机_1发送消息,客户机_1打印消息。 现在,客户端_1最初在控制台中输入的文本不再在它应该在的行中 这是在client_2发送字符串“test test”之前控制台的样子: 这就是他们发送后的样子: 注意:如果在客户端1上按Enter键,消息“TEST”仍将正确发送。问题只在于正在打印的文本与input()语句中的文本之间存在冲突 我的代码如下所示: Server.pyPython 防止print()语句覆盖input()语句中的文本,python,python-3.x,sockets,Python,Python 3.x,Sockets,所以我正在用python开发一个简单的聊天服务器。 服务器运行良好,在客户机上,我有一个线程用于接收传入数据,另一个用于发送消息 我可以从客户端_1向服务器发送消息,服务器将消息传递给所有其他客户端,然后这些客户端将打印消息 尽管技术上一切正常,但有一件事无论何时发生都非常恼人: 假设客户端1正在控制台中键入文本。 客户机_2向服务器发送消息的同时,服务器向客户机_1发送消息,客户机_1打印消息。 现在,客户端_1最初在控制台中输入的文本不再在它应该在的行中 这是在client_2发送字符串“t
connections = []
while True:
readable, writeable, exception = select.select(connections, [], [], 0)
for sock in readable:
if sock == server:
conn, addr = server.accept()
connections.append(conn)
else:
data = str(sock.recv(1024), 'utf8')
if data:
for s in connections:
if s != server_socket and s != sock:
s.send(bytes(data, 'utf8'))
else:
connections.remove(sock)
Client.py
def receive():
while True:
readable, writeable, exception = select.select([0, client], [], [])
for sock in readable:
if sock == client:
data = str(sock.recv(1024), 'utf8')
if data:
print(data)
def send():
while True:
readable, writeable, exception = select.select([0, client], [], [])
for sock in readable:
if sock == client:
pass
else:
msg = input()
client.send(bytes(msg, 'utf8'))
Thread(target=receive).start()
Thread(target=send).start()
有没有办法解决这个问题而不用在单独的脚本中运行send()和receive()函数,或者使用像Tkinter这样的GUI模块
编辑:我希望在收到传入消息后立即打印该消息,但随后会显示input()提示符并再次键入文本。这里有一种方法可以显示传入消息,然后重新显示输入提示符和部分输入字符串(如注释中指定的)。它使用
readline.get\u line\u buffer
读取当前输入的字符串并重新显示。不过,有一个警告:在不锁定的情况下从不同线程读写同一个流很容易出现故障
它只需要对接收
功能稍作修改:
if data:
print('\n' + data)
sys.stdout.write(readline.get_line_buffer())
sys.stdout.flush()
打印
中的'\n'
是这样的,因此传入的消息不会正好落在正在键入的任何内容上。flush
是必需的,这样您就可以在不换行的情况下写入当前输入,但不会对其进行缓冲。我可能建议在输入
和sys.stdout.write
中添加一个提示(如'>'
),以便用户更清楚地了解正在发生的事情
最后,运行此命令可能会弄乱终端输出。之后可能需要运行
reset
。可能有一种清理方法可以防止这种情况发生,但我不知道它是什么。有一件事我想你还没有弄清楚,那就是在这种情况下你想发生什么。如果用户正在键入,客户端是否应该等待显示收到的消息?信息是否应显示在其他位置?是否应打印传入消息,但随后再次显示输入提示和键入的文本?这些都是我见过的解决方案。对我来说,最好的办法是打印传入的消息,然后再次显示输入提示和键入的文本。