2012-12-04 30 views
12

我使用的urllib2加載網頁,我的代碼是:如何在使用urllib2加載URL時設置TCP_NODELAY標誌?

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()方法。

像這樣的東西應該是一個良好的開端:

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.build_opener針對本作:

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?

或者,你使用httplib2,其中有TCP_NODELAY選項設置。

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

它增加了一個依賴於你的項目,但似乎比猴子修補不太脆。

相關問題