Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 防止print()语句覆盖input()语句中的文本_Python_Python 3.x_Sockets - Fatal编程技术网

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

Python 防止print()语句覆盖input()语句中的文本,python,python-3.x,sockets,Python,Python 3.x,Sockets,所以我正在用python开发一个简单的聊天服务器。 服务器运行良好,在客户机上,我有一个线程用于接收传入数据,另一个用于发送消息 我可以从客户端_1向服务器发送消息,服务器将消息传递给所有其他客户端,然后这些客户端将打印消息 尽管技术上一切正常,但有一件事无论何时发生都非常恼人: 假设客户端1正在控制台中键入文本。 客户机_2向服务器发送消息的同时,服务器向客户机_1发送消息,客户机_1打印消息。 现在,客户端_1最初在控制台中输入的文本不再在它应该在的行中 这是在client_2发送字符串“t

所以我正在用python开发一个简单的聊天服务器。 服务器运行良好,在客户机上,我有一个线程用于接收传入数据,另一个用于发送消息

我可以从客户端_1向服务器发送消息,服务器将消息传递给所有其他客户端,然后这些客户端将打印消息

尽管技术上一切正常,但有一件事无论何时发生都非常恼人:

假设客户端1正在控制台中键入文本。 客户机_2向服务器发送消息的同时,服务器向客户机_1发送消息,客户机_1打印消息。 现在,客户端_1最初在控制台中输入的文本不再在它应该在的行中

这是在client_2发送字符串“test test”之前控制台的样子:

这就是他们发送后的样子:

注意:如果在客户端1上按Enter键,消息“TEST”仍将正确发送。问题只在于正在打印的文本与input()语句中的文本之间存在冲突

我的代码如下所示:

Server.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)
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
。可能有一种清理方法可以防止这种情况发生,但我不知道它是什么。

有一件事我想你还没有弄清楚,那就是在这种情况下你想发生什么。如果用户正在键入,客户端是否应该等待显示收到的消息?信息是否应显示在其他位置?是否应打印传入消息,但随后再次显示输入提示和键入的文本?这些都是我见过的解决方案。对我来说,最好的办法是打印传入的消息,然后再次显示输入提示和键入的文本。