Pythonの[エラー番号32]プロンプト切れパイプは、クラッシュエラー溶液にスレッドを引き起こします

この論文は、Pythonプロンプト[エラー番号32]壊れたパイプの例を説明間違った溶液をクラッシュさせるスレッドを引き起こします。ご参考のためにあなたに共有します。次のように具体的な方法は以下のとおりです。

  1. 症状
    。イニシアチブが切断サーバー戻る前に、クライアントは、サーバが報告される場合ThreadingHTTPServerは、HTTPサービスを実現[ERRNO 32]壊れたパイプのエラー、およびリード処理スレッドのクラッシュ
    の例では、以下の表情、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′
<html>/hello1<br><__main__.ThreadingHTTPServer instance at 0x37483b0></html>[~]$
此时服务器端输出日志如下:
$./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

第二のカール、復帰を待たずに、CTRL + Cシミュレートクライアントが接続を切断します

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

此时服务器端输出日志如下:
クエリ:/ hello2スレッド=
search041142.sqa.cm4.tbsite.net - - [15 /月/ 2014年午後3時33分10秒]「GET / hello2 HTTP / 1.1 "200 -
socket.errorが:接続が壊れました。[ERRNO 32]壊れたパイプを中止
--------------
例外は('10 .232.41.142 '、48769)からのリクエストの処理中に起こった
トレースバック(最新の呼び出しの最後):
ファイル「/ホーム/ wuzhu /ツール/ python_2_7_1 / libに/ python2.7 / SocketServer.py」、行582、process_request_threadで
self.finish_request(リクエスト、client_address)
ファイル「/home/wuzhu/tools/python_2_7_1/lib/python2.7/SocketServer.py 」、ライン323、finish_requestに
self.RequestHandlerClass(リクエスト、client_address、自己)
ファイル『/home/wuzhu/tools/python_2_7_1/lib/python2.7/SocketServer.py』、ライン639、内INIT
self.handle()
ファイル「/home/wuzhu/tools/python_2_7_1/lib/python2.7/BaseHTTPServer.py」、ライン337、ハンドルで
self.handle_one_request()
ファイル「/ホーム/ wuzhu /ツール/ python_2_7_1 / libにhandle_one_requestで/python2.7/BaseHTTPServer.py」、行326、
まだ行っていない場合self.wfile.flushは()#actually応答を送信します。
フラッシュ内のファイル「/home/wuzhu/tools/python_2_7_1/lib/python2.7/socket.py」、ライン303、
self._sock.sendall(ビュー[write_offset:write_offset + BUFFER_SIZE])
はAttributeError: 'NoneType'オブジェクトが持っています属性'sendall'
2.原因分析

理由サーバソケット書き込みSIGPIPEがリターンエラーで受信されるように、クライアントは、サーバーが返す前に接続を遮断しているため、非常に明確生成「[ERRNO 32]壊れたパイプ」。私たちのプログラムはまた、例外処理でしたが、wfile._sockのハンドラは、判定wfileせず、近いうちオブジェクトが、Pythonや直接呼び出しwfile.flushのようなメンバ関数BaseHTTPRequestHandlerではでhandle_one_requestカレーBaseHTTPServer.pyそれはすでに近くにあります。
コードのコードをコピーして、次のとおりです。

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
  1. ソリューション
    wfile.flushを呼び出す前に長いオーバーロードされたメンバ関数handle_one_requesとしての基本クラスとしてのRequestHandlerでBaseHTTPRequestHandlerでは()、()プラスwfileは近くに既にあります。
#!/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
シミュレートクライアントが接続を切断するには、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学習サイトをプログラムで学ぶことです何歳見て、!基本的なPythonスクリプト、爬虫類、ジャンゴ、データマイニング、技術をプログラミング、仕事の経験だけでなく、小型のpythonパートナーのシニア入念な研究から戦闘にゼロベースの情報のプロジェクトを仕上げ!時限プログラマPythonは日常の技術を説明している方法は、学習と細部への注意を払う必要性へのいくつかを共有します

公開された51元の記事 ウォン称賛17 ビュー30000 +

おすすめ

転載: blog.csdn.net/haoxun02/article/details/104418656