[编辑:] 我目前正在尝试制作一个小型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")
答案 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