所以我正在用python开发一个简单的聊天服务器。
服务器运行良好,在客户端我有一个线程用于接收传入数据和一个用于发送消息。
我可以从 client_1 向服务器发送一条消息,该服务器将其传递给所有其他客户端,然后这些客户端将打印该消息。
尽管技术上一切正常,但仍有一件事在发生时非常烦人:
假设 client_1 正在控制台中输入文本。
同时client_2向服务器发送消息,服务器将消息发送给client_1,client_1打印消息。
现在,最初输入控制台的文本 client_1 不再在它应该在的行中。
这是在 client_2 发送字符串“test test”之前控制台的样子:https://ibb.co/hFdeo7
这是他们发送后的样子:https://ibb.co/mEWAvn
注意:如果我在 client_1 上按 Enter,消息“TEST TEST TEST”仍然会正确发送。问题仅在于正在打印的文本与 input() 语句中的文本之间的冲突。
我的代码如下所示:
服务器.py
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)
客户端.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_line_buffer
读取当前输入的字符串并重新显示它。但是,一个警告:从不同线程读取和写入同一流而不加锁很容易出现故障。
它只需要对 receive
进行小修改功能:
if data:
print('\n' + data)
sys.stdout.write(readline.get_line_buffer())
sys.stdout.flush()
'\n'
在 print
是所以传入的消息不会落在正在输入的任何内容之上。 flush
是必要的,这样您就可以在没有换行符的情况下写入当前输入,但不会缓冲它。我可能会建议在 '> '
中添加提示(如 input
)和 sys.stdout.write
,只是为了让用户更清楚正在发生的事情。最后,运行它可能会弄乱您的终端输出。您可能需要运行
reset
然后。可能有一种清理方法可以防止这种情况发生,但我不知道它是什么。
关于python - 防止 print() 语句覆盖 input() 语句中的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48734549/