2012-12-04 33 views
12

मैं लोड हो रहा है वेब पेज के लिए urllib2 का उपयोग कर रहा है, मेरे कोड है:urllib2 के साथ यूआरएल लोड करते समय 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

वेब सर्वर को कॉल करते समय आप इसे क्यों सेट करते हैं ??? – jgauffin

+0

मैं विशिष्ट समय पर एक वेबसाइट पर मतदान कर रहा हूं, जब कुछ जानकारी वहां प्रकाशित की जानी चाहिए। गति बहुत महत्वपूर्ण है, इसलिए TCP_NODELAY को पैकेट भेजने से पहले बड़े हिस्से में डेटा के छोटे हिस्सों को जमा करने से बचें। –

+0

* * डेटा के छोटे हिस्से क्या हैं? HTTP अनुरोध लगभग एक ही प्रेषण() में लाइब्रेरी द्वारा निश्चित रूप से फ़्लश किया जाएगा और एक ही पैकेट के रूप में टीसीपी द्वारा भेजा जाएगा। और आपके अंत में 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 कक्षाएं हैं, HTTP कनेक्शन, और HTTPSConnection। मॉड्यूल शीर्ष स्तर पर उन्हें जगह में बंदरगाह होना चाहिए:

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

भयानक। मैंने सर्वर बंदरगाह सत्यापन और स्नि के लिए पहले से ही इस बंदर-पैचिंग को देखा है। मुझे आशा है कि वे संघर्ष नहीं करेंगे। –

+0

जब तक मैं इसे लिख रहा हूं, urllib3 (और इसलिए अनुरोध) डिफ़ॉल्ट रूप से TCP_NODELAY पर डिफ़ॉल्ट है। 'Request.packages.urllib3.connection.HTTPConnection' पर विशेष रूप से 'default_socket_options' देखें। –

1

क्या आपको urllib2 का उपयोग करना है?

वैकल्पिक रूप से, आप httplib2 का उपयोग कर सकते हैं, जिसमें TCP_NODELAY विकल्प सेट है।

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

यह अपने प्रोजेक्ट में कोई निर्भरता लेता है, लेकिन बंदर पैचिंग से कम भंगुर लगता है।