Wie vermeide ich Fehler 32 Rohrbruch?


120

Derzeit verwende ich eine in Python integrierte App. Wenn ich es auf einem PC ausführe, funktioniert es ohne Probleme.

Wenn ich es jedoch auf einen Produktionsserver verschiebe. Es zeigt mir immer wieder den Fehler wie folgt:

Ich habe einige Nachforschungen angestellt und festgestellt, dass der Endbenutzer-Browser die Verbindung beendet, während der Server noch Daten sendet.

Ich frage mich, warum es passiert ist und was die Hauptursache ist, die verhindert, dass es auf dem Produktionsserver ordnungsgemäß ausgeführt wird, während es auf meinem PC funktioniert. Jeder Rat wird geschätzt

    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

Löst dies Ihr Problem?
Pureferret

Oder verbinden Sie sich mit uwsgi usw.
KyungHoon Kim

Antworten:


85

Ihr Serverprozess hat ein SIGPIPESchreiben an einen Socket erhalten. Dies geschieht normalerweise, wenn Sie in einen Socket schreiben, der auf der anderen (Client-) Seite vollständig geschlossen ist. Dies kann passieren, wenn ein Client-Programm nicht wartet, bis alle Daten vom Server empfangen wurden, und einfach einen Socket schließt (mithilfe der closeFunktion).

In einem C-Programm würden Sie normalerweise versuchen, das SIGPIPESignal zu ignorieren oder einen Dummy-Signalhandler dafür einzustellen. In diesem Fall wird beim Schreiben in einen geschlossenen Socket ein einfacher Fehler zurückgegeben. In Ihrem Fall scheint eine Python eine Ausnahme auszulösen, die als vorzeitige Trennung des Clients behandelt werden kann.


2
Hier ist eine gute Antwort bezüglich der Behandlung von Client-Trennungen: stackoverflow.com/a/180922/276274
Maksim Skurydzin

9

Dies hängt davon ab, wie Sie es getestet haben, und möglicherweise von Unterschieden in der TCP-Stack-Implementierung des PCs und des Servers.

Wenn Sie beispielsweise sendallauf dem PC immer sofort (oder sehr schnell) fertig sind, ist die Verbindung beim Senden möglicherweise nie unterbrochen. Dies ist sehr wahrscheinlich, wenn Ihr Browser auf demselben Computer ausgeführt wird (da keine echte Netzwerklatenz vorliegt).


Im Allgemeinen müssen Sie nur den Fall behandeln, in dem ein Client die Verbindung trennt, bevor Sie fertig sind, indem Sie die Ausnahme behandeln.

Denken Sie daran, dass die TCP-Kommunikation asynchron ist. Dies ist jedoch bei physisch entfernten Verbindungen viel offensichtlicher als bei lokalen Verbindungen. Daher kann es schwierig sein, solche Bedingungen auf einer lokalen Workstation zu reproduzieren. Insbesondere sind Loopback-Verbindungen auf einer einzelnen Maschine häufig nahezu synchron.


Ich teste es, indem ich "paster serve abc.ini --reload" ausführe, aber die Webseite konnte nie erreicht werden. Und für die VMWare Workstation verwende ich die Option "Nur Host" für die Netzwerkverbindung. Können Sie uns also einen Rat geben, wie Sie es richtig ausführen können?
SƲmmēr Aƥ

1
Ich denke, das ist eine separate Frage zur VMWare-Netzwerkkonfiguration (ich fürchte, ich weiß nichts darüber). Der Grund, warum sich Workstation und Server möglicherweise unterschiedlich verhalten, ist oben angegeben, und die Lösung besteht nur darin, die Ausnahme mittry ... except
Nutzlos

7

Der Fehler bei einer unterbrochenen Pipe tritt normalerweise auf, wenn Ihre Anforderung blockiert ist oder zu lange dauert. Nach einem anforderungsseitigen Timeout wird die Verbindung geschlossen. Wenn die Antwortseite (der Server) versucht, in den Socket zu schreiben, wird ein Fehler ausgelöst Rohrbruchfehler.


3

Dies kann daran liegen, dass Sie zwei Methoden zum Einfügen von Daten in die Datenbank verwenden und die Site dadurch langsamer wird.

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

In der obigen Funktion zeigt der Fehler, wohin der Pfeil zeigt. Die korrekte Implementierung ist unten:

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('/')
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.