2011-06-04 2 views
10

Je suis un débutant dans la programmation réseau, alors s'il vous plaît pardonnez-moi si c'est une question stupide :) J'ai créé 1 client et 1 serveur SocketServer.ThreadingMixIn sur Ubuntu 10.04.2 utilisant python2.7, mais il semble que je ne peux appeler sock.send() une fois dans le client, alors je vais un:Python socket.send() ne peut envoyer qu'une fois, puis socket.error: [Errno 32] Broken pipe s'est produite

Traceback (most recent call last): 
    File "testClient1.py", line 33, in <module> 
    sock.send('c1:{0}'.format(n)) 
socket.error: [Errno 32] Broken pipe 

Voici le code que j'ai écrit:

testClient1.py:

#! /usr/bin/python2.7 
# -*- coding: UTF-8 -*- 
import sys,socket,time,threading 
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
try: 
    sock.connect(('localhost',20000)) 
except socket.error: 
    print('connection error') 
    sys.exit(0) 
n=0 
while n<=1000: 
    sock.send('c1:{0}'.format(n)) 
    result=sock.recv(1024) 
    print(result) 
    n+=1 
    time.sleep(1) 

testServer.py:

#! /usr/bin/python2.7 
# -*- coding: UTF-8 -*- 
import threading,SocketServer,time 

class requestHandler(SocketServer.StreamRequestHandler): 
    #currentUserLogin={} #{clientArr:accountName} 
    def handle(self): 
     requestForUpdate=self.rfile.read(4) 
     print(requestForUpdate) 
     self.wfile.write('server reply:{0}'.format(requestForUpdate)) 

class broadcastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    pass 

if __name__ == '__main__': 

    server=broadcastServer(('localhost',20000),requestHandler) 
    t = threading.Thread(target=server.serve_forever) 
    t.daemon=True 
    t.start() 
    print('server start') 
    n=0 
    while n<=60: 
     print(n) 
     n+=1 
     time.sleep(1) 
    server.socket.close() 

Je les ai couru dans 2 bornes séparées:

sortie du 1er terminal:

$ python2.7 testServer.py 
server start 
0 
1 
2 
3 
4 
c1:0 
5 
6 
7 
8 
9 
10 
11 
... 

sortie du 2ème terminal:

$ python2.7 testClient1.py 
server reply:c1:0 

Traceback (most recent call last): 
    File "testClient1.py", line 33, in <module> 
    sock.send('c1:{0}'.format(n)) 
socket.error: [Errno 32] Broken pipe 

J'ai essayé d'appeler sock.send() deux fois par jour rectement dans testClient.py, Ex:

while n<=1000: 
     sock.send('c1:{0}'.format(n)) 
     sock.send('12333')  
     result=sock.recv(1024) 
     print(result) 
     n+=1 
     time.sleep(1) 

mais les sorties des terminaux sont toujours les mêmes :( Quelqu'un peut-il s'il vous plaît indiquer ce que je fais mal ici? Thx dans adv!

Voici le [Sol] que j'ai inventé. Merci :) Mark

testClient1.py:

import sys,socket,time 
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
try: 
    sock.connect(('localhost',20000)) 
except socket.error: 
    print('connection error') 
    sys.exit(0) 
n=0 
while n<=10: #connect once 
    sock.send('c1:{0}'.format(n)) 
    result=sock.recv(1024) 
    print(result)  
    n+=1 
    time.sleep(1) 
sock.close() 

#once you close a socket, you'll need to initialize it again to another socket obj if you want to retransmit 
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
try: 
    sock.connect(('localhost',20000)) 
except socket.error: 
    print('connection error') 
    sys.exit(0) 
n=0 
while n<=10: #connect once 
    sock.send('c3:{0}'.format(n)) 
    result=sock.recv(1024) 
    print(result)  
    n+=1 
    time.sleep(1) 
sock.close() 

testServer.py:

import threading,SocketServer,time 

class requestHandler(SocketServer.StreamRequestHandler): 
    #currentUserLogin={} #{clientArr:accountName} 
    def handle(self): 
     requestForUpdate=self.request.recv(1024) 
     print(self.client_address) 
     while requestForUpdate!='':   
      print(requestForUpdate) 
      self.wfile.write('server reply:{0}'.format(requestForUpdate)) 
      requestForUpdate=self.request.recv(1024) 
     print('client disconnect') 

class broadcastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    pass 

if __name__ == '__main__': 

    server=broadcastServer(('localhost',20000),requestHandler) 
    t = threading.Thread(target=server.serve_forever) 
    t.daemon=True 
    t.start() 
    print('server start') 
    n=0 
    while n<=60: 
     print(n) 
     n+=1 
     time.sleep(1) 
    server.socket.close() 

Répondre

14

poignée() est appelée dans la SocketServer.StreamRequestHandler une fois pour chaque connexion . Si vous revenez de handle, la connexion est fermée.

Si vous souhaitez que le serveur gère plus d'un envoi/retrait, vous devez effectuer une boucle jusqu'à ce que recv() renvoie 0, indiquant que le client a fermé la connexion (ou au moins appelé shutdown()).

Notez également que TCP est un protocole de diffusion. Vous devrez concevoir un protocole de message qui indique la longueur ou la fin d'un message, et mettre le tampon recv jusqu'à ce que vous ayez un message complet. Vérifiez la valeur de retour send pour vous assurer que tout le message est également envoyé, ou utilisez sendall.

+0

Thx pour l'info !! J'ai finalement réussi à travailler :) – hencrice

+0

merci, j'avais aussi le même problème. Je me demande pourquoi ce matériel n'est pas inclus dans la documentation de SocketServer. Savez-vous où je peux trouver le document détaillé sur SocketServer.TCPServer? –

+0

@PunitSoni, le fichier 'SocketServer.py' est très simple. Il est instructif de simplement lire la source. –

Questions connexes