Come evitare che il tubo rotto errno 32?


120

Attualmente sto usando un'app costruita in Python. Quando lo eseguo sul personal computer, funziona senza problemi.

Tuttavia, quando lo sposto in un server di produzione. Continua a mostrarmi l'errore allegato come di seguito :.

Ho fatto alcune ricerche e ho ottenuto il motivo per cui il browser dell'utente finale interrompe la connessione mentre il server è ancora impegnato a inviare dati.

Mi chiedo perché sia ​​successo e qual è la causa principale che gli impedisce di funzionare correttamente nel server di produzione, mentre funziona sul mio personal computer. Ogni consiglio è apprezzato

    Exception happened during processing of request from ('127.0.0.1', 34226)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 284, in
_handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe

Ha questa 'risolvere' il problema?
Pureferret

Oppure connettiti con uwsgi, ecc.
KyungHoon Kim

Risposte:


85

Il processo del server ha ricevuto una SIGPIPEscrittura su un socket. Questo di solito accade quando scrivi su un socket completamente chiuso sull'altro lato (client). Ciò potrebbe accadere quando un programma client non attende che tutti i dati dal server vengano ricevuti e chiude semplicemente un socket (utilizzando la closefunzione).

In un programma C normalmente proveresti a ignorare il SIGPIPEsegnale o a impostare un gestore di segnale fittizio per esso. In questo caso verrà restituito un semplice errore durante la scrittura su un socket chiuso. Nel tuo caso un python sembra lanciare un'eccezione che può essere gestita come una disconnessione prematura del client.


2
Ecco una buona risposta per quanto riguarda la movimentazione client si disconnette: stackoverflow.com/a/180922/276274
Maksim Skurydzin

9

Dipende da come l'hai testato e forse dalle differenze nell'implementazione dello stack TCP del personal computer e del server.

Ad esempio, se sendallsi completa sempre immediatamente (o molto rapidamente) sul personal computer, la connessione potrebbe non essere mai interrotta durante l'invio. Questo è molto probabile se il tuo browser è in esecuzione sulla stessa macchina (poiché non c'è una reale latenza di rete).


In generale, devi solo gestire il caso in cui un client si disconnette prima che tu abbia finito, gestendo l'eccezione.

Ricorda che le comunicazioni TCP sono asincrone, ma questo è molto più ovvio su connessioni fisicamente remote che su quelle locali, quindi condizioni come questa possono essere difficili da riprodurre su una workstation locale. In particolare, le connessioni loopback su una singola macchina sono spesso quasi sincrone.


Lo sto testando eseguendo "paster serve abc.ini --reload", tuttavia la pagina web non potrebbe mai essere raggiunta. E per VMWare Workstation, sto utilizzando l'opzione solo host per la connessione di rete. Quindi puoi gentilmente consigliare un modo per eseguirlo correttamente?
SƲmmēr Aƥ

1
Penso che sia una domanda separata sulla configurazione della rete VMWare (temo di non sapere nulla al riguardo). Il motivo per cui la workstation e il server possono comportarsi in modo diverso è sopra tuttavia, e la soluzione è solo quella di gestire l'eccezione contry ... except
Inutile

7

L'errore di pipe rotto di solito si verifica se la tua richiesta è bloccata o impiega troppo tempo e dopo il timeout sul lato richiesta, chiuderà la connessione e quindi, quando il lato risposta (server) prova a scrivere sul socket, lancerà un errore di tubo rotto.


3

Ciò potrebbe essere dovuto al fatto che stai utilizzando due metodi per inserire i dati nel database e questo fa rallentare il sito.

def add_subscriber(request, email=None):
    if request.method == 'POST':
        email = request.POST['email_field']
        e = Subscriber.objects.create(email=email).save()  <==== 
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/')

Nella funzione precedente, l'errore è dove punta la freccia. La corretta implementazione è di seguito:

def add_subscriber(request, email=None):
    if request.method == 'POST':
        email = request.POST['email_field']
        e = Subscriber.objects.create(email=email)
        return HttpResponseRedirect('/')
    else:
        return HttpResponseRedirect('/')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.