Python prompts [Errno 32] How to Solve the thread crash error caused by Broken pipe, errnocrash

Source: Internet
Author: User
Tags unsupported

Python prompts [Errno 32] How to Solve the thread crash error caused by Broken pipe, errnocrash

This example describes how to solve the thread crash error caused by the Python prompt [Errno 32] Broken pipe. Share it with you for your reference. The specific method is as follows:

1. Error
The http service implemented by ThreadingHTTPServer. If the client proactively disconnects the connection before the server returns, the server reports [Errno 32] Broken pipe error and causes the processing thread crash.
Next, let's take a look at an example. python version: 2.7
Sample Code
Copy codeThe Code is as follows :#! /Usr/bin/env python
#! Coding = UTF-8

Import OS
Import time
Import socket
Import threading
From BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
From SocketServer import ThreadingMixIn

Class RequestHandler (BaseHTTPRequestHandler ):
Def do_GET (self ):
"""
Process get requests
"""
Query = self. path
Print "query: % s thread = % s" % (query, str (threading. current_thread ()))

# Ret_str = "Ret_str = "
Time. sleep (5)

Try:
Self. send_response (200)
Self. send_header ('content-type', 'text/html ')
Self. end_headers ()
Self. wfile. write (ret_str)
Failed t socket. error, e:
Print "socket. error: Connection broke. Aborting" + str (e)
Self. wfile. _ sock. close () # close socket
Self. wfile. _ sock = None
Return False

Print "success prod query: % s" % (query)
Return True

# Multithreading
Class ThreadingHTTPServer (ThreadingMixIn, HTTPServer ):
Pass

If _ name _ = '_ main __':
Server ADDR = ('', 9001)
 
Ser = ThreadingHTTPServer (serveraddr, RequestHandler)
Ser. serve_forever ()
Sys. exit (0)
Running Service
./Thread_http_server_error.py
1st times curl, waiting for return
Copy codeThe Code is as follows: [~] $ Curl-s 'HTTP: // 10.232.41.142: 9001/hello1 ′
<Html>/hello1 <br> <__main _. ThreadingHTTPServer instance at 0x37483b0> The server output log is as follows:
$./Thread_http_server_error.py
Query:/hello1 thread =
Search041142.sqa.cm4.tbsite.net--[15/May/2014 15:02:27] "GET/hello1 HTTP/1.1" 200-
Success prod query:/hello1
2nd times curl, do not wait for the return, ctrl + C to simulate client disconnection
Copy codeThe Code is as follows: [~] $ Curl-s 'HTTP: // 10.232.41.142: 9001/hello2 ′
[~] $ Ctrl + C
The server output log is as follows:
Copy codeThe Code is as follows: query:/hello2 thread =
Search041142.sqa.cm4.tbsite.net--[15/May/2014 15:33:10] "GET/hello2 HTTP/1.1" 200-
Socket. error: Connection broke. Aborting [Errno 32] Broken pipe
--------------
Exception happened during processing of request from ('10. 232.41.142 ', 48769)
Traceback (most recent call last ):
File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/SocketServer. py", line 582, in process_request_thread
Self. finish_request (request, client_address)
File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/SocketServer. py", line 323, in finish_request
Self. RequestHandlerClass (request, client_address, self)
File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/SocketServer. py", line 639, in _ init __
Self. handle ()
File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/BaseHTTPServer. py", line 337, in handle
Self. handle_one_request ()
File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/BaseHTTPServer. py", line 326, in handle_one_request
Self. wfile. flush () # actually send the response if not already done.
File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/socket. py", line 303, in flush
Self. _ sock. sendall (view [write_offset: write_offset + buffer_size])
AttributeError: 'nonetype 'object has no attribute 'sendall'

2. Cause Analysis

The reason for "[Errno 32] Broken pipe" is clear. Because the client proactively disconnects the connection before the server returns the result, the server writes the socket to report an error when receiving the SIGPIPE message. Although the exception is also handled in our program, the handler wfile. _ sock object closed, but BaseHTTPServer In the python library. in py, The BaseHTTPRequestHandler class member function handle_one_request still directly calls wfile. flush, but does not judge whether wfile has been closed.
Copy codeThe Code is as follows: def handle_one_request (self ):
"" Handle a single HTTP request.
 
You normally don't need to override this method; see the class
_ Doc _ string for information on how to handle specific HTTP
Commands such as GET and POST.
 
"""
Try:
Self. raw_requestline = self. rfile. readline (65537)
If len (self. raw_requestline)> 65536:
Self. requestline =''
Self. request_version =''
Self. command =''
Self. send_error (414)
Return
If not self. raw_requestline:
Self. close_connection = 1
Return
If not self. parse_request ():
# An error code has been sent, just exit
Return
Mname = 'do _ '+ self. command
If not hasattr (self, mname ):
Self. send_error (501, "Unsupported method (% r)" % self. command)
Return
Method = getattr (self, mname)
Method ()
# Directly call flush () without judging whether wfile has been closed ()
Self. wfile. flush () # actually send the response if not already done.
Failed t socket. timeout, e:
# A read or a write timed out. Discard this connection
Self. log_error ("Request timed out: % r", e)
Self. close_connection = 1
Return
3. Solution

You only need to reload the member function handle_one_reques () of the base class BaseHTTPRequestHandler in RequestHandler and add wfile close before calling wfile. flush.
Copy codeThe Code is as follows :#! /Usr/bin/env python
#! Coding = UTF-8

Import OS
Import time
Import socket
Import threading
From BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
From SocketServer import ThreadingMixIn

Class RequestHandler (BaseHTTPRequestHandler ):

Def handle_one_request (self ):
"" Handle a single HTTP request.
 
You normally don't need to override this method; see the class
_ Doc _ string for information on how to handle specific HTTP
Commands such as GET and POST.
 
"""
Try:
Self. raw_requestline = self. rfile. readline (65537)
If len (self. raw_requestline)> 65536:
Self. requestline =''
Self. request_version =''
Self. command =''
Self. send_error (414)
Return
If not self. raw_requestline:
Self. close_connection = 1
Return
If not self. parse_request ():
# An error code has been sent, just exit
Return
Mname = 'do _ '+ self. command
If not hasattr (self, mname ):
Self. send_error (501, "Unsupported method (% r)" % self. command)
Return
Method = getattr (self, mname)
Print "before call do_Get"
Method ()
# Add debug info and wfile to determine whether it has been closed
Print "after call do_Get"
If not self. wfile. closed:
Self. wfile. flush () # actually send the response if not already done.
Print "after wfile. flush ()"
Failed t socket. timeout, e:
# A read or a write timed out. Discard this connection
Self. log_error ("Request timed out: % r", e)
Self. close_connection = 1
Return

Def do_GET (self ):
"""
Process get requests
"""
Query = self. path
Print "query: % s thread = % s" % (query, str (threading. current_thread ()))
 
Ret_str = " 
Time. sleep (5)

Try:
Self. send_response (200)
Self. send_header ('content-type', 'text/html ')
Self. end_headers ()
Self. wfile. write (ret_str)
Failed t socket. error, e:
Print "socket. error: Connection broke. Aborting" + str (e)
Self. wfile. _ sock. close ()
Self. wfile. _ sock = None
Return False

Print "success prod query: % s" % (query)
Return True
 
# Multithreading
Class ThreadingHTTPServer (ThreadingMixIn, HTTPServer ):
Pass

If _ name _ = '_ main __':
Server ADDR = ('', 9001)
 
Ser = ThreadingHTTPServer (serveraddr, RequestHandler)
Ser. serve_forever ()
Sys. exit (0)
Running Service
./Thread_http_server.py
Curl, do not wait to return, ctrl + C to simulate client disconnection
Copy codeThe Code is as follows: [~] $ Curl-s 'HTTP: // 10.232.41.142: 9001/hello2'
[~] $ Ctrl + C
The server output log is as follows:
Copy codeThe Code is as follows: $./thread_http_server.pybefore call do_Get
Query:/hello2 thread = <Thread (Thread-1, started1103210816)>
Search041142.sqa.cm4.tbsite.net--[15/May/2014 15:54:09] "GET/hello2 HTTP/1.1" 200-
Socket. error: Connection broke. Aborting [Errno 32] Broken pipe
After call do_Get
After wfile. flush ()
I hope this article will help you with Python programming.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.