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

Source: Internet
Author: User
Tags curl flush readline unsupported in python

The example in this article tells the python hint [Errno 32]broken pipe causes a thread crash error resolution. Share to everyone for your reference. The specific methods are as follows:

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

Copy Code code 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):
"""
Handling 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)
Except 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

#多线程处理
Class Threadinghttpserver (Threadingmixin,httpserver):
Pass

if __name__ = = ' __main__ ':
Serveraddr = (', 9001)

Ser = Threadinghttpserver (Serveraddr,requesthandler)
Ser.serve_forever ()
Sys.exit (0)

Running Services
./thread_http_server_error.py
1th time Curl, waiting to return
Copy Code code as follows:
[~] $curl-S ' http://10.232.41.142:9001/hello1′
At this point the server-side 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 time Curl, do not wait to return, CTRL +C to simulate client disconnect
Copy Code code as follows:
[~] $curl-S ' http://10.232.41.142:9001/hello2′
[~]$ Ctrl + C

At this point the server-side output log is as follows:
Copy Code code 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 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. Causal analysis

"[Errno] broken pipe" The reason is relatively clear, because the client in the server before the return of the active disconnect, so the server on the return write socket received sigpipe error. Although exceptions are also processed in our programs, close the handler Wfile._sock object, but the member functions of the Basehttprequesthandler class in Python's library basehttpserver.py handle _one_request will still call Wfile.flush directly, without determining if wfile is close.

Copy Code code as follows:
def handle_one_request (self):
"" "Handle a single HTTP request.

You are normally don ' t need to override this method; The class
__doc__ string for information on I 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 ()
#没有判断 Wfile is already close, call flush directly ()
Self.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. Solutions

As long as you overload the member function Handle_one_reques () of its base class Basehttprequesthandler in RequestHandler, precede the call to Wfile.flush () plus whether the wfile is close.

Copy Code code 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 are normally don ' t need to override this method; The class
__doc__ string for information on I 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 ()
#增加 Debug Info and Wfile to determine if close
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 ()"
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):
"""
Handling 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)
Except 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

#多线程处理
Class Threadinghttpserver (Threadingmixin,httpserver):
Pass

if __name__ = = ' __main__ ':
Serveraddr = (', 9001)

Ser = Threadinghttpserver (Serveraddr,requesthandler)
Ser.serve_forever ()
Sys.exit (0)


Running Services
./thread_http_server.py
Curl, do not wait to return, CTRL +C to simulate client disconnect
Copy Code code as follows:
[~] $curl-S ' Http://10.232.41.142:9001/hello2 '
[~]$ Ctrl + C

At this point the server-side output log is as follows:
Copy Code code as follows:
$./thread_http_server.pybefore Call Do_get
Query:/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 Pipe
After the call Do_get
After Wfile.flush ()

I hope this article will help you with your Python programming.

Related Article

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.