python - 防止 print() 语句覆盖 input() 语句中的文本

标签 python python-3.x sockets

所以我正在用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/

相关文章:

python - 使用变量将选项传递给 Tkinter 小部件

c++ - C/C++中的并发UDP连接限制

c++ - 使用 select() 检测套接字何时断开连接

python - Pygame,移动时如何从播放器中删除轨迹,我尝试填充屏幕但仍然不适合我

python - 创建类后在方法上设置属性会引发 "' instancemethod' object has no attribute“但属性显然存在

Python 子模块更简单的引用

python - FutureWarning : elementwise comparison failed; returning scalar, 但将来会执行元素比较

python - 如何将 pandas 日期列与今天的日期进行比较?

python - 如何从描述符将属性请求委托(delegate)给 MRO 链

c - EV3 上的蓝牙