Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
本文实例讲述了Python提示[Errno 32]Broken pipe导致线程crash错误解决方法。分享给大家供大家参考。具体方法如下:
1. 错误现象
ThreadingHTTPServer 实现的 http 服务,如果客户端在服务器返回前,主动断开连接,则服务器端会报 [Errno 32] Broken pipe 错,并导致处理线程 crash.
下面先看个例子,python 版本: 2.7
示例代码
代码如下:
#!/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): """ 处理get请求 """ query=self.path print "query: %s thread=%s" % (query, str(threading.current_thread())) #ret_str="<html>" + self.path + "<br>" + str(self.server) + "<br>" + str(self.responses) + "</html>" ret_str="<html>" + self.path + "<br>" + str(self.server) + "</html>" 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)
运行服务
./thread_http_server_error.py
第1次 curl ,等待返回
代码如下:
[~]$curl -s 'http://10.232.41.142:9001/hello1′ [~]$ 此时服务器端输出日志如下: $./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
第2次 curl ,不等待返回,ctrl +C 来模拟客户端断开
代码如下:
[~]$curl -s 'http://10.232.41.142:9001/hello2′ [~]$ ctrl+C
此时服务器端输出日志如下:
代码如下:
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. 原因分析
“[Errno 32] Broken pipe “ 产生的原因还是比较明确的,由于 client 在服务器返回前主动断开连接,所以服务器在返回时写 socket 收到SIGPIPE报错。虽然在我们的程序中也对异常进行了处理,将handler 的 wfile._sock 对象close 掉 ,但python 的库里BaseHTTPServer.py中BaseHTTPRequestHandler 类的成员函数handle_one_request还是会直接调用 wfile.flush ,而没有判断 wfile 是否已经 close。
代码如下:
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() #没有判断 wfile 是否已经 close 就直接调用 flush() 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. 解决办法
只要在RequestHandler重载其基类BaseHTTPRequestHandler的成员函数handle_one_reques(),在调用 wfile.flush() 前加上 wfile 是否已经 close 即可。
代码如下:
#!/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() #增加 debug info 及 wfile 判断是否已经 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): """ 处理get请求 """ query=self.path print "query: %s thread=%s" % (query, str(threading.current_thread())) ret_str="<html>" + self.path + "<br>" + str(self.server) + "</html>" 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)
运行服务
./thread_http_server.py
curl ,不等待返回,ctrl +C 来模拟客户端断开
复制代码 代码如下:
[~]$curl -s 'http://10.232.41.142:9001/hello2' [~]$ ctrl+C
此时服务器端输出日志如下:
$./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 32] Broken pipe after call do_Get after wfile.flush()
以上就是Python提示[Errno 32]Broken pipe导致线程crash错误解决方法的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

In VS Code, you can run the program in the terminal through the following steps: Prepare the code and open the integrated terminal to ensure that the code directory is consistent with the terminal working directory. Select the run command according to the programming language (such as Python's python your_file_name.py) to check whether it runs successfully and resolve errors. Use the debugger to improve debugging efficiency.

VS Code can be used to write Python and provides many features that make it an ideal tool for developing Python applications. It allows users to: install Python extensions to get functions such as code completion, syntax highlighting, and debugging. Use the debugger to track code step by step, find and fix errors. Integrate Git for version control. Use code formatting tools to maintain code consistency. Use the Linting tool to spot potential problems ahead of time.

VS Code extensions pose malicious risks, such as hiding malicious code, exploiting vulnerabilities, and masturbating as legitimate extensions. Methods to identify malicious extensions include: checking publishers, reading comments, checking code, and installing with caution. Security measures also include: security awareness, good habits, regular updates and antivirus software.

VS Code can run on Windows 8, but the experience may not be great. First make sure the system has been updated to the latest patch, then download the VS Code installation package that matches the system architecture and install it as prompted. After installation, be aware that some extensions may be incompatible with Windows 8 and need to look for alternative extensions or use newer Windows systems in a virtual machine. Install the necessary extensions to check whether they work properly. Although VS Code is feasible on Windows 8, it is recommended to upgrade to a newer Windows system for a better development experience and security.

Python excels in automation, scripting, and task management. 1) Automation: File backup is realized through standard libraries such as os and shutil. 2) Script writing: Use the psutil library to monitor system resources. 3) Task management: Use the schedule library to schedule tasks. Python's ease of use and rich library support makes it the preferred tool in these areas.

VS Code is the full name Visual Studio Code, which is a free and open source cross-platform code editor and development environment developed by Microsoft. It supports a wide range of programming languages and provides syntax highlighting, code automatic completion, code snippets and smart prompts to improve development efficiency. Through a rich extension ecosystem, users can add extensions to specific needs and languages, such as debuggers, code formatting tools, and Git integrations. VS Code also includes an intuitive debugger that helps quickly find and resolve bugs in your code.
