2012-12-04 13 views
12

、私のコードは次のとおりです。urllib2でURLを読み込むときにTCP_NODELAYフラグを設定するには?私はロードのWebページのためのurllib2のを使用しています

httpRequest = urllib2.Request("http:/www....com") 
pageContent = urllib2.urlopen(httpRequest) 
pageContent.readline() 

私はTCP_NODELAYを設定するには、ソケットのプロパティのホールドを取得できますか?

私は機能を使用することになり、通常のソケットで

socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 
+1

なぜWebサーバーを呼び出すときに設定しますか? – jgauffin

+0

私はいくつかの情報がそこに掲載されるべきである特定の時間にウェブサイトをポーリングしています。速度は非常に重要です。したがって、TCP_NODELAYを設定すると、パケットを送信する前にデータの小さな部分をより大きな部分に累積することが回避されます。 –

+0

*「データの小さな部分」とは何ですか? HTTPリクエストは、ほぼ確実にライブラリによって単一のsend()でフラッシュされ、TCPによって単一のパケットとして送信されます。最後にTCP_NODELAYを設定しても、ピアが応答を送信する方法は変わりません。本当の質問ではありません。 – EJP

答えて

14

あなたが使用するソケットに、このような低レベルのプロパティにアクセスする必要がある場合、あなたはいくつかのオブジェクトをオーバーロードする必要があります。

まず、あなたが標準ライブラリに行うことを、HTTPHandlerのサブクラスを作成する必要があります:

class HTTPHandler(AbstractHTTPHandler): 

    def http_open(self, req): 
     return self.do_open(httplib.HTTPConnection, req) 

    http_request = AbstractHTTPHandler.do_request_ 

あなたが見ることができるように、それは、接続を開くためにHTTPConnectionを使用しています...あなたは持っていますそれを無効にする;)connect()メソッドをアップグレードします。 urllib2.build_openerは、このために作られ、

class LowLevelHTTPConnection(httplib.HTTPConnection): 

    def connect(self): 
     httplib.HTTPConnection.connect(self) 
     self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 


class LowLevelHTTPHandler(HTTPHandler): 

    def http_open(self, req): 
     return self.do_open(LowLevelHTTPConnection, req) 

urllib2のは、あなたがそれを使用し、いくつかのハンドラをサブクラス化することを可能にするのに十分なスマートです:このような

何かが良いスタートでなければなりません

urllib2.install_opener(urllib2.build_opener(LowLevelHTTPHandler)) # tell urllib2 to use your HTTPHandler in replacement of the standard HTTPHandler 
httpRequest = urllib2.Request("http:/www....com") 
pageContent = urllib2.urlopen(httpRequest) 
pageContent.readline() 
+1

素敵な答え!あなたはおそらくそれをurllib3と要求に絞ることも知っていますか? –

8

リクエストの場合、クラスはrequest.packages.urllib3にあるようです。 2つのクラス、 HTTPConnection、およびHTTPSConnectionがあります。彼らは、モジュールトップレベルの場所でmonkeypatchableする必要があります:

from requests.packages.urllib3 import connectionpool 

_HTTPConnection = connectionpool.HTTPConnection 
_HTTPSConnection = connectionpool.HTTPSConnection 

class HTTPConnection(_HTTPConnection): 
    def connect(self): 
     _HTTPConnection.connect(self) 
     self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 

class HTTPSConnection(_HTTPSConnection): 
    def connect(self): 
     _HTTPSConnection.connect(self) 
     self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) 

connectionpool.HTTPConnection = HTTPConnection 
connectionpool.HTTPSConnection = HTTPSConnection 
+0

素晴らしい。私は、サーバー証明書の検証とsni用のこのサルパッチを既に見てきました。彼らが葛藤しないことを願っています。 –

+0

私がこれを書いている時点で、urllib3(そしてそれゆえ要求)はデフォルトでTCP_NODELAYになっています。 'requests.packages.urllib3.connection.HTTPConnection'、特に' default_socket_options'を見てください。 –

1

urllib2を使用する必要がありますか?

また、TCP_NODELAYオプションが設定されたhttplib2を使用することもできます。

https://code.google.com/p/httplib2/

それはあなたのプロジェクトに依存関係が追加されますが、サルのパッチ未満脆いようです。

関連する問題