问题:如何防止errno 32管道破裂?

目前,我正在使用内置于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

Currently I am using an app built in python. When I run it in personal computer, it works without problems.

However, when I move it into a production server. It keeps showing me the error attached as below:.

I’ve done some research and I got the reason that the end user browser stops the connection while the server is still busy sending data.

I wonder why did it happen and what is the root cause that prevents it from running properly in production server, while it works on my personal computer. Any advice is appreciated

    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

回答 0

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

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

Your server process has received a SIGPIPE writing to a socket. This usually happens when you write to a socket fully closed on the other (client) side. This might be happening when a client program doesn’t wait till all the data from the server is received and simply closes a socket (using close function).

In a C program you would normally try setting to ignore SIGPIPE signal or setting a dummy signal handler for it. In this case a simple error will be returned when writing to a closed socket. In your case a python seems to throw an exception that can be handled as a premature disconnect of the client.


回答 1

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

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


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

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

It depends on how you tested it, and possibly on differences in the TCP stack implementation of the personal computer and the server.

For example, if your sendall always completes immediately (or very quickly) on the personal computer, the connection may simply never have broken during sending. This is very likely if your browser is running on the same machine (since there is no real network latency).


In general, you just need to handle the case where a client disconnects before you’re finished, by handling the exception.

Remember that TCP communications are asynchronous, but this is much more obvious on physically remote connections than on local ones, so conditions like this can be hard to reproduce on a local workstation. Specifically, loopback connections on a single machine are often almost synchronous.


回答 2

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

The broken pipe error usually occurs if your request is blocked or takes too long and after request-side timeout, it’ll close the connection and then, when the respond-side (server) tries to write to the socket, it will throw a pipe broken error.


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

This might be because you are using two method for inserting data into database and this cause the site to slow down.

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 above function, the error is where arrow is pointing. The correct implementation is below:

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

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。