2017-09-09 5 views
0

D'abord j'écrire un ChatServerPython TCP Program, le chat à son tour, fonctionne bien d'abord, mais de toute façon il a bloqué?

#!/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() 

et le client

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

import socket 

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
client.connect(('127.0.0.1', 9999)) 
print(client.recv(1024).decode('utf-8')) 
while True: 
    print('please say something:') 
    smg = input() 
    client.send(smg.encode('utf-8')) 
    re = client.recv(1024).decode('utf-8') 
    print(re) 
    if re[:3] == 'Bye': 
     print('Connection closed') 
     break 
client.close() 

Le client va d'abord dire quelque chose au serveur, et dire le serveur à son tour quelque chose au client. Cela fonctionne bien. Mais si j'ai tapé accidentellement une entrée supplémentaire ou que je n'ai pas dit quelque chose à son tour, alors le programme sera bloqué? Puis j'ai tapé quelque chose dans le serveur et le client et rien ne s'est passé, pourquoi? Merci !!!

+0

N'utilisez jamais 'socket' directement. Toujours utiliser 'twisted' ou équivalent. – o11c

Répondre

1

La logique de votre serveur est essentiellement:

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

Alors que la logique de votre client est:

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

... Je n'ai pas dit quelque chose à son tour, le le programme sera bloqué

Le client ne passera que la ligne 5 et recommencera avec la ligne 3 si h comme les données reçues du serveur. Mais le serveur n'enverra des données que si l'utilisateur a entré des données sur le terminal. Cela signifie que le client bloquera à la ligne 5 si l'utilisateur n'entre pas de données sur le serveur.

... si je tapais par mégarde un supplément ... Entrez alors le programme sera bloqué

Le client et l'utilisation du serveur input() pour lire une seule ligne à partir du terminal. Si vous tapez un caractère supplémentaire, cela signifie une ligne supplémentaire. Cette ligne sera tamponnée en interne jusqu'au prochain input() qui revient immédiatement avec cette nouvelle ligne. Ainsi, même si votre client vient de recevoir un message du serveur de la ligne 5, il passera immédiatement les lignes 3 et 4 et attendra de nouveau les données du serveur de la ligne 5. Pire encore, la ligne vide retournée par input() à la ligne 3 signifie que aucune donnée n'a été réellement envoyée à la ligne 4. Cela signifie que le serveur n'attend pas de données du client et que le client attend du serveur, c'est-à-dire un blocage. Pour des applications de chat appropriées, vous devez gérer la réception de l'homologue et l'entrée du terminal indépendamment les unes des autres, c'est-à-dire ne pas exiger qu'elles se produisent toujours dans un ordre spécifique comme vous le faites actuellement. Un moyen commun à ceci est en utilisant select. Et il y a many examples on the internet which show how to do this.