2010-12-14 5 views
1

Je fais une programmation socket/select et un de mes événements est déclenché par la chaîne d'octets entrants 'OK'. J'utilise utf_8 pour encoder tout ce qui est envoyé depuis le serveur et le décoder sur le client. Cependant, mes comparaisons client ne fonctionnent pas et mon instruction if ne donne jamais la valeur true. Voici le code en question:comparer des chaînes et unicode décodé dans python3

côté serveur:

def broadcast_string(self, data, omit_sock): # broadcasts data utf_8 encoded to all socks 
    for sock in self.descriptors: 
     if sock is not self.server and sock is not omit_sock: 
      sock.send(data.encode('utf_8')) 
    print(data) 

def start_game(self): # i call this to send 'OK' 
    data = 'OK' 
    self.broadcast_string(data, 0) 
    self.new_round() 

côté client:

else: # got data from server 
    if data.decode('utf_8') == 'OK': # i've tried substituting this with a var, no luck 
     self.playstarted = True 
    else: 
     sys.stdout.write(data.decode('utf_8') + "\n") 
     sys.stdout.flush() 

    if self.playstarted is True: # never reached because if statement never True 
     command = input("-->") 

J'ai lu this et je pense que je suis, mais apparemment pas. J'ai même fait les exemples en utilisant le shell python et les ai fait évaluer à True, mais pas quand j'ai lancé ce programme.

Merci!

+0

Vous devriez frapper le 'autre'. Quelles impressions? – Robert

+0

OK est imprimé sur stdout. Désolé, j'ai édité l'indentation pour le rendre plus clair. La dernière instruction if n'aurait pas dû être imbriquée dans le if, else. – Andrew

+0

Dans python3, est-ce que 'str' est toujours le nom du type? Parce que vous pourriez juste appeler la méthode de type. – Robert

Répondre

1

Les sockets TCP n'ont pas de frontières de message. Comme votre dernier commentaire dit que vous obtenez plusieurs messages dans une longue chaîne. Vous êtes responsable de la mise en file d'attente des données jusqu'à ce que vous ayez un message complet, puis le traitement en tant que message complet.

Chaque fois select dit qu'un socket a des données à lire, ajouter les données à un lire tampon, puis vérifiez si le tampon contient un message complet. Si c'est le cas, extrayez juste le message de l'avant du tampon et traitez-le. Continuez jusqu'à ce qu'aucun message plus complet ne soit trouvé, puis appelez à nouveau select. Notez également que vous ne devriez écrire qu'un message complet, car vous pourriez recevoir un caractère UTF-8 multi-octet partiel dans le cas contraire.

exemple rugueux à l'aide \n comme terminaison de message (pas de traitement d'erreur):

tmp = sock.recv(1000) 
readbuf += tmp 
while b'\n' in readbuf: 
    msg,readbuf = readbuf.split(b'\n',1) 
    process(msg.decode('utf8')) 
Questions connexes