如何在此Python本地聊天服务器中正确处理输入

时间:2014-07-30 22:50:34

标签: python networking connection chat

所以我得到了这个python服务器,它被禁止返回给客户端他/她输入的相同输入,但前面有“Ok you said:”。例如,如果客户端收到输入“Hello”,服务器应发送以下消息“Ok you said:Hello”。 问题是我的代码没有将完整的单词保存为输入,只保存单个字母。如果客户试图写“你好”,那么当他/她写第一个字母“h”时,它会自动收到“Ok you said:h”。只需在Window的CMD中写入“telnet localhost”和端口号即可创建客户端。希望我清楚自己。提前致谢。我是初学者,所以你们可能会在我的代码中发现其他错误,建议非常受欢迎!

代码:

#Server.py

#Importing Modules
import socket, sys, thread

#Variables
HOST = '' # I do this to be able to connect to all available computers
PORT = 1234 # Arbitrarily chosen

#Creating socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

#Binding socket
try:
    s.bind((HOST,PORT))
except socket.error, msg:
    print 'Bind failed. Error code : ' + str(msg[0]) + 'Message ' + msg[1]
    sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening...'


#Function for creating threads for every connection
def clientThread(conection):
    #Welcome Message
    conn.send('Welcome to the chat room. In order to exit type "exit-room" ' )

    #infinite loop so that function does not terminate and thread does not end
    while True:
        #receiving from client
        data = conn.recv(1024) 
        reply = 'Ok You said: ' + data
        if data == 'exit-room':
            break
        conn.sendall(reply)
    conn.close()

while True:
    #wait for incoming connection
    conn, addr = s.accept()
    # display client info
    print 'Connected with ' +addr[0] + ':' +str(addr[1])
    #now keep talking with client
    thread.start_new_thread(clientThread,((conn,)))

s.close()

1 个答案:

答案 0 :(得分:1)

你的问题有两个方面:

  1. Windows telnet立即将您的击键发送到服务器 。它不像Unix版本那样进行行缓冲。

  2. conn.recv阻止,直到它从客户端收到任何数据。由于Windows telnet正在发送按键,因此conn.recv一次不会返回超过1个字符。

  3. 解决方案是在服务器端实现行缓冲:

    # oops! you seemed to have misnamed the parameter, so I fixed it for you
    def clientThread (conn):
        try:
            conn.send('Welcome to the chat room. In order to exit type "exit-room" ' )
            # makefile creates a file-like object (with a readline method)
            # from a socket. "r" means read-only mode, and 1 means line-buffered
            connfile = conn.makefile("r", 1)
            try:
                while True:
                    # readline will block until a newline '\n' is encountered
                    # or the stream is closed
                    data = connfile.readline(1024)
                    # the readline method includes the trailing newlines,
                    # so we want to strip them
                    data = data.rstrip("\r\n")
                    reply = 'Ok You said: ' + data
                    if data == 'exit-room':
                        break
                    conn.sendall(reply + "\r\n")
            finally:
                connfile.close()
        finally:
            # put this line in a finally block so it gets
            # executed even when an exception is thrown
            conn.close()
    

    socket.makefile的参数与内置open函数的参数相同:

    https://docs.python.org/2/library/socket.html#socket.socket.makefile

    https://docs.python.org/2/library/functions.html#open