c# – 绑定IP地址只是第一次工作
我想从服务器上的一个可用的IP地址发出一个Web请求,所以我使用这个类:
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 = new BindIPEndPoint(Bind); return WebRequest.Create(uri) as HttpWebRequest; } private IPEndPoint Bind(ServicePoint servicePoint,IPEndPoint remoteEndPoint,int retryCount) { IPAddress address = IPAddress.Parse(this.IP); return new IPEndPoint(address,0); } } 然后: UseIP useIP = new UseIP("Valid IP address here..."); Uri uri = new Uri("http://ip.nefsc.noaa.gov"); HttpWebRequest request = useIP.CreateWebRequest(uri); // Then make the request with the specified IP address 但解决方案第一次工作! 解决方法
一个理论:
HttpWebRequest依赖于底层ServicePoint. ServicePoint表示与URL的实际连接.与浏览器保持与请求之间打开的URL的连接并重用该连接(为了消除打开和关闭每个请求的连接的开销),ServicePoint执行与HttpWebRequest相同的功能. 我认为您正在为ServicePoint设置的BindIPEndPointDelegate在每次使用HttpWebRequest时都不会被调用,因为ServicePoint正在重用该连接.如果您可以强制连接关闭,则下一次调用该URL应该导致ServicePoint需要再次调用BindIPEndPointDelegate. 不幸的是,ServicePoint界面并不能让您直接强制连接关闭. 两个解决方案(每个结果略有不同) 1)对于每个请求,设置HttpWebRequest.KeepAlive = false.在我的测试中,这导致绑定委托每个请求一一对应. 2)将ServicePoint ConnectionLeaseTimeout属性设置为零或一些小值.这将有效地定期强制绑定委托被调用(不是每个请求一对一). 从documentation:
设置此值会影响由ServicePoint对象管理的所有连接. 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)); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |