如何防止errno 32破pipe?

目前我正在使用python构build的应用程序。 当我在个人电脑上运行它,它没有任何问题。

但是,当我把它移到生产服务器。 它不断显示我附带的错误如下:

我已经做了一些研究,并得到了最终用户浏览器在服务器仍在忙于发送数据时停止连接的原因。

我想知道为什么会发生,什么是阻止它在生产服务器上正常运行的根本原因,而在个人计算机上运行。 任何意见表示赞赏

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 

您的服务器进程已收到SIGPIPE写入套接字。 这通常发生在写入另一个(客户端)完全closures的套接字时。 当一个客户端程序不等待,直到收到所有来自服务器的数据,并简单地closures一个套接字(使用closefunction)时,可能会发生这种情况。

在C程序中,您通常会尝试设置忽略SIGPIPE信号或为其设置一个虚拟信号处理程序。 在这种情况下,写入一个封闭的套接字时会返回一个简单的错误。 在你的情况python似乎抛出一个exception,可以作为客户端的提前断开处理。

这取决于你如何testing它,也可能取决于个人计算机和服务器的TCP堆栈实现的差异。

例如,如果sendall总是立即(或很快)在个人计算机上完成,那么在发送过程中连接可能根本不会中断。 如果您的浏览器运行在同一台计算机上,这很可能(因为没有真正的networking延迟)。


一般情况下,您只需处理客户端在完成之前断开连接的情况,即可处理exception。

请记住,TCP通信是asynchronous的,但在物理远程连接上比本地连接要明显得多,所以在本地工作站上很难重现这种情况。 具体而言,单个机器上的回送连接通常几乎是同步的。

如果请求被阻塞或者需要太长时间,并且在请求端超时之后,它会closures连接,然后当响应端(服务器)试图写入套接字时,它会抛出一个pipe道破碎的错误。

这可能是因为您正在使用两种方法将数据插入到数据库中,导致网站速度变慢。

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

在上面的函数中,错误是箭头指向的地方。 正确的实施如下:

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