Python hint [Errno 32]broken pipe causes thread crash error resolution

Source: Internet
Author: User
Tags unsupported
This example describes the Python hint [Errno 32]broken pipe causes thread crash error resolution. Share to everyone for your reference. Here's how:

1. Error phenomena
Threadinghttpserver implementation of the HTTP service, if the client is actively disconnected before the server returns, the server will report [Errno] broken pipe error, and cause the processing thread crash.
Let's take a look at the following example, Python version: 2.7
Sample code

The code is as follows:

#!/usr/bin/env python#!coding=utf-8 Import osimport timeimport socketimport threadingfrom BaseHTTPServer Import Httpserver, Basehttprequesthandlerfrom socketserver import threadingmixin class RequestHandler ( Basehttprequesthandler): def do_get (self): "" "Handle GET Request" "" Query=self.path PR  int "Query:%s thread=%s"% (query, str (Threading.current_thread ())) #ret_str = "

Running the service
./thread_http_server_error.py
1th time Curl, waiting to return

The code is as follows:

[~] $curl-S ' http://10.232.41.142:9001/hello1′[~]$ this time the server-side output log is as follows: $./thread_http_server_error.pyquery:/hello1 Thread =search041142.sqa.cm4.tbsite.net–-[15/may/2014 15:02:27] "get/hello1 http/1.1″200-success prod query:/hello1


2nd time Curl, do not wait to return, CTRL +c to impersonate client disconnects

The code is as follows:

[~] $curl-S ' http://10.232.41.142:9001/hello2′[~]$ Ctrl + C


At this point the server-side output logs are as follows:

The 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] Broken pipe —————————————-Exception happened during processing of request from (' 10.232.41.142′, 48769) Traceback (most recent): File "/home/wuzhu/tools/python_2_7_1/lib/python2.7/socketserver.py", line 582, in Process_request_threadself.finish_request (Request, client_address) File "/home/wuzhu/tools/python_2_7_1/lib/ python2.7/socketserver.py ", line 323, in Finish_requestself. 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 Handleself.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 Flushself._sock.sendall (view[write_offset:write_offset +buffer_size]) Attributeerror: ' Nonetype ' object has no attribute ' Sendall '

2. Cause analysis

"[Errno] broken pipe" cause is still relatively clear, because the client in the server before the return of the active disconnection, so the server on the return to write the socket received sigpipe error. Although the exception is also handled in our program, the Wfile._sock object of handler is close, but the member function of the Basehttprequesthandler class in the Python library basehttpserver.py handle _one_request will still call Wfile.flush directly, without judging if wfile is already close.

The 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 what 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 (4  return if not self.raw_requestline:self.close_connection = 1 return if Not Self.parse_request (): # A error code has been sent, just exit return mname = ' do_ ' + SE            Lf.command if not hasattr (self, Mname): Self.send_error (501, "Unsupported Method (%r)"% Self.command) return method = GetAttr (self, Mname) method () #没有判断 whether the Wfile has been close immediately call flush () s Elf.wfile.flush () #actually send The response if not already done.  Except 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. Workaround

As long as the member function handle_one_reques () of the base class Basehttprequesthandler is overloaded with RequestHandler, add wfile before calling Wfile.flush () to be close.

The code is as follows:

#!/usr/bin/env python#!coding=utf-8import osimport timeimport socketimport threadingfrom BaseHTTPServer Import Httpserver, basehttprequesthandlerfrom socketserver import Threadingmixinclass 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 what to handle specific HTTP commands such as GET and POST. "" "Try:self.raw_requestline = Self.rfile.readline (65537) If Len (Self.raw_requestlin  e) > 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 (): # A error code has been          Sent, just exit      return mname = ' Do_ ' + Self.command if not hasattr (self, mname): Self.send_erro            R (501, "Unsupported Method (%r)"% Self.command) return method = GetAttr (self, mname) Print "Before Call Do_get" method () #增加 Debug Info and wfile determine if close print "After Cal L Do_get "if not Self.wfile.closed:self.wfile.flush () #actually Send the response if not alread            Y done.  Print "After Wfile.flush ()" Except 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): "" "Handle GET Request" "Query=self.path print" query:%s t hread=%s "% (query, str (Threading.current_thread ())) ret_str=" 


Running the service
./thread_http_server.py
Curl, do not wait to return, CTRL +c to impersonate client disconnects

Copy the Code code as follows:

[~] $curl-S ' Http://10.232.41.142:9001/hello2 ' [~]$ Ctrl + C


At this point the server-side output logs are as follows:

$./thread_http_server.pybefore call Do_getquery:/hello2 thread=<thread (Thread-1, started 1103210816) > Search041142.sqa.cm4.tbsite.net--[15/may/2014 15:54:09] "Get/hello2 http/1.1" 200-socket.error:connection broke. Aborting[errno] Broken Pipeafter call Do_getafter Wfile.flush ()


Above is the Python hint [Errno 32]broken pipe causes thread crash Error resolution content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • 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.