首先我写一个聊天服务器
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或者我没有依次说出来,那么程序会被阻止吗?然后我在服务器和客户端输入了一些内容,没有发生任何事情,为什么? 感谢!!!
答案 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。