es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obteniendo BrokenPipeError: [Errno 32] Tubería rota al enviar el segundo mensaje del socket.

Estoy intentando enviar instrucciones desde un sitio web Django a un robot (Raspberry Pi) utilizando sockets, pero cada vez que intento enviar una segunda instrucción desde el sitio web, me da un error. Si tienes alguna idea de lo que está causando esto, ¡la ayuda sería increíble!

Vista de envío del sitio web:

def form_valid(self, form, **kwargs):
    robo_pk = self.kwargs['pk']
    robo = Robot.objects.get(pk=robo_pk)
    PORT = robo.port
    SERVER = robo.server
    ADDR = (SERVER, PORT)
    self.object = form.save()
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(ADDR)

    def send(msg):
        message = msg.encode(FORMAT)
        msg_length = len(message)
        send_length = str(msg_length).encode(FORMAT)
        send_length += b' ' * (HEADER - len(send_length))
        client.send(send_length)
        client.send(message)

    send(form.cleaned_data['path_options'])
    send("¡MENSAJE ENVIADO :)!")
    send(DISCONNECT_MESSAGE)
    return render(self.request, "dashboard-home/thank-you.html")
ERROR TRACEBACK:

Traceback (most recent call last):
File “/usr/lib/python3.7/threading.py”, line 917, in _bootstrap_inner
self.run()
File “/usr/lib/python3.7/threading.py”, line 865, in run
self.target(*self.args, **self.kwargs)
File “main.py”, line 46, in handle_client
conn.send(“MSG Received”.encode(FORMAT))
BrokenPipeError: [Errno 32] Broken pipe

Código relevante:
def handle_client(conn, addr):
    print(f"[NUEVA CONEXIÓN] {addr} conectado")
    connected = True
    while connected:
        msg_length = conn.recv(HEADER).decode(FORMAT)
        if msg_length:
            msg_length = int(msg_length)
            msg = conn.recv(msg_length).decode(FORMAT)
            if msg == '!DISCONNECT!':
                connected = False
                print("desconectar")
                break
            else:
                my_queue.put(msg)
            print(f"[{ADDR}] {msg}")
            conn.send("MSG Received".encode(FORMAT))
    conn.close()

def start():
    server.listen()
    print(f"[ESCUCHANDO] El servidor está escuchando en {SERVER}")
    while True:
        print("antes")
        conn, addr = server.accept()
        print("después")
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
        print(f"[CONEXIONES ACTIVAS] {threading.activeCount()}")

print("[Iniciando] Servidor")
threading.Thread(target=start).start()

msg = my_queue.get()
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El error traceback indica un BrokenPipeError, lo que significa que la conexión se cerró de forma inesperada. Esto puede estar sucediendo porque el servidor está tratando de enviar un mensaje a un cliente que ya se ha desconectado.

    En el código relevante, la función handle_client es la responsable de manejar las conexiones entrantes. Recibe mensajes del cliente y los coloca en una cola para su procesamiento. Sin embargo, también intenta enviar un mensaje de confirmación de vuelta al cliente utilizando el método conn.send().

    Si el cliente se ha desconectado antes de que se envíe el mensaje de confirmación, se producirá un BrokenPipeError.

    Para solucionar este problema, puedes agregar una comprobación para ver si el cliente aún está conectado antes de enviar el mensaje de confirmación. Puedes hacer esto envolviendo la llamada conn.send() en un bloque try-except, capturando el BrokenPipeError y cerrando la conexión si esto ocurre.

    Aquí tienes una versión actualizada de la función handle_client que incluye esta comprobación:

    def handle_client(conn, addr):
        print(f"[NUEVA CONEXIÓN] {addr} conectado")
        connected = True
        while connected:
            msg_length = conn.recv(HEADER).decode(FORMAT)
            if msg_length:
                msg_length = int(msg_length)
                msg = conn.recv(msg_length).decode(FORMAT)
                if msg == '!DESCONECTAR!':
                    connected = False
                    print("desconectar")
                    break
                else:
                    my_queue.put(msg)
                print(f"[{ADDR}] {msg}")
                try:
                    conn.send("MSG Recibido".encode(FORMAT))
                except BrokenPipeError:
                    print(f"[{addr}] Cliente desconectado de forma inesperada")
                    connected = False
        conn.close()
    

Comments are closed.