如何防止errno 32管道破裂?


120

目前,我正在使用内置于python的应用程序。当我在个人计算机上运行它时,它可以正常工作。

但是,当我将其移至生产服务器时。它不断向我显示以下错误:

我进行了一些研究,得出的原因是,当服务器仍在忙于发送数据时,最终用户浏览器会停止连接。

我想知道为什么会发生这种情况,以及导致它在我的个人计算机上运行时阻止它在生产服务器中正常运行的根本原因是什么?任何建议表示赞赏

    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

请问这个 “解决”您的问题?
Pureferret

或用uwsgi连接等
KyungHoon金

Answers:


85

您的服务器进程已收到SIGPIPE对套接字的写入。当您写入另一端(客户端)完全关闭的套接字时,通常会发生这种情况。当客户端程序不等到接收到来自服务器的所有数据而只是关闭套接字(使用close函数)时,可能会发生这种情况。

在C程序中,通常会尝试设置忽略SIGPIPE信号或为其设置虚拟信号处理程序。在这种情况下,写入关闭的套接字时将返回一个简单的错误。在您的情况下,Python似乎抛出了一个异常,该异常可以作为客户端的过早断开连接进行处理。


2
对于处理客户端断开连接,这是一个很好的答案:stackoverflow.com/a/180922/276274
Maksim Skurydzin,2012年

9

这取决于您对其进行测试的方式,并且可能取决于个人计算机和服务器的TCP堆栈实现上的差异。

例如,如果您sendall总是在个人计算机上立即(或非常快地)完成操作,则连接在发送过程中可能永远不会中断。如果您的浏览器在同一台计算机上运行,​​则很有可能(因为没有实际的网络延迟)。


通常,您只需要通过处理异常来解决客户端断开连接之前的情况。

请记住,TCP通信是异步的,但这在物理远程连接上比在本地连接上更为明显,因此在本地工作站上很难再现这种情况。具体而言,单台计算机上的环回连接通常几乎是同步的。


我正在通过运行“ paster serve abc.ini --reload”进行测试,但是无法访问该网页。对于VMWare工作站,我正在使用“仅主机”选项进行网络连接。那么,您能建议任何方式正常运行它吗?
SƲmmērAƥ

1
我认为这是一个单独的VMWare网络配置问题(恐怕我对此一无所知)。工作站和服务器的行为可能有所不同的原因已在上面,而解决方案仅是使用以下方法来处理异常:try ... except
无用的2012年

7

如果您的请求被阻塞或花费的时间太长,通常会发生管道断开错误,并且在请求端超时后,它将关闭连接,然后,当响应端(服务器)尝试写入套接字时,它将抛出一个错误。管道损坏错误。


3

这可能是因为您使用两种方法将数据插入数据库中,这导致站点速度降低。

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('/')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.