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)!