Python TCP程序,反过来聊天,首先工作正常,但不知何故它被阻止?

时间:2017-09-09 16:24:50

标签: python tcp

首先我写一个聊天服务器

vpc_

然后是客户

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket, threading, time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 9999))

s.listen(3)
print('waiting for someone to chat with...')

def chatpro(sock, addr):
    print('Connection with %s:%s established!'%addr)
    sock.send(('Welcome: %s:%s'%addr).encode('utf-8'))
    while True:
        data = sock.recv(1024)
        if data.decode('utf-8') == 'exit':
            sock.send(('Bye: %s:%s' % addr).encode('utf-8'))
            break
        print('From %s:%s: \n'%addr, data.decode('utf-8'))
        print('Please say something:')
        smg = input()
        sock.send(smg.encode('utf-8'))
    sock.close()
    print('Connection closed!')


while True:
    sock, addr = s.accept()
    t = threading.Thread(target=chatpro, args=(sock, addr))
    t.start()

客户端首先会向服务器说些什么,然后服务器会向客户端说些什么。这很好用。 但是,如果我意外输入一个额外的Enter或者我没有依次说出来,那么程序会被阻止吗?然后我在服务器和客户端输入了一些内容,没有发生任何事情,为什么? 感谢!!!

1 个答案:

答案 0 :(得分:1)

服务器中的逻辑主要是:

1 send initial greeting
2 while True:
3    receive data from client
4    read line from terminal
5    send line to client

虽然您客户的逻辑是:

1 receive initial greeting
2 while True:
3     read line from terminal
4     send line to server
5     receive data from server
  

......我没有依次说些什么,然后程序会被阻止

如果客户端已从服务器接收数据,则客户端将仅传递第5行并从第3行重新开始。但是,如果用户在终端输入数据,服务器将仅发送数据。这意味着如果用户没有在服务器上输入数据,客户端将在第5行中阻止。

  

...如果我意外输入了额外的输入...那么该程序将被阻止

客户端和服务器使用input()从终端读取一行。如果您输入额外的Enter,则表示附加行。该行将在内部缓冲,直到下一个input(),然后立即返回此新行。因此,即使您的客户端刚刚从第5行的服务器收到消息,它也会立即再次通过第3行和第4行,并再次等待来自第5行服务器的数据。更糟糕的是,input()返回的空行第3行表示实际上没有数据在第4行发送。这意味着服务器没有等待来自客户端的数据,客户端正在等待服务器,即死锁。

对于正确的聊天应用程序,您需要处理来自对等方的接收和来自终端的独立输入,即不要求这些应用始终按照您当前的特定顺序进行。一种常见的方法是使用select。还有many examples on the internet which show how to do this