एक सिद्धांत:
HttpWebRequest एक अंतर्निहित ServicePoint पर निर्भर करता है। सेवापॉइंट यूआरएल के वास्तविक कनेक्शन का प्रतिनिधित्व करता है। वैसे ही आपका ब्राउज़र अनुरोधों के बीच खुले यूआरएल से कनेक्शन रखता है और उस कनेक्शन का पुन: उपयोग करता है (प्रत्येक अनुरोध के साथ कनेक्शन खोलने और बंद करने के ऊपरी हिस्से को खत्म करने के लिए), सर्विसपॉइंट HttpWebRequest के लिए एक ही कार्य करता है।
मुझे लगता है कि BindIPEndPointDelegate जिसे आप सर्विसपॉइंट के लिए सेट कर रहे हैं उसे HttpWebRequest के प्रत्येक उपयोग पर नहीं कहा जा रहा है क्योंकि सेवापॉइंट कनेक्शन का पुन: उपयोग कर रहा है। यदि आप कनेक्शन को बंद करने के लिए मजबूर कर सकते हैं, तो उस यूआरएल के लिए अगली कॉल सर्विसपॉइंट को फिर से BindIPEndPointDelegate को कॉल करने की आवश्यकता होनी चाहिए।
दुर्भाग्य से, ऐसा नहीं लगता है कि सर्विसपॉइंट इंटरफ़ेस आपको कनेक्शन को बंद करने के लिए सीधे बल देने की क्षमता देता है।
दो समाधान (थोड़ा अलग परिणामों के साथ प्रत्येक)
1) प्रत्येक अनुरोध के लिए, HttpWebRequest.KeepAlive = false निर्धारित किया है। मेरे परीक्षण में, इसने बाईंड प्रतिनिधि को प्रत्येक अनुरोध के साथ एक-एक के लिए बुलाया।
2) सेवापॉइंट कनेक्शन LeaseTimeout संपत्ति को शून्य या कुछ छोटे मान पर सेट करें। इसका समय-समय पर बाध्य प्रतिनिधि को बुलाए जाने का असर होगा (प्रत्येक अनुरोध के साथ एक के लिए नहीं)।
documentation से
:
आप इस प्रॉपर्टी को सुनिश्चित करना है कि एक ServicePoint वस्तु की सक्रिय कनेक्शन अनिश्चित काल के लिए खुले रहते हैं नहीं है का उपयोग कर सकते हैं। यह संपत्ति उन परिदृश्यों के लिए लक्षित है जहां कनेक्शन को छोड़ दिया जाना चाहिए और समय-समय पर पुन: स्थापित किया गया है, जैसे भार संतुलन परिदृश्य।
डिफ़ॉल्ट रूप से, जब KeepAlive अनुरोध के लिए सच है, तो MaxIdleTime संपत्ति निष्क्रियता के कारण सेवापॉइंट कनेक्शन बंद करने के लिए टाइम-आउट सेट करती है। यदि सर्विसपॉइंट के सक्रिय कनेक्शन हैं, तो MaxIdleTime का कोई प्रभाव नहीं पड़ता है और कनेक्शन अनिश्चित काल तक खुला रहता है।
ConnectionLeaseTimeout संपत्ति -1 के अलावा किसी अन्य मान पर सेट किया जाता है, और निर्दिष्ट समय समाप्त होने के बाद, एक सक्रिय ServicePoint कनेक्शन उस अनुरोध में KeepAlivefalse करने के लिए की स्थापना करके एक अनुरोध सर्विसिंग के बाद बंद कर दिया है।
यह मान सेट करना सर्विसपॉइंट ऑब्जेक्ट द्वारा प्रबंधित सभी कनेक्शन को प्रभावित करता है।
public class UseIP
{
public string IP { get; private set; }
public UseIP(string IP)
{
this.IP = IP;
}
public HttpWebRequest CreateWebRequest(Uri uri)
{
ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri);
servicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) =>
{
IPAddress address = IPAddress.Parse(this.IP);
return new IPEndPoint(address, 0);
};
//Will cause bind to be called periodically
servicePoint.ConnectionLeaseTimeout = 0;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
//will cause bind to be called for each request (as long as the consumer of the request doesn't set it back to true!
req.KeepAlive = false;
return req;
}
}
निम्नलिखित (मूल) परीक्षण बाध्य प्रतिनिधि में परिणाम प्रत्येक अनुरोध के लिए कहा जाता हो रही है:
static void Main(string[] args)
{
//Note, I don't have a multihomed machine, so I'm not using the IP in my test implementation. The bind delegate increments a counter and returns IPAddress.Any.
UseIP ip = new UseIP("111.111.111.111");
for (int i = 0; i < 100; ++i)
{
HttpWebRequest req = ip.CreateWebRequest(new Uri("http://www.yahoo.com"));
using (WebResponse response = req.GetResponse())
{
}
}
Console.WriteLine(string.Format("Req: {0}", UseIP.RequestCount));
Console.WriteLine(string.Format("Bind: {0}", UseIP.BindCount));
}
हां, मैं अपना आईपी पता तेजी से बदलना चाहता हूं। मुझे किस दृष्टिकोण पर जाना चाहिए? – Xaqron
क्या आपको कोई अपवाद मिल रहा है? – alexD
आप बाध्यकारी केवल पहली बार बनाने और इसे स्थिर या आवृत्ति चर में रखने की कोशिश कर सकते हैं? – Cilvic