2012-12-04 27 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/

它增加了一个依赖于你的项目,但似乎比猴子修补不太脆。

相关问题