保持控制台输入线低于输出

时间:2014-08-16 18:00:27

标签: python networking text console

[编辑:] 我目前正在尝试制作一个小型tcp聊天应用程序。发送和接收消息已经正常工作......但问题是:

当我收到一条消息时开始输入消息...它出现在我正在撰写的文本之后

屏幕截图:http://s7.directupload.net/images/140816/6svxo5ui.png

[用户发送> "你好",然后我开始写作#34;我正在写..."然后用户写了#34;我发了一个..."在我发送信息之前...所以它是在我输入后放置的...... 我希望收到的消息总是在我输入之前!

这是我目前的代码: Client.py

con = connect.User()
server = raw_input("Type in the server adress \n[leave blank to use xyr.no-ip.info]\n>:")
nick =""

while nick == "":
    nick = raw_input("Type in your nickname\n>:")

con.connect(server, nick)


def sender():
    print("Sender started")
    while 1:
        msg = raw_input()
        if msg == "q":
            break
        con.send(msg)

    con.disconnect()



def receiver(server):

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        if server == "":
            server="xyr.no-ip.info"

        sock.connect((server, 8000))

        sock.send("%pyreceiver\n")

        print("Receiver started")

        while 1:
           msg_in = sock.recv(1024)
           if not str(msg_in).startswith("[py]" + nick):
               if str(msg_in).startswith("/ua"):
                   print(str(msg_in)[3:])

               elif str(msg_in).startswith("/u "):
                   print(str(msg_in)[2:])
               else:

                print(str(msg_in[:-1]))
#

if nick == "":
    nick = "guest"
    print("Name changed to ""guest""")
    time.sleep(.5)

thread.start_new_thread(receiver, (server, ))
time.sleep(.5)
thread.start_new_thread(sender())

Connect.py

import socket

import time

class User():


    nickel =""
    def connect(self, server="xyr.no-ip.info", nick="guest"):
        nickel = nick
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if server == "":
            server="xyr.no-ip.info"
            print("server changed to xyr.no-ip.info")
            time.sleep(.5)


        print("Connecting...")
        self.sock.connect((server, 8000))
        print("Connected")
        time.sleep(.4)
        self.sock.send("[py]" + nick + "\n")


        self.sock.send(nick + " connected with a python client\n")
        print("registered as " + nick)
        time.sleep(.3)


    def send(self, msg):
        self.sock.send(msg + "\n")


    def disconnect(self):
        self.sock.close()

        print("disconnected")

2 个答案:

答案 0 :(得分:2)

我遇到了类似的问题,我发现一个更简单的解决方案(对我而言)是通过readchar(https://github.com/magmax/python-readchar/tree/master/readchar)获取输入。

使用readchar,我会缓冲每次击键(检查key.BACKSPACE和CR - 请参阅下面的代码片段。)

我将在" / 033 [1A" (使光标向上移动),打印输出线,然后打印" / n" ...

在每个输出行之后,我将光标移动到开头并重新打印self.input_buff

当用户正在输入时,它会处理控制台输入,显示他们输入的内容:

            keypress = readkey()

            if keypress == key.BACKSPACE:
                self.input_buff = self.input_buff[:-1]
                print("\033[0A%s         " % self.input_buff)
                continue

            if keypress != key.CR:
                self.input_buff = "%s%s" % (self.input_buff, keypress)
                print("\033[0A%s" %  self.input_buff)
                continue

这使输入线保持在底部,所有终端输出都在它上面。

我知道它来晚了一年,如果你是一个诅咒的巫师,也许这是要走的路......

答案 1 :(得分:1)

您的代码将所有内容写入stdout。每当有东西到达你的发送者/接收者线程时,它都会打印到stdout。问题在于,由于输出流的基本特性,您无法完成以下操作:

  • 将传入的消息放在上面当前正在输入/回显的内容。

事情严格按照发生的顺序发生。当某些东西进来时,无论光标在哪里,print语句都会在那里转储那些数据。如果不使用更高级/更强大的构造,则无法修改该行为。

为了做你想做的事,我会使用ncurses。您似乎在Windows上使用python,因此您将不得不在如何获得等效功能方面进行一些挖掘。看看这个主题:Curses alternative for windows