2011-06-04 14 views
10

Soy un novato en la programación de la red, así que por favor, discúlpeme si esta es una pregunta tonta :) Creé 1 cliente y servidor 1 SocketServer.ThreadingMixIn en Ubuntu 10.04.2 utilizando Python2.7, pero parece que sólo puedo llamar sock.send() una vez en el cliente, entonces voy a conseguir una:Python socket.send() solo puede enviar una vez, luego socket.error: [Errno 32] Se produjo una tubería rota

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

aquí está el código que escribí:

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() 

que ellos corrió en 2 terminales separadas:

salida del primero de terminal:

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

salida del segundo terminal de:

$ 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 

Intenté llamar a sock.send() dos veces di tamente en testClient.py, para excepto:

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

pero las salidas de los terminales siguen siendo los mismos :( Puede alguien por favor señalar lo que estoy haciendo mal aquí? Thx in adv!

Aquí está el [Sol] que se me ocurrió. Gracias Marcos :)

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() 

Respuesta

14

mango() se llama en el SocketServer.StreamRequestHandler una vez por cada conexión . Si regresa de handle, la conexión está cerrada.

Si desea que el servidor maneje más de un envío/recepción, debe repetir hasta que recv() devuelva 0, indicando que el cliente cerró la conexión (o al menos llamado shutdown() en envíos).

También tenga en cuenta que TCP es un protocolo de transmisión. Tendrá que diseñar un protocolo de mensaje que indique la longitud o el final de un mensaje, y el buffer recv hasta que tenga un mensaje completo. Compruebe send valor de retorno para asegurarse de que también se envíe todo el mensaje, o use sendall.

+0

¡Gracias por la información! Finalmente lo hice funcionar :) – hencrice

+0

gracias, yo también tenía el mismo problema. Me pregunto por qué esto no está incluido en la documentación de SocketServer. ¿Sabes dónde puedo encontrar el documento detallado en SocketServer.TCPServer? –

+0

@PunitSoni, el archivo 'SocketServer.py' es muy simple. Es instructivo leer la fuente. –

Cuestiones relacionadas